1 /*****************************************************************************
5 ** Description: Download a patchram files for the HCD format
7 ** Copyright (c) 2000-2009, Broadcom Corp., All Rights Reserved.
8 ******************************************************************************/
12 #include <sys/types.h>
20 #include <sys/termios.h>
21 #include <sys/ioctl.h>
26 #define HCI_UART_BCSP 1
27 #define HCI_UART_3WIRE 2
28 #define HCI_UART_H4DS 3
30 #define HCIUARTSETPROTO _IOW('U', 200, int)
31 #define HCIUARTGETPROTO _IOR('U', 201, int)
32 #define HCIUARTGETDEVICE _IOR('U', 202, int)
34 /* BT_WAKE Polarity - 0=Active Low, 1= Active High */
35 #define HCILP_BT_WAKE_POLARITY 1
37 /* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
38 #define HCILP_HOST_WAKE_POLARITY 1
41 #define BCM_DISABLE_RF_PWRCTRL FALSE
43 #define RELEASE_DATE "2011.02.07"
46 typedef unsigned char UINT8;
47 typedef unsigned short UINT16;
48 typedef unsigned long UINT32;
49 typedef signed long INT32;
50 typedef signed char INT8;
51 typedef signed short INT16;
52 typedef unsigned char BOOLEAN;
57 #define BD_ADDR_LEN 6 /* Device address length */
58 typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */
60 #define HCI_GRP_LINK_CONTROL_CMDS (0x01 << 10)
61 #define HCI_GRP_LINK_POLICY_CMDS (0x02 << 10)
62 #define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10)
63 #define HCI_GRP_INFORMATIONAL_PARAMS (0x04 << 10)
64 #define HCI_GRP_STATUS_PARAMS (0x05 << 10)
65 #define HCI_GRP_TESTING_CMDS (0x06 << 10)
66 #define HCI_GRP_L2CAP_CMDS (0x07 << 10)
67 #define HCI_GRP_L2CAP_HCI_EVTS (0x08 << 10)
68 #define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10)
70 #define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
71 #define HCI_SET_EVENT_FILTER (0x0005 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
72 #define HCI_READ_LOCAL_NAME (0x0014 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
73 #define HCI_READ_SCAN_ENABLE (0x0019 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
74 #define HCI_WRITE_SCAN_ENABLE (0x001A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
76 #define HCI_READ_LOCAL_VERSION_INFO (0x0001 | HCI_GRP_INFORMATIONAL_PARAMS)
77 #define HCI_READ_LOCAL_FEATURES (0x0003 | HCI_GRP_INFORMATIONAL_PARAMS)
79 #define HCI_ENABLE_DEV_UNDER_TEST_MODE (0x0003 | HCI_GRP_TESTING_CMDS)
81 #define HCI_BRCM_SUPER_PEEK_POKE (0x000A | HCI_GRP_VENDOR_SPECIFIC)
82 #define VSC_WRITE_BD_ADDR (0x0001 | HCI_GRP_VENDOR_SPECIFIC)
83 #define VSC_HCI_CMD_SET_LOC_FEATURES_CMD (0x000B | HCI_GRP_VENDOR_SPECIFIC)
84 #define HCI_BRCM_UPDATE_BAUDRATE_CMD (0x0018 | HCI_GRP_VENDOR_SPECIFIC)
85 #define HCI_BRCM_WRITE_SCO_PCM_INT_PARAM (0x001C | HCI_GRP_VENDOR_SPECIFIC)
86 #define VSC_WRITE_PCM_DATA_FORMAT_PARAM (0x001E | HCI_GRP_VENDOR_SPECIFIC)
87 #define HCI_BRCM_WRITE_SLEEP_MODE (0x0027 | HCI_GRP_VENDOR_SPECIFIC)
88 #define HCI_BRCM_DOWNLOAD_MINI_DRV (0x002E | HCI_GRP_VENDOR_SPECIFIC)
89 #define VSC_WRITE_UART_CLOCK_SETTING (0x0045 | HCI_GRP_VENDOR_SPECIFIC)
90 #define HCI_VSC_WRITE_RAM (0x004C | HCI_GRP_VENDOR_SPECIFIC)
91 #define HCI_VSC_LAUNCH_RAM (0x004E | HCI_GRP_VENDOR_SPECIFIC)
93 #define VOICE_SETTING_MU_LAW_MD 0x0100
94 #define VOICE_SETTING_LINEAR_MD 0x0060
96 #define HCI_ARM_MEM_PEEK 0x04
97 #define HCI_ARM_MEM_POKE 0x05
99 #define BTUI_MAX_STRING_LENGTH_PER_LINE 255
100 #define HCI_BRCM_WRITE_SLEEP_MODE_LENGTH 12
102 #define HCI_BRCM_UPDATE_BAUD_RATE_ENCODED_LENGTH 0x02
103 #define HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH 0x06
105 #define VSC_WRITE_UART_CLOCK_SETTING_LEN 1
107 /* print string with time stamp */
108 #define TDEBUG0(m) if(debug_mode) {print_time();fprintf(stderr,m);}
109 #define TDEBUG1(m,n1) if(debug_mode) {print_time();fprintf(stderr,m,n1);}
110 #define TDEBUG2(m,n1,n2) if(debug_mode) {print_time();fprintf(stderr,m,n1,n2);}
111 #define TDEBUG3(m,n1,n2,n3) if(debug_mode) {print_time();fprintf(stderr,m,n1,n2,n3);}
112 #define TDEBUG4(m,n1,n2,n3,n4) if(debug_mode) {print_time();fprintf(stderr,m,n1,n2,n3,n4);}
113 #define TDEBUG5(m,n1,n2,n3,n4,n5) if(debug_mode) {print_time();fprintf(stderr,m,n1,n2,n3,n4,n5);}
114 #define TDEBUG6(m,n1,n2,n3,n4,n5,n6) if(debug_mode) {print_time();fprintf(stderr,m,n1,n2,n3,n4,n5,n6);}
116 /* print just string */
117 #define DEBUG0(m) if(debug_mode) {fprintf(stderr,m);}
118 #define DEBUG1(m,n1) if(debug_mode) {fprintf(stderr,m,n1);}
119 #define DEBUG2(m,n1,n2) if(debug_mode) {fprintf(stderr,m,n1,n2);}
120 #define DEBUG3(m,n1,n2,n3) if(debug_mode) {fprintf(stderr,m,n1,n2,n3);}
121 #define DEBUG4(m,n1,n2,n3,n4) if(debug_mode) {fprintf(stderr,m,n1,n2,n3,n4);}
122 #define DEBUG5(m,n1,n2,n3,n4,n5) if(debug_mode) {fprintf(stderr,m,n1,n2,n3,n4,n5);}
123 #define DEBUG6(m,n1,n2,n3,n4,n5,n6) if(debug_mode) {fprintf(stderr,m,n1,n2,n3,n4,n5,n6);}
125 #define STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;}
126 #define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
127 #define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
129 #define ROTATE_BD_ADDR(p1, p2) \
140 UINT8 vsc_for_pcm_config[5] = { 0x00, 0x00, 0x03, 0x03, 0x00 };
143 Byte1 -- 0 for MSb first
144 Byte2 -- 0 Fill value
145 Byte3 -- 1 Fill option (0:0's, 1:1's , 2:Signed, 3:Programmable)
146 Byte4 -- 1 Number of fill bits
147 Byte5 -- 1 Right justified (0 for left justified)
150 UINT8 vsc_for_sco_pcm[5] = { 0x00, 0x01, 0x00, 0x01, 0x01 };
153 Neverland : PCM, 256, short, master ,master
154 Volance : PCM, 256, short, master ,master
156 Byte1 -- 0 for PCM 1 for UART or USB
157 Byte2 -- 0 : 128, 1: 256, 2:512, 3:1024, 4:2048 Khz
158 Byte3 -- 0 for short frame sync 1 for long frame sync
159 Byte4 -- 0 Clock direction 0 for same as sync 1 for opposite direction
160 Byte5 -- 0 for slave 1 for master
163 int fd; /* HCI handle */
165 BOOLEAN debug_mode = FALSE; /* Debug Mode Enable */
167 BOOLEAN use_two_stop_bits = FALSE; /* Flag of two stop bits for tty */
169 BOOLEAN use_high_speed_download_mode = TRUE; /* Flag of High Speed download mode */
171 unsigned char buffer[1024];
180 bcm_product_type bcm_target_product = BCM_UNKNOWN;
183 bcm_product_type bcm_product;
185 } bcm_product_table[] = {
186 { BCM_UNKNOWN, "UNKNOWN"},
187 { BCM4330, "BCM4330"},
188 { BCM4334W, "BCM4334W"},
189 { BCM4343W, "BCM4343W"},
193 struct termios termios;
195 void ChangeBaudRate(UINT32 baudrate);
197 void exit_err(UINT8 err)
199 if (use_high_speed_download_mode)
200 ChangeBaudRate(115200);
205 void print_time(void)
211 rs = clock_gettime(CLOCK_REALTIME, &tp);
212 fprintf(stderr, "[%04d : %06d]\n", tp.tv_sec, tp.tv_nsec / 1000);
217 void dump(unsigned char *out, int len)
221 for (i = 0; i < len; i++) {
225 DEBUG1("%02x ", out[i]);
230 UINT8 SendCommand(UINT16 opcode, UINT8 param_len, UINT8 * p_param_buf)
232 UINT8 pbuf[255] = { 0, };
236 pbuf[1] = (UINT8) (opcode);
237 pbuf[2] = (UINT8) (opcode >> 8);
240 for (i = 0; i < param_len; i++) {
241 pbuf[i + 4] = *p_param_buf++;
244 DEBUG1("Send %d", param_len + 4);
246 dump(pbuf, param_len + 4);
248 if (write(fd, pbuf, param_len + 4) < 0)
249 DEBUG0("Fail to write pbuf");
254 void expired(int sig)
256 static UINT8 count = 0;
257 DEBUG0("expired try again\n");
258 SendCommand(HCI_RESET, 0, NULL);
263 fprintf(stderr, "[ERR] HCI reset time expired\n");
268 void read_event(int fd, unsigned char *buffer)
274 while ((count = read(fd, &buffer[i], len)) < len) {
282 while ((count = read(fd, &buffer[i], len)) < len) {
290 DEBUG1("\nreceived %d", count);
295 INT32 filesize(char *name)
301 flag = stat(name, &buf);
309 void DisplayProgress(int total, int val)
312 #define PROGRESS_NUM 20
316 char text[PROGRESS_NUM + 2] = { 0, };
319 text[PROGRESS_NUM + 1] = ']';
320 p = (val * PROGRESS_NUM) / total;
322 for (i = 1; i <= p; i++) {
326 for (i = p + 1; i <= PROGRESS_NUM; i++) {
330 for (i = 0; i <= (PROGRESS_NUM + 1); i++) {
331 fprintf(stderr, "%c", text[i]);
334 if (p >= PROGRESS_NUM)
335 fprintf(stderr, " %6d/%6d\n", val, total);
337 fprintf(stderr, " %6d/%6d\r", val, total);
340 fprintf(stderr, " %6d/%6d\n", val, total);
342 fprintf(stderr, " %6d/%6d\r", val, total);
346 UINT8 DownloadPatchram(char *patchram1)
349 char prm[128] = { 0, };
358 DEBUG1("\n%s\n", patchram1);
361 DEBUG0("HCI reset\n");
362 SendCommand(HCI_RESET, 0, NULL);
364 read_event(fd, buffer);
367 if (use_high_speed_download_mode)
368 ChangeBaudRate(3000000);
370 strcpy(prm, patchram1);
372 fprintf(stderr, "Download Start\n");
374 if ((pFile = fopen(prm, "r")) == NULL) {
375 fprintf(stderr, "file %s could not be opened, error %d\n", prm,
381 FileSize = filesize(prm);
384 SendCommand(HCI_BRCM_DOWNLOAD_MINI_DRV, 0, NULL);
385 read_event(fd, buffer);
389 while (fread(&buffer[1], sizeof(UINT8), 3, pFile)) {
394 size = fread(&buffer[4], sizeof(UINT8), len, pFile);
395 fprintf(stderr, "fread size: %d\n", (int) size);
397 size = write(fd, buffer, len + 4);
398 fprintf(stderr, "write size: %d\n", (int) size);
400 /* dispaly progress */
401 SentSize += (len + 3);
403 DisplayProgress(FileSize, SentSize);
405 /* dispaly progress */
407 read_event(fd, buffer);
412 if (bcm_target_product == BCM4343W) {
413 fprintf(stderr, "Delay 200ms for BCM4343W Wireless Charging Feature\n");
414 usleep(200000); /*200ms delay */
416 usleep(100000); /*100ms delay */
419 tcflush(fd, TCIOFLUSH);
420 tcgetattr(fd, &termios);
422 termios.c_cflag |= CRTSCTS;
424 if (use_two_stop_bits)
425 termios.c_cflag |= CSTOPB;
427 tcsetattr(fd, TCSANOW, &termios);
428 tcflush(fd, TCIOFLUSH);
429 tcsetattr(fd, TCSANOW, &termios);
430 tcflush(fd, TCIOFLUSH);
431 tcflush(fd, TCIOFLUSH);
432 cfsetospeed(&termios, B115200);
433 cfsetispeed(&termios, B115200);
434 tcsetattr(fd, TCSANOW, &termios);
436 /* Send HCI_RESET Command and process event */
437 DEBUG0("HCI reset\n");
438 SendCommand(HCI_RESET, 0, NULL);
440 read_event(fd, buffer);
442 fprintf(stderr, "Download Complete\n");
447 void SetScanEnable(void)
451 /* 0x00: No scan enabled */
452 /* 0x01: Inquiry scan enabled | Page scan disabled */
453 /* 0x02: Inquiry scan disabled | Page scan enabled */
454 /* 0x03: Inquiry scan enabled | Page scan enabled */
457 SendCommand(HCI_WRITE_SCAN_ENABLE, 1, &scan_data[0]);
458 read_event(fd, buffer);
461 /* This patch has been added to write PCM setting for Ponte */
462 void SetAudio_for_PCM(void)
464 fprintf(stderr, "Write Audio parameter for PCM\n");
466 vsc_for_pcm_config[0] = 0x0;
467 vsc_for_pcm_config[1] = 0x0;
468 vsc_for_pcm_config[2] = 0x3; /* PCM format 16bit */
469 vsc_for_pcm_config[3] = 0x0;
470 vsc_for_pcm_config[4] = 0x0;
472 DEBUG5("vsc_for_pcm_config = {%d,%d,%d,%d,%d}\n", vsc_for_pcm_config[0],
473 vsc_for_pcm_config[1], vsc_for_pcm_config[2],
474 vsc_for_pcm_config[3], vsc_for_pcm_config[4]);
476 SendCommand(VSC_WRITE_PCM_DATA_FORMAT_PARAM, 5,
477 (UINT8 *) vsc_for_pcm_config);
478 read_event(fd, buffer);
483 fprintf(stderr, "Write Audio parameter\n");
485 DEBUG5("vsc_for_sco_pcm = {%d,%d,%d,%d,%d}\n", vsc_for_sco_pcm[0],
486 vsc_for_sco_pcm[1], vsc_for_sco_pcm[2],
487 vsc_for_sco_pcm[3], vsc_for_sco_pcm[4]);
489 SendCommand(HCI_BRCM_WRITE_SCO_PCM_INT_PARAM, 5,
490 (UINT8 *) vsc_for_sco_pcm);
491 read_event(fd, buffer);
493 DEBUG5("vsc_for_pcm_config = {%d,%d,%d,%d,%d}\n", vsc_for_pcm_config[0],
494 vsc_for_pcm_config[1], vsc_for_pcm_config[2],
495 vsc_for_pcm_config[3], vsc_for_pcm_config[4]);
497 SendCommand(VSC_WRITE_PCM_DATA_FORMAT_PARAM, 5,
498 (UINT8 *) vsc_for_pcm_config);
499 read_event(fd, buffer);
502 void SetPcmConf(UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4)
504 vsc_for_pcm_config[0] = p0;
505 vsc_for_pcm_config[1] = p1;
506 vsc_for_pcm_config[2] = p2;
507 vsc_for_pcm_config[3] = p3;
508 vsc_for_pcm_config[4] = p4;
511 void SetScoConf(UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4)
513 vsc_for_sco_pcm[0] = p0;
514 vsc_for_sco_pcm[1] = p1;
515 vsc_for_sco_pcm[2] = p2;
516 vsc_for_sco_pcm[3] = p3;
517 vsc_for_sco_pcm[4] = p4;
520 void HCILP_Enable(BOOLEAN on)
522 /* Host Stack Idle Threshold */
523 UINT8 hcilp_idle_threshold = 0x01;
525 /* Host Controller Idle Threshold */
526 UINT8 hcilp_hc_idle_threshold = 0x01;
528 if (bcm_target_product == BCM4343W) {
529 hcilp_idle_threshold = 0x0A;
530 hcilp_hc_idle_threshold = 0x0A;
533 fprintf(stderr, "Set Low Power mode %d for %s\n", on,
534 bcm_product_table[bcm_target_product].name);
536 UINT8 data[HCI_BRCM_WRITE_SLEEP_MODE_LENGTH] = {
537 0x01, /* Sleep Mode algorithm 1 */
538 hcilp_idle_threshold, /* Host Idle Treshold */
539 hcilp_hc_idle_threshold, /* Host Controller Idle Treshold*//* this should be less than scan interval. */
540 HCILP_BT_WAKE_POLARITY, /* BT_WAKE Polarity - 0=Active Low, 1= Active High */
541 HCILP_HOST_WAKE_POLARITY, /* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
542 0x01, /* Allow host Sleep during SCO */
543 0x01, /* Combine Sleep Mode and LPM - The device will not sleep in mode 0 if this flag is set to 1, */
544 0x00, /* UART_TXD Tri-State : 0x00 = Do not tri-state UART_TXD in sleep mode */
545 0x00, /* NA to Mode 1 */
546 0x00, /* NA to Mode 1 */
557 SendCommand(HCI_BRCM_WRITE_SLEEP_MODE, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH,
559 read_event(fd, buffer);
562 UINT32 uart_speed(UINT32 Speed)
590 void ChangeBaudRate(UINT32 baudrate)
592 UINT8 hci_data[HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH] =
593 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
594 UINT8 uart_clock_24 = 0x2; /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */
595 UINT8 uart_clock_48 = 0x1; /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */
606 /* Write UART Clock setting of 24MHz */
607 DEBUG0("Change UART_CLOCK 24Mhz\n");
608 SendCommand(VSC_WRITE_UART_CLOCK_SETTING,
609 VSC_WRITE_UART_CLOCK_SETTING_LEN,
610 (UINT8 *) & uart_clock_24);
611 read_event(fd, buffer);
616 /* Write UART Clock setting of 48MHz */
617 DEBUG0("Change UART_CLOCK 48Mhz\n");
618 SendCommand(VSC_WRITE_UART_CLOCK_SETTING,
619 VSC_WRITE_UART_CLOCK_SETTING_LEN,
620 (UINT8 *) & uart_clock_48);
621 read_event(fd, buffer);
625 fprintf(stderr, "Not Support baudrate = %ld\n", baudrate);
630 hci_data[2] = baudrate & 0xFF;
631 hci_data[3] = (baudrate >> 8) & 0xFF;
632 hci_data[4] = (baudrate >> 16) & 0xFF;
633 hci_data[5] = (baudrate >> 24) & 0xFF;
635 DEBUG1("Change Baudrate %ld\n", baudrate);
637 SendCommand(HCI_BRCM_UPDATE_BAUDRATE_CMD,
638 HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH,
640 read_event(fd, buffer);
642 tcflush(fd, TCIOFLUSH);
643 tcgetattr(fd, &termios);
645 termios.c_cflag |= CRTSCTS;
647 if (use_two_stop_bits)
648 termios.c_cflag |= CSTOPB;
650 tcsetattr(fd, TCSANOW, &termios);
651 tcflush(fd, TCIOFLUSH);
652 tcsetattr(fd, TCSANOW, &termios);
653 tcflush(fd, TCIOFLUSH);
654 tcflush(fd, TCIOFLUSH);
655 cfsetospeed(&termios, uart_speed(baudrate));
656 cfsetispeed(&termios, uart_speed(baudrate));
657 tcsetattr(fd, TCSANOW, &termios);
661 void EnableTestMode(void)
663 UINT8 filter_data[] = { 0x02, 0x00, 0x02 };
665 /* bt sleep disable */
668 /* Enable both Inquiry & Page Scans */
671 /* Set Event Filter: Enable Auto Connect */
672 SendCommand(HCI_SET_EVENT_FILTER, 0x03, (UINT8 *) filter_data);
673 read_event(fd, buffer);
675 /* Enable Device under test */
676 SendCommand(HCI_ENABLE_DEV_UNDER_TEST_MODE, 0x0, NULL);
677 read_event(fd, buffer);
679 fprintf(stderr, "Enable Device Under Test\n");
682 void GetLocalName(void)
687 DEBUG0("HCI reset\n");
688 SendCommand(HCI_RESET, 0, NULL);
690 read_event(fd, buffer);
693 DEBUG0("Read Local Name\n");
694 SendCommand(HCI_READ_LOCAL_NAME, 0, NULL);
695 read_event(fd, buffer);
699 fprintf(stderr, "Chip Name is %s\n", data);
702 void SetLocalFeatures(void)
706 DEBUG0("Read Local Feature\n");
707 SendCommand(HCI_READ_LOCAL_FEATURES, 0, NULL);
708 read_event(fd, buffer);
712 #if (BCM_DISABLE_RF_PWRCTRL == TRUE)
713 fprintf(stderr, "Remove Power Control\n");
714 data[2] &= 0xFB; /* Power contrel */
716 DEBUG0("Write Local Feature\n");
717 SendCommand(VSC_HCI_CMD_SET_LOC_FEATURES_CMD, 0x08, (UINT8 *) data);
718 read_event(fd, buffer);
724 int proto = HCI_UART_H4;
726 if (ioctl(fd, TIOCSETD, &i) < 0) {
727 fprintf(stderr, "Can't set line discipline\n");
731 if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) {
732 fprintf(stderr, "Can't set hci protocol\n");
735 fprintf(stderr, "Done setting line discpline\n");
740 void SetBcmProductType(char *bcm_product_name)
744 if (bcm_product_name == NULL) {
745 bcm_target_product = BCM_UNKNOWN;
749 for (i = 0; bcm_product_table[i].name != NULL; i++) {
750 if (!strcasecmp(bcm_product_table[i].name,bcm_product_name)) {
751 bcm_target_product = bcm_product_table[i].bcm_product;
752 fprintf(stderr, "Detected name is %s\n",
753 bcm_product_table[i].name);
760 void print_usage(void)
762 fprintf(stderr, "\n");
763 fprintf(stderr, "BRCM BT tool for Linux release %s\n", RELEASE_DATE);
764 fprintf(stderr, "\n");
766 " Usage: bcmtool <tty Device> <command> [command parameter],....\n\n");
768 " -FILE Patchram file name EX) -FILE=BCM43xx_xxx.hcd\n");
770 " -BAUD Set Baudrate EX) -BAUD=3000000\n");
772 " -ADDR BD addr file name EX) -ADDR=.bdaddr\n");
773 fprintf(stderr, " -SCO Enable SCO/PCM config EX) -SCO\n");
774 fprintf(stderr, " -PCM_SETTING Write PCM config EX) -PCM_SETTING\n");
776 " -SETSCO SCO/PCM values verify EX) -SETSCO=0,1,0,1,1,0,0,3,3,0\n");
777 fprintf(stderr, " -LP Enable Low power EX) -LP\n");
778 fprintf(stderr, " -FEATURE Set local Feature EX) -FEATURE\n");
779 fprintf(stderr, " -GETNAME Get local Name EX) -GETNAME\n");
781 " -DUT Enable DUT mode(do not use with -LP) EX) -DUT\n");
783 " -ATTACH Attach BT controller to BlueZ stack EX) -ATTACH\n");
784 fprintf(stderr, " -DEBUG Debug message EX) -DEBUG\n");
785 fprintf(stderr, " -CSTOPB Set two stop bits for tty EX) -CSTOPB\n");
786 fprintf(stderr, " -SLOWDOWN Set low speed download mode \n");
787 fprintf(stderr, " default is High speed mode EX) -SLOWDOWN\n");
788 fprintf(stderr, " -TYPE BCM Product name EX) -TYPE=BCM4343W\n");
790 fprintf(stderr, "\n");
793 int main(int argc, char *argv[])
801 fprintf(stderr, "BRCM BT tool for Linux release %s\n",
806 if ((fd = open(argv[1], O_RDWR | O_NOCTTY)) == -1) {
807 fprintf(stderr, "port %s could not be opened, error %d\n",
812 tcflush(fd, TCIOFLUSH);
813 tcgetattr(fd, &termios);
815 termios.c_cflag |= CRTSCTS;
817 if (use_two_stop_bits)
818 termios.c_cflag |= CSTOPB;
820 tcsetattr(fd, TCSANOW, &termios);
821 tcflush(fd, TCIOFLUSH);
822 tcsetattr(fd, TCSANOW, &termios);
823 tcflush(fd, TCIOFLUSH);
824 tcflush(fd, TCIOFLUSH);
825 cfsetospeed(&termios, B115200);
826 cfsetispeed(&termios, B115200);
827 tcsetattr(fd, TCSANOW, &termios);
829 signal(SIGALRM, expired);
831 for (i = 2; i < argc; i++) {
834 if (strstr(ptr, "-DEBUG")) {
836 DEBUG0("DEBUG On\n");
838 } else if (strstr(ptr, "-CSTOPB")) {
839 use_two_stop_bits = TRUE;
840 DEBUG0("Use two stop bits for tty\n");
842 } else if (strstr(ptr, "-SLOWDOWN")) {
843 use_high_speed_download_mode = FALSE;
844 DEBUG0("Disable High Speed Download mode\n");
846 } else if (strstr(ptr, "-TYPE=")) {
847 char bcm_product_name[128];
850 strncpy(bcm_product_name,ptr,8);
852 SetBcmProductType(bcm_product_name);
856 for (i = 2; i < argc; i++) {
862 fprintf(stderr, "[%d] %s\n", i - 1, ptr);
864 if (strstr(ptr, "-FILE=")) {
869 strncpy(prm_name, ptr, 127);
870 DownloadPatchram(prm_name);
872 } else if (strstr(ptr, "-BAUD=")) {
876 baudrate = atoi(ptr);
878 ChangeBaudRate(baudrate);
879 } else if (strstr(ptr, "-ADDR=")) {
880 char *bdaddr_filename;
883 int bdaddr[10]; /* Displayed BD Address */
885 BD_ADDR local_addr; /* BD Address for write */
890 (ptr, "%02X:%02X:%02X:%02X:%02X:%02X", &bdaddr[0],
891 &bdaddr[1], &bdaddr[2], &bdaddr[3], &bdaddr[4],
893 fprintf(stderr, "-ADDR: Parameter error");
896 bte_write_bdaddr(bdaddr);
899 bdaddr_filename = ptr;
901 if (bdaddr_filename) {
902 pFile = fopen(bdaddr_filename, "r");
908 char text[BTUI_MAX_STRING_LENGTH_PER_LINE];
910 if (!fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile))
911 fprintf(stderr, "fail to fgets");
913 sscanf(text, "%02x%02x", &bdaddr[0],
916 if (!fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile))
917 fprintf(stderr, "fail to fgets");
919 sscanf(text, "%02x", &bdaddr[2]);
921 if (!fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE, pFile))
922 fprintf(stderr, "fail to fgets");
924 sscanf(text, "%02x%02x%02x", &bdaddr[3],
925 &bdaddr[4], &bdaddr[5]);
928 "Writing B/D Address = %02X:%02X:%02X:%02X:%02X:%02X\n",
929 bdaddr[0], bdaddr[1], bdaddr[2],
930 bdaddr[3], bdaddr[4], bdaddr[5]);
932 ROTATE_BD_ADDR(local_addr, bdaddr);
934 SendCommand(VSC_WRITE_BD_ADDR, BD_ADDR_LEN,
935 (UINT8 *) local_addr);
936 read_event(fd, buffer);
938 fprintf(stderr, "-ADDR: file open fail\n");
941 } else if (strstr(ptr, "-PCM_SETTING")) {
944 } else if (strstr(ptr, "-SCO")) {
947 } else if (strstr(ptr, "-SETSCO=")) {
952 (ptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", &value[0],
953 &value[1], &value[2], &value[3], &value[4],
954 &value[5], &value[6], &value[7], &value[8],
956 DEBUG0("PCM / SCO configuration value err\n");
958 ("SCO_Routing,PCM_Interface_Rate,Frame_Type,Sync_Mode,Clock_Mode,LSB_First,Fill_bits,Fill_Method,Fill_Num,Right_Justify\n");
962 SetScoConf(value[0], value[1], value[2], value[3],
964 SetPcmConf(value[5], value[6], value[7], value[8],
967 } else if (strstr(ptr, "-LP")) {
969 } else if (strstr(ptr, "-DUT")) {
971 } else if (strstr(ptr, "-FEATURE")) {
973 } else if (strstr(ptr, "-GETNAME")) {
975 } else if (strstr(ptr, "-ATTACH")) {
980 } else if (strstr(ptr, "-DEBUG")) {
981 } else if (strstr(ptr, "-CSTOPB")) {
982 } else if (strstr(ptr, "-SLOWDOWN")) {
983 } else if (strstr(ptr, "-TYPE")) {
985 fprintf(stderr, "Invalid parameter(s)!\n");
990 fprintf(stderr, "EXIT\n");