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 write(fd, pbuf, param_len + 4);
252 void expired(int sig)
254 static UINT8 count = 0;
255 DEBUG0("expired try again\n");
256 SendCommand(HCI_RESET, 0, NULL);
261 fprintf(stderr, "[ERR] HCI reset time expired\n");
266 void read_event(int fd, unsigned char *buffer)
272 while ((count = read(fd, &buffer[i], len)) < len) {
280 while ((count = read(fd, &buffer[i], len)) < len) {
288 DEBUG1("\nreceived %d", count);
293 INT32 filesize(char *name)
299 flag = stat(name, &buf);
307 void DisplayProgress(int total, int val)
310 #define PROGRESS_NUM 20
314 char text[PROGRESS_NUM + 2] = { 0, };
317 text[PROGRESS_NUM + 1] = ']';
318 p = (val * PROGRESS_NUM) / total;
320 for (i = 1; i <= p; i++) {
324 for (i = p + 1; i <= PROGRESS_NUM; i++) {
328 for (i = 0; i <= (PROGRESS_NUM + 1); i++) {
329 fprintf(stderr, "%c", text[i]);
332 if (p >= PROGRESS_NUM)
333 fprintf(stderr, " %6d/%6d\n", val, total);
335 fprintf(stderr, " %6d/%6d\r", val, total);
338 fprintf(stderr, " %6d/%6d\n", val, total);
340 fprintf(stderr, " %6d/%6d\r", val, total);
344 UINT8 DownloadPatchram(char *patchram1)
347 char prm[128] = { 0, };
353 DEBUG1("\n%s\n", patchram1);
356 DEBUG0("HCI reset\n");
357 SendCommand(HCI_RESET, 0, NULL);
359 read_event(fd, buffer);
362 if (use_high_speed_download_mode)
363 ChangeBaudRate(3000000);
365 strcpy(prm, patchram1);
367 fprintf(stderr, "Download Start\n");
369 if ((pFile = fopen(prm, "r")) == NULL) {
370 fprintf(stderr, "file %s could not be opened, error %d\n", prm,
374 FileSize = filesize(prm);
376 SendCommand(HCI_BRCM_DOWNLOAD_MINI_DRV, 0, NULL);
377 read_event(fd, buffer);
381 while (fread(&buffer[1], sizeof(UINT8), 3, pFile)) {
386 fread(&buffer[4], sizeof(UINT8), len, pFile);
388 write(fd, buffer, len + 4);
390 /* dispaly progress */
391 SentSize += (len + 3);
393 DisplayProgress(FileSize, SentSize);
395 /* dispaly progress */
397 read_event(fd, buffer);
402 if (bcm_target_product == BCM4343W) {
403 fprintf(stderr, "Delay 200ms for BCM4343W Wireless Charging Feature\n");
404 usleep(200000); /*200ms delay */
406 usleep(100000); /*100ms delay */
409 tcflush(fd, TCIOFLUSH);
410 tcgetattr(fd, &termios);
412 termios.c_cflag |= CRTSCTS;
414 if (use_two_stop_bits)
415 termios.c_cflag |= CSTOPB;
417 tcsetattr(fd, TCSANOW, &termios);
418 tcflush(fd, TCIOFLUSH);
419 tcsetattr(fd, TCSANOW, &termios);
420 tcflush(fd, TCIOFLUSH);
421 tcflush(fd, TCIOFLUSH);
422 cfsetospeed(&termios, B115200);
423 cfsetispeed(&termios, B115200);
424 tcsetattr(fd, TCSANOW, &termios);
426 /* Send HCI_RESET Command and process event */
427 DEBUG0("HCI reset\n");
428 SendCommand(HCI_RESET, 0, NULL);
430 read_event(fd, buffer);
432 fprintf(stderr, "Download Complete\n");
437 void SetScanEnable(void)
441 /* 0x00: No scan enabled */
442 /* 0x01: Inquiry scan enabled | Page scan disabled */
443 /* 0x02: Inquiry scan disabled | Page scan enabled */
444 /* 0x03: Inquiry scan enabled | Page scan enabled */
447 SendCommand(HCI_WRITE_SCAN_ENABLE, 1, &scan_data[0]);
448 read_event(fd, buffer);
451 /* This patch has been added to write PCM setting for Ponte */
452 void SetAudio_for_PCM(void)
454 fprintf(stderr, "Write Audio parameter for PCM\n");
456 vsc_for_pcm_config[0] = 0x0;
457 vsc_for_pcm_config[1] = 0x0;
458 vsc_for_pcm_config[2] = 0x3; /* PCM format 16bit */
459 vsc_for_pcm_config[3] = 0x0;
460 vsc_for_pcm_config[4] = 0x0;
462 DEBUG5("vsc_for_pcm_config = {%d,%d,%d,%d,%d}\n", vsc_for_pcm_config[0],
463 vsc_for_pcm_config[1], vsc_for_pcm_config[2],
464 vsc_for_pcm_config[3], vsc_for_pcm_config[4]);
466 SendCommand(VSC_WRITE_PCM_DATA_FORMAT_PARAM, 5,
467 (UINT8 *) vsc_for_pcm_config);
468 read_event(fd, buffer);
473 fprintf(stderr, "Write Audio parameter\n");
475 DEBUG5("vsc_for_sco_pcm = {%d,%d,%d,%d,%d}\n", vsc_for_sco_pcm[0],
476 vsc_for_sco_pcm[1], vsc_for_sco_pcm[2],
477 vsc_for_sco_pcm[3], vsc_for_sco_pcm[4]);
479 SendCommand(HCI_BRCM_WRITE_SCO_PCM_INT_PARAM, 5,
480 (UINT8 *) vsc_for_sco_pcm);
481 read_event(fd, buffer);
483 DEBUG5("vsc_for_pcm_config = {%d,%d,%d,%d,%d}\n", vsc_for_pcm_config[0],
484 vsc_for_pcm_config[1], vsc_for_pcm_config[2],
485 vsc_for_pcm_config[3], vsc_for_pcm_config[4]);
487 SendCommand(VSC_WRITE_PCM_DATA_FORMAT_PARAM, 5,
488 (UINT8 *) vsc_for_pcm_config);
489 read_event(fd, buffer);
492 void SetPcmConf(UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4)
494 vsc_for_pcm_config[0] = p0;
495 vsc_for_pcm_config[1] = p1;
496 vsc_for_pcm_config[2] = p2;
497 vsc_for_pcm_config[3] = p3;
498 vsc_for_pcm_config[4] = p4;
501 void SetScoConf(UINT8 p0, UINT8 p1, UINT8 p2, UINT8 p3, UINT8 p4)
503 vsc_for_sco_pcm[0] = p0;
504 vsc_for_sco_pcm[1] = p1;
505 vsc_for_sco_pcm[2] = p2;
506 vsc_for_sco_pcm[3] = p3;
507 vsc_for_sco_pcm[4] = p4;
510 void HCILP_Enable(BOOLEAN on)
512 /* Host Stack Idle Threshold */
513 UINT8 hcilp_idle_threshold = 0x01;
515 /* Host Controller Idle Threshold */
516 UINT8 hcilp_hc_idle_threshold = 0x01;
518 if (bcm_target_product == BCM4343W) {
519 hcilp_idle_threshold = 0x0A;
520 hcilp_hc_idle_threshold = 0x0A;
523 fprintf(stderr, "Set Low Power mode %d for %s\n", on,
524 bcm_product_table[bcm_target_product].name);
526 UINT8 data[HCI_BRCM_WRITE_SLEEP_MODE_LENGTH] = {
527 0x01, /* Sleep Mode algorithm 1 */
528 hcilp_idle_threshold, /* Host Idle Treshold */
529 hcilp_hc_idle_threshold, /* Host Controller Idle Treshold*//* this should be less than scan interval. */
530 HCILP_BT_WAKE_POLARITY, /* BT_WAKE Polarity - 0=Active Low, 1= Active High */
531 HCILP_HOST_WAKE_POLARITY, /* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
532 0x01, /* Allow host Sleep during SCO */
533 0x01, /* Combine Sleep Mode and LPM - The device will not sleep in mode 0 if this flag is set to 1, */
534 0x00, /* UART_TXD Tri-State : 0x00 = Do not tri-state UART_TXD in sleep mode */
535 0x00, /* NA to Mode 1 */
536 0x00, /* NA to Mode 1 */
547 SendCommand(HCI_BRCM_WRITE_SLEEP_MODE, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH,
549 read_event(fd, buffer);
552 UINT32 uart_speed(UINT32 Speed)
580 void ChangeBaudRate(UINT32 baudrate)
582 UINT8 hci_data[HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH] =
583 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
584 UINT8 uart_clock_24 = 0x2; /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */
585 UINT8 uart_clock_48 = 0x1; /* 0x1 - UART Clock 48MHz, 0x2 - UART Clock 24MHz */
596 /* Write UART Clock setting of 24MHz */
597 DEBUG0("Change UART_CLOCK 24Mhz\n");
598 SendCommand(VSC_WRITE_UART_CLOCK_SETTING,
599 VSC_WRITE_UART_CLOCK_SETTING_LEN,
600 (UINT8 *) & uart_clock_24);
601 read_event(fd, buffer);
606 /* Write UART Clock setting of 48MHz */
607 DEBUG0("Change UART_CLOCK 48Mhz\n");
608 SendCommand(VSC_WRITE_UART_CLOCK_SETTING,
609 VSC_WRITE_UART_CLOCK_SETTING_LEN,
610 (UINT8 *) & uart_clock_48);
611 read_event(fd, buffer);
615 fprintf(stderr, "Not Support baudrate = %ld\n", baudrate);
620 hci_data[2] = baudrate & 0xFF;
621 hci_data[3] = (baudrate >> 8) & 0xFF;
622 hci_data[4] = (baudrate >> 16) & 0xFF;
623 hci_data[5] = (baudrate >> 24) & 0xFF;
625 DEBUG1("Change Baudrate %ld\n", baudrate);
627 SendCommand(HCI_BRCM_UPDATE_BAUDRATE_CMD,
628 HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH,
630 read_event(fd, buffer);
632 tcflush(fd, TCIOFLUSH);
633 tcgetattr(fd, &termios);
635 termios.c_cflag |= CRTSCTS;
637 if (use_two_stop_bits)
638 termios.c_cflag |= CSTOPB;
640 tcsetattr(fd, TCSANOW, &termios);
641 tcflush(fd, TCIOFLUSH);
642 tcsetattr(fd, TCSANOW, &termios);
643 tcflush(fd, TCIOFLUSH);
644 tcflush(fd, TCIOFLUSH);
645 cfsetospeed(&termios, uart_speed(baudrate));
646 cfsetispeed(&termios, uart_speed(baudrate));
647 tcsetattr(fd, TCSANOW, &termios);
651 void EnableTestMode(void)
653 UINT8 filter_data[] = { 0x02, 0x00, 0x02 };
655 /* bt sleep disable */
658 /* Enable both Inquiry & Page Scans */
661 /* Set Event Filter: Enable Auto Connect */
662 SendCommand(HCI_SET_EVENT_FILTER, 0x03, (UINT8 *) filter_data);
663 read_event(fd, buffer);
665 /* Enable Device under test */
666 SendCommand(HCI_ENABLE_DEV_UNDER_TEST_MODE, 0x0, NULL);
667 read_event(fd, buffer);
669 fprintf(stderr, "Enable Device Under Test\n");
672 void GetLocalName(void)
677 DEBUG0("HCI reset\n");
678 SendCommand(HCI_RESET, 0, NULL);
680 read_event(fd, buffer);
683 DEBUG0("Read Local Name\n");
684 SendCommand(HCI_READ_LOCAL_NAME, 0, NULL);
685 read_event(fd, buffer);
689 fprintf(stderr, "Chip Name is %s\n", data);
692 void SetLocalFeatures(void)
696 DEBUG0("Read Local Feature\n");
697 SendCommand(HCI_READ_LOCAL_FEATURES, 0, NULL);
698 read_event(fd, buffer);
702 #if (BCM_DISABLE_RF_PWRCTRL == TRUE)
703 fprintf(stderr, "Remove Power Control\n");
704 data[2] &= 0xFB; /* Power contrel */
706 DEBUG0("Write Local Feature\n");
707 SendCommand(VSC_HCI_CMD_SET_LOC_FEATURES_CMD, 0x08, (UINT8 *) data);
708 read_event(fd, buffer);
714 int proto = HCI_UART_H4;
716 if (ioctl(fd, TIOCSETD, &i) < 0) {
717 fprintf(stderr, "Can't set line discipline\n");
721 if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) {
722 fprintf(stderr, "Can't set hci protocol\n");
725 fprintf(stderr, "Done setting line discpline\n");
730 void SetBcmProductType(char *bcm_product_name)
734 if (bcm_product_name == NULL) {
735 bcm_target_product = BCM_UNKNOWN;
739 for (i = 0; bcm_product_table[i].name != NULL; i++) {
740 if (!strcasecmp(bcm_product_table[i].name,bcm_product_name)) {
741 bcm_target_product = bcm_product_table[i].bcm_product;
742 fprintf(stderr, "Detected name is %s\n",
743 bcm_product_table[i].name);
750 void print_usage(void)
752 fprintf(stderr, "\n");
753 fprintf(stderr, "BRCM BT tool for Linux release %s\n", RELEASE_DATE);
754 fprintf(stderr, "\n");
756 " Usage: bcmtool <tty Device> <command> [command parameter],....\n\n");
758 " -FILE Patchram file name EX) -FILE=BCM43xx_xxx.hcd\n");
760 " -BAUD Set Baudrate EX) -BAUD=3000000\n");
762 " -ADDR BD addr file name EX) -ADDR=.bdaddr\n");
763 fprintf(stderr, " -SCO Enable SCO/PCM config EX) -SCO\n");
764 fprintf(stderr, " -PCM_SETTING Write PCM config EX) -PCM_SETTING\n");
766 " -SETSCO SCO/PCM values verify EX) -SETSCO=0,1,0,1,1,0,0,3,3,0\n");
767 fprintf(stderr, " -LP Enable Low power EX) -LP\n");
768 fprintf(stderr, " -FEATURE Set local Feature EX) -FEATURE\n");
769 fprintf(stderr, " -GETNAME Get local Name EX) -GETNAME\n");
771 " -DUT Enable DUT mode(do not use with -LP) EX) -DUT\n");
773 " -ATTACH Attach BT controller to BlueZ stack EX) -ATTACH\n");
774 fprintf(stderr, " -DEBUG Debug message EX) -DEBUG\n");
775 fprintf(stderr, " -CSTOPB Set two stop bits for tty EX) -CSTOPB\n");
776 fprintf(stderr, " -SLOWDOWN Set low speed download mode \n");
777 fprintf(stderr, " default is High speed mode EX) -SLOWDOWN\n");
778 fprintf(stderr, " -TYPE BCM Product name EX) -TYPE=BCM4343W\n");
780 fprintf(stderr, "\n");
783 int main(int argc, char *argv[])
791 fprintf(stderr, "BRCM BT tool for Linux release %s\n",
796 if ((fd = open(argv[1], O_RDWR | O_NOCTTY)) == -1) {
797 fprintf(stderr, "port %s could not be opened, error %d\n",
802 tcflush(fd, TCIOFLUSH);
803 tcgetattr(fd, &termios);
805 termios.c_cflag |= CRTSCTS;
807 if (use_two_stop_bits)
808 termios.c_cflag |= CSTOPB;
810 tcsetattr(fd, TCSANOW, &termios);
811 tcflush(fd, TCIOFLUSH);
812 tcsetattr(fd, TCSANOW, &termios);
813 tcflush(fd, TCIOFLUSH);
814 tcflush(fd, TCIOFLUSH);
815 cfsetospeed(&termios, B115200);
816 cfsetispeed(&termios, B115200);
817 tcsetattr(fd, TCSANOW, &termios);
819 signal(SIGALRM, expired);
821 for (i = 2; i < argc; i++) {
824 if (strstr(ptr, "-DEBUG")) {
826 DEBUG0("DEBUG On\n");
828 } else if (strstr(ptr, "-CSTOPB")) {
829 use_two_stop_bits = TRUE;
830 DEBUG0("Use two stop bits for tty\n");
832 } else if (strstr(ptr, "-SLOWDOWN")) {
833 use_high_speed_download_mode = FALSE;
834 DEBUG0("Disable High Speed Download mode\n");
836 } else if (strstr(ptr, "-TYPE=")) {
837 char bcm_product_name[128];
840 strncpy(bcm_product_name,ptr,8);
842 SetBcmProductType(bcm_product_name);
846 for (i = 2; i < argc; i++) {
852 fprintf(stderr, "[%d] %s\n", i - 1, ptr);
854 if (strstr(ptr, "-FILE=")) {
859 strncpy(prm_name, ptr, 127);
860 DownloadPatchram(prm_name);
862 } else if (strstr(ptr, "-BAUD=")) {
866 baudrate = atoi(ptr);
868 ChangeBaudRate(baudrate);
869 } else if (strstr(ptr, "-ADDR=")) {
870 char *bdaddr_filename;
873 int bdaddr[10]; /* Displayed BD Address */
875 BD_ADDR local_addr; /* BD Address for write */
880 (ptr, "%02X:%02X:%02X:%02X:%02X:%02X", &bdaddr[0],
881 &bdaddr[1], &bdaddr[2], &bdaddr[3], &bdaddr[4],
883 fprintf(stderr, "-ADDR: Parameter error");
886 bte_write_bdaddr(bdaddr);
889 bdaddr_filename = ptr;
891 if (bdaddr_filename) {
892 pFile = fopen(bdaddr_filename, "r");
896 char text[BTUI_MAX_STRING_LENGTH_PER_LINE];
898 fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE,
900 sscanf(text, "%02x%02x", &bdaddr[0],
903 fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE,
905 sscanf(text, "%02x", &bdaddr[2]);
907 fgets(text, BTUI_MAX_STRING_LENGTH_PER_LINE,
909 sscanf(text, "%02x%02x%02x", &bdaddr[3],
910 &bdaddr[4], &bdaddr[5]);
913 "Writing B/D Address = %02X:%02X:%02X:%02X:%02X:%02X\n",
914 bdaddr[0], bdaddr[1], bdaddr[2],
915 bdaddr[3], bdaddr[4], bdaddr[5]);
917 ROTATE_BD_ADDR(local_addr, bdaddr);
919 SendCommand(VSC_WRITE_BD_ADDR, BD_ADDR_LEN,
920 (UINT8 *) local_addr);
921 read_event(fd, buffer);
923 fprintf(stderr, "-ADDR: file open fail\n");
926 } else if (strstr(ptr, "-PCM_SETTING")) {
929 } else if (strstr(ptr, "-SCO")) {
932 } else if (strstr(ptr, "-SETSCO=")) {
937 (ptr, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", &value[0],
938 &value[1], &value[2], &value[3], &value[4],
939 &value[5], &value[6], &value[7], &value[8],
941 DEBUG0("PCM / SCO configuration value err\n");
943 ("SCO_Routing,PCM_Interface_Rate,Frame_Type,Sync_Mode,Clock_Mode,LSB_First,Fill_bits,Fill_Method,Fill_Num,Right_Justify\n");
947 SetScoConf(value[0], value[1], value[2], value[3],
949 SetPcmConf(value[5], value[6], value[7], value[8],
952 } else if (strstr(ptr, "-LP")) {
954 } else if (strstr(ptr, "-DUT")) {
956 } else if (strstr(ptr, "-FEATURE")) {
958 } else if (strstr(ptr, "-GETNAME")) {
960 } else if (strstr(ptr, "-ATTACH")) {
965 } else if (strstr(ptr, "-DEBUG")) {
966 } else if (strstr(ptr, "-CSTOPB")) {
967 } else if (strstr(ptr, "-SLOWDOWN")) {
968 } else if (strstr(ptr, "-TYPE")) {
970 fprintf(stderr, "Invalid parameter(s)!\n");
975 fprintf(stderr, "EXIT\n");