├── Broadcom_AP6212-1.20 ├── AP6212 BT │ ├── Bluetooth FW Auto Detection v01-1.pdf │ ├── Bluetooth User Guide for Linux-v02.pdf │ ├── FwAutoDetection-1.tgz │ ├── IMX6_bluetooth_transplant.txt │ ├── brcm_patchram_plus.c │ ├── 操作方法.txt │ └── 蓝牙应用库bluez编译与设置.txt ├── AP6212 WIFI │ ├── Wi-Fi User Guide for Linux 3.X-v03.pdf │ └── 移植AP6212 wifi方法及问题汇总.txt ├── AP6212 all firmware&nvram.rar ├── AP6212-3个版本区别.jpg ├── AP6212-version.jpg ├── Wi-Fi User Guide for Linux 3.X-v03.pdf └── bcmdhd.1.201.59.x.cn.tar.bz2 ├── Broadcom_AP6212-1.579 ├── AP6212 all firmware&nvram.rar ├── AP6212-3个版本区别.jpg ├── Wi-Fi User Guide for Linux 3.X-v03.pdf └── bcmdhd.1.579.77.41.x.7z └── README.md /Broadcom_AP6212-1.20/AP6212 BT/Bluetooth FW Auto Detection v01-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 BT/Bluetooth FW Auto Detection v01-1.pdf -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 BT/Bluetooth User Guide for Linux-v02.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 BT/Bluetooth User Guide for Linux-v02.pdf -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 BT/FwAutoDetection-1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 BT/FwAutoDetection-1.tgz -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 BT/IMX6_bluetooth_transplant.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 BT/IMX6_bluetooth_transplant.txt -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 BT/brcm_patchram_plus.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * Copyright (C) 2009-2011 Broadcom Corporation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | ******************************************************************************/ 18 | 19 | /***************************************************************************** 20 | ** 21 | ** Name: brcm_patchram_plus.c 22 | ** 23 | ** Description: This program downloads a patchram files in the HCD format 24 | ** to Broadcom Bluetooth based silicon and combo chips and 25 | ** and other utility functions. 26 | ** 27 | ** It can be invoked from the command line in the form 28 | ** <-d> to print a debug log 29 | ** <--patchram patchram_file> 30 | ** <--baudrate baud_rate> 31 | ** <--bd_addr bd_address> 32 | ** <--enable_lpm> 33 | ** <--enable_hci> 34 | ** <--use_baudrate_for_download> 35 | ** <--scopcm=sco_routing,pcm_interface_rate,frame_type, 36 | ** sync_mode,clock_mode,lsb_first,fill_bits, 37 | ** fill_method,fill_num,right_justify> 38 | ** 39 | ** Where 40 | ** 41 | ** sco_routing is 0 for PCM, 1 for Transport, 42 | ** 2 for Codec and 3 for I2S, 43 | ** 44 | ** pcm_interface_rate is 0 for 128KBps, 1 for 45 | ** 256 KBps, 2 for 512KBps, 3 for 1024KBps, 46 | ** and 4 for 2048Kbps, 47 | ** 48 | ** frame_type is 0 for short and 1 for long, 49 | ** 50 | ** sync_mode is 0 for slave and 1 for master, 51 | ** 52 | ** clock_mode is 0 for slabe and 1 for master, 53 | ** 54 | ** lsb_first is 0 for false aand 1 for true, 55 | ** 56 | ** fill_bits is the value in decimal for unused bits, 57 | ** 58 | ** fill_method is 0 for 0's and 1 for 1's, 2 for 59 | ** signed and 3 for programmable, 60 | ** 61 | ** fill_num is the number or bits to fill, 62 | ** 63 | ** right_justify is 0 for false and 1 for true 64 | ** 65 | ** <--i2s=i2s_enable,is_master,sample_rate,clock_rate> 66 | ** 67 | ** Where 68 | ** 69 | ** i2s_enable is 0 for disable and 1 for enable, 70 | ** 71 | ** is_master is 0 for slave and 1 for master, 72 | ** 73 | ** sample_rate is 0 for 8KHz, 1 for 16Khz and 74 | ** 2 for 4 KHz, 75 | ** 76 | ** clock_rate is 0 for 128KHz, 1 for 256KHz, 3 for 77 | ** 1024 KHz and 4 for 2048 KHz. 78 | ** 79 | ** <--no2bytes skips waiting for two byte confirmation 80 | ** before starting patchram download. Newer chips 81 | ** do not generate these two bytes.> 82 | ** <--tosleep=number of microsseconds to sleep before 83 | ** patchram download begins.> 84 | ** uart_device_name 85 | ** 86 | ** For example: 87 | ** 88 | ** brcm_patchram_plus -d --patchram \ 89 | ** BCM2045B2_002.002.011.0348.0349.hcd /dev/ttyHS0 90 | ** 91 | ** It will return 0 for success and a number greater than 0 92 | ** for any errors. 93 | ** 94 | ** For Android, this program invoked using a 95 | ** "system(2)" call from the beginning of the bt_enable 96 | ** function inside the file 97 | ** system/bluetooth/bluedroid/bluetooth.c. 98 | ** 99 | ** If the Android system property "ro.bt.bcm_bdaddr_path" is 100 | ** set, then the bd_addr will be read from this path. 101 | ** This is overridden by --bd_addr on the command line. 102 | ** 103 | ******************************************************************************/ 104 | 105 | // TODO: Integrate BCM support into Bluez hciattach 106 | 107 | #include 108 | #include 109 | #include 110 | 111 | #include 112 | #include 113 | #include 114 | 115 | #include 116 | 117 | #ifdef ANDROID 118 | #include 119 | #else 120 | #include 121 | #include 122 | #include 123 | #endif 124 | 125 | #include 126 | #include 127 | 128 | #ifdef ANDROID 129 | #include 130 | #define LOG_TAG "brcm_patchram_plus" 131 | #include 132 | #undef printf 133 | #define printf ALOGD 134 | #undef fprintf 135 | #define fprintf(x, ...) \ 136 | { if(x==stderr) ALOGE(__VA_ARGS__); else fprintf(x, __VA_ARGS__); } 137 | 138 | #endif //ANDROID 139 | 140 | #ifndef N_HCI 141 | #define N_HCI 15 142 | #endif 143 | 144 | #define HCIUARTSETPROTO _IOW('U', 200, int) 145 | #define HCIUARTGETPROTO _IOR('U', 201, int) 146 | #define HCIUARTGETDEVICE _IOR('U', 202, int) 147 | 148 | #define HCI_UART_H4 0 149 | #define HCI_UART_BCSP 1 150 | #define HCI_UART_3WIRE 2 151 | #define HCI_UART_H4DS 3 152 | #define HCI_UART_LL 4 153 | 154 | typedef unsigned char uchar; 155 | 156 | int uart_fd = -1; 157 | int hcdfile_fd = -1; 158 | int termios_baudrate = 0; 159 | int bdaddr_flag = 0; 160 | int enable_lpm = 0; 161 | int enable_hci = 0; 162 | int use_baudrate_for_download = 0; 163 | int debug = 0; 164 | int scopcm = 0; 165 | int i2s = 0; 166 | int no2bytes = 0; 167 | int tosleep = 0; 168 | 169 | struct termios termios; 170 | uchar buffer[1024]; 171 | 172 | uchar hci_reset[] = { 0x01, 0x03, 0x0c, 0x00 }; 173 | 174 | uchar hci_download_minidriver[] = { 0x01, 0x2e, 0xfc, 0x00 }; 175 | 176 | uchar hci_update_baud_rate[] = { 0x01, 0x18, 0xfc, 0x06, 0x00, 0x00, 177 | 0x00, 0x00, 0x00, 0x00 }; 178 | 179 | uchar hci_write_bd_addr[] = { 0x01, 0x01, 0xfc, 0x06, 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 181 | 182 | uchar hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc, 0x0c, 183 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 184 | 0x00, 0x00 }; 185 | 186 | uchar hci_write_sco_pcm_int[] = 187 | { 0x01, 0x1C, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; 188 | 189 | uchar hci_write_pcm_data_format[] = 190 | { 0x01, 0x1e, 0xFC, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; 191 | 192 | uchar hci_write_i2spcm_interface_param[] = 193 | { 0x01, 0x6d, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00 }; 194 | 195 | int 196 | parse_patchram(char *optarg) 197 | { 198 | char *p; 199 | 200 | if (!(p = strrchr(optarg, '.'))) { 201 | fprintf(stderr, "file %s not an HCD file\n", optarg); 202 | exit(3); 203 | } 204 | 205 | p++; 206 | 207 | if (strcasecmp("hcd", p) != 0) { 208 | fprintf(stderr, "file %s not an HCD file\n", optarg); 209 | exit(4); 210 | } 211 | 212 | if ((hcdfile_fd = open(optarg, O_RDONLY)) == -1) { 213 | fprintf(stderr, "file %s could not be opened, error %d\n", optarg, errno); 214 | exit(5); 215 | } 216 | 217 | return(0); 218 | } 219 | 220 | void 221 | BRCM_encode_baud_rate(uint baud_rate, uchar *encoded_baud) 222 | { 223 | if(baud_rate == 0 || encoded_baud == NULL) { 224 | fprintf(stderr, "Baudrate not supported!"); 225 | return; 226 | } 227 | 228 | encoded_baud[3] = (uchar)(baud_rate >> 24); 229 | encoded_baud[2] = (uchar)(baud_rate >> 16); 230 | encoded_baud[1] = (uchar)(baud_rate >> 8); 231 | encoded_baud[0] = (uchar)(baud_rate & 0xFF); 232 | } 233 | 234 | typedef struct { 235 | int baud_rate; 236 | int termios_value; 237 | } tBaudRates; 238 | 239 | tBaudRates baud_rates[] = { 240 | { 115200, B115200 }, 241 | { 230400, B230400 }, 242 | { 460800, B460800 }, 243 | { 500000, B500000 }, 244 | { 576000, B576000 }, 245 | { 921600, B921600 }, 246 | { 1000000, B1000000 }, 247 | { 1152000, B1152000 }, 248 | { 1500000, B1500000 }, 249 | { 2000000, B2000000 }, 250 | { 2500000, B2500000 }, 251 | { 3000000, B3000000 }, 252 | #ifndef __CYGWIN__ 253 | { 3500000, B3500000 }, 254 | { 4000000, B4000000 } 255 | #endif 256 | }; 257 | 258 | int 259 | validate_baudrate(int baud_rate, int *value) 260 | { 261 | unsigned int i; 262 | 263 | for (i = 0; i < (sizeof(baud_rates) / sizeof(tBaudRates)); i++) { 264 | if (baud_rates[i].baud_rate == baud_rate) { 265 | *value = baud_rates[i].termios_value; 266 | return(1); 267 | } 268 | } 269 | 270 | return(0); 271 | } 272 | 273 | int 274 | parse_baudrate(char *optarg) 275 | { 276 | int baudrate = atoi(optarg); 277 | 278 | if (validate_baudrate(baudrate, &termios_baudrate)) { 279 | BRCM_encode_baud_rate(baudrate, &hci_update_baud_rate[6]); 280 | } 281 | 282 | return(0); 283 | } 284 | 285 | int 286 | parse_bdaddr(char *optarg) 287 | { 288 | int bd_addr[6]; 289 | int i; 290 | 291 | sscanf(optarg, "%02X:%02X:%02X:%02X:%02X:%02X", 292 | &bd_addr[5], &bd_addr[4], &bd_addr[3], 293 | &bd_addr[2], &bd_addr[1], &bd_addr[0]); 294 | 295 | for (i = 0; i < 6; i++) { 296 | hci_write_bd_addr[4 + i] = bd_addr[i]; 297 | } 298 | 299 | bdaddr_flag = 1; 300 | 301 | return(0); 302 | } 303 | 304 | int 305 | parse_enable_lpm(char *optarg) 306 | { 307 | enable_lpm = 1; 308 | return(0); 309 | } 310 | 311 | int 312 | parse_use_baudrate_for_download(char *optarg) 313 | { 314 | use_baudrate_for_download = 1; 315 | return(0); 316 | } 317 | 318 | int 319 | parse_enable_hci(char *optarg) 320 | { 321 | enable_hci = 1; 322 | return(0); 323 | } 324 | 325 | int 326 | parse_scopcm(char *optarg) 327 | { 328 | int param[10]; 329 | int ret; 330 | int i; 331 | 332 | ret = sscanf(optarg, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", 333 | ¶m[0], ¶m[1], ¶m[2], ¶m[3], ¶m[4], 334 | ¶m[5], ¶m[6], ¶m[7], ¶m[8], ¶m[9]); 335 | 336 | if (ret != 10) { 337 | return(1); 338 | } 339 | 340 | scopcm = 1; 341 | 342 | for (i = 0; i < 5; i++) { 343 | hci_write_sco_pcm_int[4 + i] = param[i]; 344 | } 345 | 346 | for (i = 0; i < 5; i++) { 347 | hci_write_pcm_data_format[4 + i] = param[5 + i]; 348 | } 349 | 350 | return(0); 351 | } 352 | 353 | int 354 | parse_i2s(char *optarg) 355 | { 356 | int param[4]; 357 | int ret; 358 | int i; 359 | 360 | ret = sscanf(optarg, "%d,%d,%d,%d", ¶m[0], ¶m[1], ¶m[2], 361 | ¶m[3]); 362 | 363 | if (ret != 4) { 364 | return(1); 365 | } 366 | 367 | i2s = 1; 368 | 369 | for (i = 0; i < 4; i++) { 370 | hci_write_i2spcm_interface_param[4 + i] = param[i]; 371 | } 372 | 373 | return(0); 374 | } 375 | 376 | int 377 | parse_no2bytes(char *optarg) 378 | { 379 | no2bytes = 1; 380 | return(0); 381 | } 382 | 383 | int 384 | parse_tosleep(char *optarg) 385 | { 386 | tosleep = atoi(optarg); 387 | 388 | if (tosleep <= 0) { 389 | return(1); 390 | } 391 | 392 | return(0); 393 | } 394 | 395 | void 396 | usage(char *argv0) 397 | { 398 | printf("Usage %s:\n", argv0); 399 | printf("\t<-d> to print a debug log\n"); 400 | printf("\t<--patchram patchram_file>\n"); 401 | printf("\t<--baudrate baud_rate>\n"); 402 | printf("\t<--bd_addr bd_address>\n"); 403 | printf("\t<--enable_lpm>\n"); 404 | printf("\t<--enable_hci>\n"); 405 | printf("\t<--use_baudrate_for_download> - Uses the\n"); 406 | printf("\t\tbaudrate for downloading the firmware\n"); 407 | printf("\t<--scopcm=sco_routing,pcm_interface_rate,frame_type,\n"); 408 | printf("\t\tsync_mode,clock_mode,lsb_first,fill_bits,\n"); 409 | printf("\t\tfill_method,fill_num,right_justify>\n"); 410 | printf("\n\t\tWhere\n"); 411 | printf("\n\t\tsco_routing is 0 for PCM, 1 for Transport,\n"); 412 | printf("\t\t2 for Codec and 3 for I2S,\n"); 413 | printf("\n\t\tpcm_interface_rate is 0 for 128KBps, 1 for\n"); 414 | printf("\t\t256 KBps, 2 for 512KBps, 3 for 1024KBps,\n"); 415 | printf("\t\tand 4 for 2048Kbps,\n"); 416 | printf("\n\t\tframe_type is 0 for short and 1 for long,\n"); 417 | printf("\t\tsync_mode is 0 for slave and 1 for master,\n"); 418 | printf("\n\t\tclock_mode is 0 for slabe and 1 for master,\n"); 419 | printf("\n\t\tlsb_first is 0 for false aand 1 for true,\n"); 420 | printf("\n\t\tfill_bits is the value in decimal for unused bits,\n"); 421 | printf("\n\t\tfill_method is 0 for 0's and 1 for 1's, 2 for\n"); 422 | printf("\t\tsigned and 3 for programmable,\n"); 423 | printf("\n\t\tfill_num is the number or bits to fill,\n"); 424 | printf("\n\t\tright_justify is 0 for false and 1 for true\n"); 425 | printf("\n\t<--i2s=i2s_enable,is_master,sample_rate,clock_rate>\n"); 426 | printf("\n\t\tWhere\n"); 427 | printf("\n\t\ti2s_enable is 0 for disable and 1 for enable,\n"); 428 | printf("\n\t\tis_master is 0 for slave and 1 for master,\n"); 429 | printf("\n\t\tsample_rate is 0 for 8KHz, 1 for 16Khz and\n"); 430 | printf("\t\t2 for 4 KHz,\n"); 431 | printf("\n\t\tclock_rate is 0 for 128KHz, 1 for 256KHz, 3 for\n"); 432 | printf("\t\t1024 KHz and 4 for 2048 KHz.\n\n"); 433 | printf("\t<--no2bytes skips waiting for two byte confirmation\n"); 434 | printf("\t\tbefore starting patchram download. Newer chips\n"); 435 | printf("\t\tdo not generate these two bytes.>\n"); 436 | printf("\t<--tosleep=microseconds>\n"); 437 | printf("\tuart_device_name\n"); 438 | } 439 | 440 | int 441 | parse_cmd_line(int argc, char **argv) 442 | { 443 | int c; 444 | int ret = 0; 445 | 446 | typedef int (*PFI)(); 447 | 448 | PFI parse[] = { parse_patchram, parse_baudrate, 449 | parse_bdaddr, parse_enable_lpm, parse_enable_hci, 450 | parse_use_baudrate_for_download, 451 | parse_scopcm, parse_i2s, parse_no2bytes, parse_tosleep}; 452 | 453 | while (1) { 454 | int this_option_optind = optind ? optind : 1; 455 | int option_index = 0; 456 | 457 | static struct option long_options[] = { 458 | {"patchram", 1, 0, 0}, 459 | {"baudrate", 1, 0, 0}, 460 | {"bd_addr", 1, 0, 0}, 461 | {"enable_lpm", 0, 0, 0}, 462 | {"enable_hci", 0, 0, 0}, 463 | {"use_baudrate_for_download", 0, 0, 0}, 464 | {"scopcm", 1, 0, 0}, 465 | {"i2s", 1, 0, 0}, 466 | {"no2bytes", 0, 0, 0}, 467 | {"tosleep", 1, 0, 0}, 468 | {0, 0, 0, 0} 469 | }; 470 | 471 | c = getopt_long_only (argc, argv, "d", long_options, 472 | &option_index); 473 | 474 | if (c == -1) { 475 | break; 476 | } 477 | 478 | switch (c) { 479 | case 0: 480 | if (debug) { 481 | printf ("option %s", 482 | long_options[option_index].name); 483 | if (optarg) 484 | printf (" with arg %s", optarg); 485 | printf ("\n"); 486 | } 487 | 488 | ret = (*parse[option_index])(optarg); 489 | 490 | break; 491 | case 'd': 492 | debug = 1; 493 | break; 494 | 495 | case '?': 496 | //nobreak 497 | default: 498 | usage(argv[0]); 499 | break; 500 | } 501 | 502 | if (ret) { 503 | usage(argv[0]); 504 | break; 505 | } 506 | } 507 | 508 | if (ret) { 509 | return(1); 510 | } 511 | 512 | if (optind < argc) { 513 | if (debug) 514 | printf ("%s \n", argv[optind]); 515 | if ((uart_fd = open(argv[optind], O_RDWR | O_NOCTTY)) == -1) { 516 | fprintf(stderr, "port %s could not be opened, error %d\n", 517 | argv[2], errno); 518 | } 519 | } 520 | 521 | return(0); 522 | } 523 | 524 | void 525 | init_uart() 526 | { 527 | tcflush(uart_fd, TCIOFLUSH); 528 | tcgetattr(uart_fd, &termios); 529 | 530 | #ifndef __CYGWIN__ 531 | cfmakeraw(&termios); 532 | #else 533 | termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP 534 | | INLCR | IGNCR | ICRNL | IXON); 535 | termios.c_oflag &= ~OPOST; 536 | termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 537 | termios.c_cflag &= ~(CSIZE | PARENB); 538 | termios.c_cflag |= CS8; 539 | #endif 540 | 541 | termios.c_cflag |= CRTSCTS; 542 | tcsetattr(uart_fd, TCSANOW, &termios); 543 | tcflush(uart_fd, TCIOFLUSH); 544 | tcsetattr(uart_fd, TCSANOW, &termios); 545 | tcflush(uart_fd, TCIOFLUSH); 546 | tcflush(uart_fd, TCIOFLUSH); 547 | cfsetospeed(&termios, B115200); 548 | cfsetispeed(&termios, B115200); 549 | tcsetattr(uart_fd, TCSANOW, &termios); 550 | } 551 | 552 | void 553 | dump(uchar *out, int len) 554 | { 555 | int i; 556 | 557 | for (i = 0; i < len; i++) { 558 | if (i && !(i % 16)) { 559 | fprintf(stderr, "\n"); 560 | } 561 | 562 | fprintf(stderr, "%02x ", out[i]); 563 | } 564 | 565 | fprintf(stderr, "\n"); 566 | } 567 | 568 | void 569 | read_event(int fd, uchar *buffer) 570 | { 571 | int i = 0; 572 | int len = 3; 573 | int count; 574 | 575 | while ((count = read(fd, &buffer[i], len)) < len) { 576 | i += count; 577 | len -= count; 578 | } 579 | 580 | i += count; 581 | len = buffer[2]; 582 | 583 | while ((count = read(fd, &buffer[i], len)) < len) { 584 | i += count; 585 | len -= count; 586 | } 587 | 588 | if (debug) { 589 | count += i; 590 | 591 | fprintf(stderr, "received %d\n", count); 592 | dump(buffer, count); 593 | } 594 | } 595 | 596 | void 597 | hci_send_cmd(uchar *buf, int len) 598 | { 599 | if (debug) { 600 | fprintf(stderr, "writing\n"); 601 | dump(buf, len); 602 | } 603 | 604 | write(uart_fd, buf, len); 605 | } 606 | 607 | void 608 | expired(int sig) 609 | { 610 | hci_send_cmd(hci_reset, sizeof(hci_reset)); 611 | alarm(4); 612 | } 613 | 614 | void 615 | proc_reset() 616 | { 617 | signal(SIGALRM, expired); 618 | 619 | 620 | hci_send_cmd(hci_reset, sizeof(hci_reset)); 621 | 622 | alarm(4); 623 | 624 | read_event(uart_fd, buffer); 625 | 626 | alarm(0); 627 | } 628 | 629 | void 630 | proc_patchram() 631 | { 632 | int len; 633 | 634 | hci_send_cmd(hci_download_minidriver, sizeof(hci_download_minidriver)); 635 | 636 | read_event(uart_fd, buffer); 637 | 638 | if (!no2bytes) { 639 | read(uart_fd, &buffer[0], 2); 640 | } 641 | 642 | if (tosleep) { 643 | usleep(tosleep); 644 | } 645 | 646 | while (read(hcdfile_fd, &buffer[1], 3)) { 647 | buffer[0] = 0x01; 648 | 649 | len = buffer[3]; 650 | 651 | read(hcdfile_fd, &buffer[4], len); 652 | 653 | hci_send_cmd(buffer, len + 4); 654 | 655 | read_event(uart_fd, buffer); 656 | } 657 | 658 | if (use_baudrate_for_download) { 659 | cfsetospeed(&termios, B115200); 660 | cfsetispeed(&termios, B115200); 661 | tcsetattr(uart_fd, TCSANOW, &termios); 662 | } 663 | proc_reset(); 664 | } 665 | 666 | void 667 | proc_baudrate() 668 | { 669 | hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate)); 670 | 671 | read_event(uart_fd, buffer); 672 | 673 | cfsetospeed(&termios, termios_baudrate); 674 | cfsetispeed(&termios, termios_baudrate); 675 | tcsetattr(uart_fd, TCSANOW, &termios); 676 | 677 | if (debug) { 678 | fprintf(stderr, "Done setting baudrate\n"); 679 | } 680 | } 681 | 682 | void 683 | proc_bdaddr() 684 | { 685 | hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr)); 686 | 687 | read_event(uart_fd, buffer); 688 | } 689 | 690 | void 691 | proc_enable_lpm() 692 | { 693 | hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode)); 694 | 695 | read_event(uart_fd, buffer); 696 | } 697 | 698 | void 699 | proc_scopcm() 700 | { 701 | hci_send_cmd(hci_write_sco_pcm_int, 702 | sizeof(hci_write_sco_pcm_int)); 703 | 704 | read_event(uart_fd, buffer); 705 | 706 | hci_send_cmd(hci_write_pcm_data_format, 707 | sizeof(hci_write_pcm_data_format)); 708 | 709 | read_event(uart_fd, buffer); 710 | } 711 | 712 | void 713 | proc_i2s() 714 | { 715 | hci_send_cmd(hci_write_i2spcm_interface_param, 716 | sizeof(hci_write_i2spcm_interface_param)); 717 | 718 | read_event(uart_fd, buffer); 719 | } 720 | 721 | void 722 | proc_enable_hci() 723 | { 724 | int i = N_HCI; 725 | int proto = HCI_UART_H4; 726 | if (ioctl(uart_fd, TIOCSETD, &i) < 0) { 727 | fprintf(stderr, "Can't set line discipline\n"); 728 | return; 729 | } 730 | 731 | if (ioctl(uart_fd, HCIUARTSETPROTO, proto) < 0) { 732 | fprintf(stderr, "Can't set hci protocol\n"); 733 | return; 734 | } 735 | fprintf(stderr, "Done setting line discpline\n"); 736 | return; 737 | } 738 | 739 | #ifdef ANDROID 740 | void 741 | read_default_bdaddr() 742 | { 743 | int sz; 744 | int fd; 745 | 746 | char path[PROPERTY_VALUE_MAX]; 747 | 748 | char bdaddr[18]; 749 | int len = 17; 750 | memset(bdaddr, 0, (len + 1) * sizeof(char)); 751 | 752 | property_get("ro.bt.bdaddr_path", path, ""); 753 | if (path[0] == 0) 754 | return; 755 | 756 | fd = open(path, O_RDONLY); 757 | if (fd < 0) { 758 | fprintf(stderr, "open(%s) failed: %s (%d)", path, strerror(errno), 759 | errno); 760 | return; 761 | } 762 | 763 | sz = read(fd, bdaddr, len); 764 | if (sz < 0) { 765 | fprintf(stderr, "read(%s) failed: %s (%d)", path, strerror(errno), 766 | errno); 767 | close(fd); 768 | return; 769 | } else if (sz != len) { 770 | fprintf(stderr, "read(%s) unexpected size %d", path, sz); 771 | close(fd); 772 | return; 773 | } 774 | 775 | if (debug) { 776 | printf("Read default bdaddr of %s\n", bdaddr); 777 | } 778 | 779 | parse_bdaddr(bdaddr); 780 | } 781 | #endif 782 | 783 | 784 | int 785 | main (int argc, char **argv) 786 | { 787 | #ifdef ANDROID 788 | read_default_bdaddr(); 789 | #endif 790 | 791 | if (parse_cmd_line(argc, argv)) { 792 | exit(1); 793 | } 794 | 795 | if (uart_fd < 0) { 796 | exit(2); 797 | } 798 | 799 | init_uart(); 800 | 801 | proc_reset(); 802 | 803 | if (use_baudrate_for_download) { 804 | if (termios_baudrate) { 805 | proc_baudrate(); 806 | } 807 | } 808 | 809 | if (hcdfile_fd > 0) { 810 | proc_patchram(); 811 | } 812 | 813 | if (termios_baudrate) { 814 | proc_baudrate(); 815 | } 816 | 817 | if (bdaddr_flag) { 818 | proc_bdaddr(); 819 | } 820 | 821 | if (enable_lpm) { 822 | proc_enable_lpm(); 823 | } 824 | 825 | if (scopcm) { 826 | proc_scopcm(); 827 | } 828 | 829 | if (i2s) { 830 | proc_i2s(); 831 | } 832 | 833 | if (enable_hci) { 834 | proc_enable_hci(); 835 | 836 | while (1) { 837 | sleep(UINT_MAX); 838 | } 839 | } 840 | 841 | exit(0); 842 | } 843 | -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 BT/操作方法.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 BT/操作方法.txt -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 BT/蓝牙应用库bluez编译与设置.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 BT/蓝牙应用库bluez编译与设置.txt -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 WIFI/Wi-Fi User Guide for Linux 3.X-v03.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 WIFI/Wi-Fi User Guide for Linux 3.X-v03.pdf -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 WIFI/移植AP6212 wifi方法及问题汇总.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 WIFI/移植AP6212 wifi方法及问题汇总.txt -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212 all firmware&nvram.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212 all firmware&nvram.rar -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212-3个版本区别.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212-3个版本区别.jpg -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/AP6212-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/AP6212-version.jpg -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/Wi-Fi User Guide for Linux 3.X-v03.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/Wi-Fi User Guide for Linux 3.X-v03.pdf -------------------------------------------------------------------------------- /Broadcom_AP6212-1.20/bcmdhd.1.201.59.x.cn.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.20/bcmdhd.1.201.59.x.cn.tar.bz2 -------------------------------------------------------------------------------- /Broadcom_AP6212-1.579/AP6212 all firmware&nvram.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.579/AP6212 all firmware&nvram.rar -------------------------------------------------------------------------------- /Broadcom_AP6212-1.579/AP6212-3个版本区别.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.579/AP6212-3个版本区别.jpg -------------------------------------------------------------------------------- /Broadcom_AP6212-1.579/Wi-Fi User Guide for Linux 3.X-v03.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.579/Wi-Fi User Guide for Linux 3.X-v03.pdf -------------------------------------------------------------------------------- /Broadcom_AP6212-1.579/bcmdhd.1.579.77.41.x.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiFDW/broadcom-ap6212/2d61f4c3aef2cd30e375e4f2b018f16f0aef1f08/Broadcom_AP6212-1.579/bcmdhd.1.579.77.41.x.7z -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | o broadcom-ap6212 2 | --------------------------------------------------------------------------------