diff --git a/chipset/csr/btstack_chipset_csr.c b/chipset/csr/btstack_chipset_csr.c index 037f6c626..043501788 100644 --- a/chipset/csr/btstack_chipset_csr.c +++ b/chipset/csr/btstack_chipset_csr.c @@ -55,38 +55,48 @@ #include "btstack_util.h" #include "hci_transport.h" +enum update_result { + OK, + SKIP, +}; + // minimal CSR init script to configure PSKEYs and activate them static const uint8_t init_script[] = { - // Set ANA_Freq to 26MHz - 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xfe, 0x01, 0x01, 0x00, 0x00, 0x00, 0x90, 0x65, + // 0x01fe: Set ANA_Freq to 26MHz + 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xfe, 0x01, 0x01, 0x00, 0x00, 0x00, 0x90, 0x65, - // Set HCI_NOP_DISABLE - 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + // 0x00f2: Set HCI_NOP_DISABLE + 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, #ifdef ENABLE_SCO_OVER_HCI - // Set HOSTIO_MAP_SCO_PCM to 0 - 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xab, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - // Set HOSTIO_MAP_SCO_CODEC to 0 - 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x03, 0x70, 0x00, 0x00, 0xb0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - // Set ENABLE_SCO_STREAMS to 0 - 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xc9, 0x22, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x01ab: Set HOSTIO_MAP_SCO_PCM to 0 + 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xab, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x01b0: Set HOSTIO_MAP_SCO_CODEC to 0 + 0x00, 0xFC, 0x13, 0xc2, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x03, 0x70, 0x00, 0x00, 0xb0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x22c9: Set ENABLE_SCO_STREAMS to 0 + 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xc9, 0x22, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, #endif - // Enable RTS/CTS for BCSP (0806 -> 080e) - 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xbf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x08, + // 0x01bf: Enable RTS/CTS for BCSP (0806 -> 080e) + 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xbf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x08, - // Set UART baudrate to 115200 - 0x01, 0x00, 0xFC, 0x15, 0xc2, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x03, 0x70, 0x00, 0x00, 0xea, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc2, + // 0x01ea: Set UART baudrate to 115200 + 0x00, 0xFC, 0x15, 0xc2, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x03, 0x70, 0x00, 0x00, 0xea, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc2, + + // 0x0001: Set Bluetooth address + 0x00, 0xFC, 0x19, 0xc2, 0x02, 0x00, 0x0A, 0x00, 0x03, 0x00, 0x03, 0x70, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf3, 0x00, 0xf5, 0xf4, 0xf2, 0x00, 0xf2, 0xf1, // WarmReset - 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x03, 0x0e, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x03, 0x0e, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const uint16_t init_script_size = sizeof(init_script); // static uint32_t init_script_offset = 0; static hci_transport_config_uart_t * hci_transport_config_uart = NULL; +static int set_bd_addr; +static bd_addr_t bd_addr; static void chipset_init(const void * config){ init_script_offset = 0; @@ -98,51 +108,70 @@ static void chipset_init(const void * config){ } // set requested baud rate -static void update_init_script_command(uint8_t *hci_cmd_buffer){ +// @return 0 = OK, 1 = SKIP, 2 = .. +static enum update_result update_init_script_command(uint8_t *hci_cmd_buffer){ uint16_t varid = little_endian_read_16(hci_cmd_buffer, 10); - if (varid != 0x7003) return; + if (varid != 0x7003) return OK; uint16_t key = little_endian_read_16(hci_cmd_buffer, 14); log_info("csr: pskey 0x%04x", key); - if (key != 0x01ea) return; - - // check for baud rate - if (!hci_transport_config_uart) return; - uint32_t baudrate = hci_transport_config_uart->baudrate_main; - if (baudrate == 0){ - baudrate = hci_transport_config_uart->baudrate_init; + switch (key){ + case 0x001: + // set bd addr command + if (!set_bd_addr) return SKIP; + hci_cmd_buffer[20] = bd_addr[3]; + hci_cmd_buffer[22] = bd_addr[5]; + hci_cmd_buffer[23] = bd_addr[4]; + hci_cmd_buffer[24] = bd_addr[2]; + hci_cmd_buffer[26] = bd_addr[1]; + hci_cmd_buffer[27] = bd_addr[0]; + return OK; + case 0x01ea: + // baud rate command + if (!hci_transport_config_uart) return OK; + uint32_t baudrate = hci_transport_config_uart->baudrate_main; + if (baudrate == 0){ + baudrate = hci_transport_config_uart->baudrate_init; + } + // uint32_t is stored as 2 x uint16_t with most important 16 bits first + little_endian_store_16(hci_cmd_buffer, 20, baudrate >> 16); + little_endian_store_16(hci_cmd_buffer, 22, baudrate & 0xffff); + break; + default: + break; } - // uint32_t is stored as 2 x uint16_t with most important 16 bits first - little_endian_store_16(hci_cmd_buffer, 20, baudrate >> 16); - little_endian_store_16(hci_cmd_buffer, 22, baudrate & 0xffff); + return OK; } static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){ - if (init_script_offset >= init_script_size) { - return BTSTACK_CHIPSET_DONE; + while (1){ + + if (init_script_offset >= init_script_size) { + return BTSTACK_CHIPSET_DONE; + } + + // copy command header + memcpy(&hci_cmd_buffer[0], (uint8_t *) &init_script[init_script_offset], 3); + init_script_offset += 3; + int payload_len = hci_cmd_buffer[2]; + // copy command payload + memcpy(&hci_cmd_buffer[3], (uint8_t *) &init_script[init_script_offset], payload_len); + + // support for on-the-fly configuration updates + enum update_result res = update_init_script_command(hci_cmd_buffer); + init_script_offset += payload_len; + + // support for skipping commands + if (res == SKIP) continue; + + // support for warm boot command + uint16_t varid = little_endian_read_16(hci_cmd_buffer, 10); + if (varid == 0x4002){ + return BTSTACK_CHIPSET_WARMSTART_REQUIRED; + } + + return BTSTACK_CHIPSET_VALID_COMMAND; } - - // init script is stored with the HCI Command Packet Type - init_script_offset++; - // copy command header - memcpy(&hci_cmd_buffer[0], (uint8_t *) &init_script[init_script_offset], 3); - init_script_offset += 3; - int payload_len = hci_cmd_buffer[2]; - // copy command payload - memcpy(&hci_cmd_buffer[3], (uint8_t *) &init_script[init_script_offset], payload_len); - - // support for on-the-fly configuration updates - update_init_script_command(hci_cmd_buffer); - - init_script_offset += payload_len; - - // support for warm boot command - uint16_t varid = little_endian_read_16(hci_cmd_buffer, 10); - if (varid == 0x4002){ - return BTSTACK_CHIPSET_WARMSTART_REQUIRED; - } - - return BTSTACK_CHIPSET_VALID_COMMAND; } @@ -158,3 +187,12 @@ static const btstack_chipset_t btstack_chipset_bcm = { const btstack_chipset_t * btstack_chipset_csr_instance(void){ return &btstack_chipset_bcm; } + +/** + * Set BD ADDR before HCI POWER_ON + * @param bd_addr + */ +void btstack_chipset_csr_set_bd_addr(bd_addr_t new_bd_addr){ + set_bd_addr = 1; + memcpy(bd_addr, new_bd_addr, 6); +} diff --git a/chipset/csr/btstack_chipset_csr.h b/chipset/csr/btstack_chipset_csr.h index a0b747dd0..b28c9d35d 100644 --- a/chipset/csr/btstack_chipset_csr.h +++ b/chipset/csr/btstack_chipset_csr.h @@ -50,7 +50,17 @@ extern "C" { #include #include "btstack_chipset.h" +#include "bluetooth.h" + +/** + * Set BD ADDR before HCI POWER_ON + * @param bd_addr + */ +void btstack_chipset_csr_set_bd_addr(bd_addr_t bd_addr); +/** + * Get chipset instance for CSR chipsets + */ const btstack_chipset_t * btstack_chipset_csr_instance(void); #if defined __cplusplus diff --git a/port/posix-h4/main.c b/port/posix-h4/main.c index 758b38331..0ef51625f 100644 --- a/port/posix-h4/main.c +++ b/port/posix-h4/main.c @@ -227,6 +227,10 @@ int main(int argc, const char * argv[]){ const btstack_link_key_db_t * link_key_db = btstack_link_key_db_fs_instance(); hci_init(transport, (void*) &config); hci_set_link_key_db(link_key_db); + + // set BD_ADDR for CSR without Flash/unique address + // bd_addr_t own_address = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + // btstack_chipset_csr_set_bd_addr(own_address); // inform about BTstack state hci_event_callback_registration.callback = &packet_handler; diff --git a/port/posix-h5/main.c b/port/posix-h5/main.c index aa4f8cb18..2ae9a4007 100644 --- a/port/posix-h5/main.c +++ b/port/posix-h5/main.c @@ -206,6 +206,10 @@ int main(int argc, const char * argv[]){ // enable BCSP mode for CSR chipsets - auto detect might not work // hci_transport_h5_enable_bcsp_mode(); + // set BD_ADDR for CSR without Flash/unique address + // bd_addr_t own_address = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + // btstack_chipset_csr_set_bd_addr(own_address); + // enable auto-sleep mode // hci_transport_h5_set_auto_sleep(300);