csr: support setting baud rate via h4/h5

This commit is contained in:
Matthias Ringwald 2017-04-19 15:12:51 +02:00
parent cf524f2b10
commit 77b95b4145
4 changed files with 107 additions and 51 deletions

View File

@ -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);
}

View File

@ -50,7 +50,17 @@ extern "C" {
#include <stdint.h>
#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

View File

@ -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;

View File

@ -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);