mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-27 14:37:12 +00:00
hci_transport_h4: add workaround for flow control bug in CYW2070x, enable with ENABLE_CYPRESS_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
This commit is contained in:
parent
7741d2d072
commit
77291b13db
@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||||||
- port/stm32-f4discovery-cc256x: add support for built-in MEMS microphone
|
- port/stm32-f4discovery-cc256x: add support for built-in MEMS microphone
|
||||||
- libusb: add support for nRF52840-PCA10056 running Zephyr hci_usb example
|
- libusb: add support for nRF52840-PCA10056 running Zephyr hci_usb example
|
||||||
- port for Nucelo L073RZ with EM9304 DVK: stm32-l073rz-nucleo-em9304
|
- port for Nucelo L073RZ with EM9304 DVK: stm32-l073rz-nucleo-em9304
|
||||||
|
- hci_transport_h4: add workaround for flow control bug in CYW2070x, enable with ENABLE_CYPRESS_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
|
|
||||||
## Changes February 2019
|
## Changes February 2019
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ ENABLE_ATT_DELAYED_RESPONSE | Enable support for delayed ATT operations, se
|
|||||||
ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE | Enable L2CAP Enhanced Retransmission Mode. Mandatory for AVRCP Browsing
|
ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE | Enable L2CAP Enhanced Retransmission Mode. Mandatory for AVRCP Browsing
|
||||||
ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL | Enable HCI Controller to Host Flow Control, see below
|
ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL | Enable HCI Controller to Host Flow Control, see below
|
||||||
ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CC256x Flow Control during baud rate change, see chipset docs.
|
ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CC256x Flow Control during baud rate change, see chipset docs.
|
||||||
|
ENABLE_CYPRESS_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CYW2070x Flow Control during baud rate change, similar to CC256x.
|
||||||
ENABLE_TLV_FLASH_EXPLICIT_DELETE_FIELD | Enable use of explicit delete field in TLV Flash implemenation - required when flash value cannot be overwritten with zero
|
ENABLE_TLV_FLASH_EXPLICIT_DELETE_FIELD | Enable use of explicit delete field in TLV Flash implemenation - required when flash value cannot be overwritten with zero
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,9 +147,22 @@ static int read_pos;
|
|||||||
static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE + 1]; // packet type + max(acl header + acl payload, event header + event data)
|
static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE + 1]; // packet type + max(acl header + acl payload, event header + event data)
|
||||||
static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE];
|
static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
// Baudrate change bugs in TI CC256x and CYW20704
|
||||||
#ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
#ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
static const uint8_t local_version_event_prefix[] = { 0x04, 0x0e, 0x0c, 0x01, 0x01, 0x10};
|
#define ENABLE_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
static const uint8_t baud_rate_command_prefix[] = { 0x01, 0x36, 0xff, 0x04};
|
static const uint8_t baud_rate_command_prefix[] = { 0x01, 0x36, 0xff, 0x04};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_CYPRESS_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
|
#ifdef ENABLE_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
|
#error "Please enable either ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND or ENABLE_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND"
|
||||||
|
#endif
|
||||||
|
#define ENABLE_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
|
static const uint8_t baud_rate_command_prefix[] = { 0x01, 0x18, 0xfc, 0x06};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
|
static const uint8_t local_version_event_prefix[] = { 0x04, 0x0e, 0x0c, 0x01, 0x01, 0x10};
|
||||||
static enum {
|
static enum {
|
||||||
BAUDRATE_CHANGE_WORKAROUND_IDLE,
|
BAUDRATE_CHANGE_WORKAROUND_IDLE,
|
||||||
BAUDRATE_CHANGE_WORKAROUND_CHIPSET_DETECTED,
|
BAUDRATE_CHANGE_WORKAROUND_CHIPSET_DETECTED,
|
||||||
@ -243,9 +256,10 @@ static void hci_transport_h4_block_read(void){
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case H4_W4_PAYLOAD:
|
case H4_W4_PAYLOAD:
|
||||||
#ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
#ifdef ENABLE_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
if (baudrate_change_workaround_state == BAUDRATE_CHANGE_WORKAROUND_IDLE
|
if (baudrate_change_workaround_state == BAUDRATE_CHANGE_WORKAROUND_IDLE
|
||||||
&& memcmp(hci_packet, local_version_event_prefix, sizeof(local_version_event_prefix)) == 0){
|
&& memcmp(hci_packet, local_version_event_prefix, sizeof(local_version_event_prefix)) == 0){
|
||||||
|
#ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
if (little_endian_read_16(hci_packet, 11) == BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC){
|
if (little_endian_read_16(hci_packet, 11) == BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC){
|
||||||
// detect TI CC256x controller based on manufacturer
|
// detect TI CC256x controller based on manufacturer
|
||||||
log_info("Detected CC256x controller");
|
log_info("Detected CC256x controller");
|
||||||
@ -255,6 +269,18 @@ static void hci_transport_h4_block_read(void){
|
|||||||
log_info("Bluetooth controller not by TI");
|
log_info("Bluetooth controller not by TI");
|
||||||
baudrate_change_workaround_state = BAUDRATE_CHANGE_WORKAROUND_DONE;
|
baudrate_change_workaround_state = BAUDRATE_CHANGE_WORKAROUND_DONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_CYPRESS_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
|
if (little_endian_read_16(hci_packet, 11) == BLUETOOTH_COMPANY_ID_CYPRESS_SEMICONDUCTOR){
|
||||||
|
// detect Cypress controller based on manufacturer
|
||||||
|
log_info("Detected Cypress controller");
|
||||||
|
baudrate_change_workaround_state = BAUDRATE_CHANGE_WORKAROUND_CHIPSET_DETECTED;
|
||||||
|
} else {
|
||||||
|
// work around not needed
|
||||||
|
log_info("Bluetooth controller not by Cypress");
|
||||||
|
baudrate_change_workaround_state = BAUDRATE_CHANGE_WORKAROUND_DONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
packet_handler(hci_packet[0], &hci_packet[1], read_pos-1);
|
packet_handler(hci_packet[0], &hci_packet[1], read_pos-1);
|
||||||
@ -264,7 +290,7 @@ static void hci_transport_h4_block_read(void){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
#ifdef ENABLE_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
if (baudrate_change_workaround_state == BAUDRATE_CHANGE_WORKAROUND_BAUDRATE_COMMAND_SENT){
|
if (baudrate_change_workaround_state == BAUDRATE_CHANGE_WORKAROUND_BAUDRATE_COMMAND_SENT){
|
||||||
baudrate_change_workaround_state = BAUDRATE_CHANGE_WORKAROUND_IDLE;
|
baudrate_change_workaround_state = BAUDRATE_CHANGE_WORKAROUND_IDLE;
|
||||||
// avoid flowcontrol problem by reading expected hci command complete event of 7 bytes in a single block read
|
// avoid flowcontrol problem by reading expected hci command complete event of 7 bytes in a single block read
|
||||||
@ -316,7 +342,7 @@ static int hci_transport_h4_send_packet(uint8_t packet_type, uint8_t * packet, i
|
|||||||
packet--;
|
packet--;
|
||||||
*packet = packet_type;
|
*packet = packet_type;
|
||||||
|
|
||||||
#ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
#ifdef ENABLE_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND
|
||||||
if ((baudrate_change_workaround_state == BAUDRATE_CHANGE_WORKAROUND_CHIPSET_DETECTED)
|
if ((baudrate_change_workaround_state == BAUDRATE_CHANGE_WORKAROUND_CHIPSET_DETECTED)
|
||||||
&& (memcmp(packet, baud_rate_command_prefix, sizeof(baud_rate_command_prefix)) == 0)) {
|
&& (memcmp(packet, baud_rate_command_prefix, sizeof(baud_rate_command_prefix)) == 0)) {
|
||||||
log_info("Baud rate command detected, expect command complete event next");
|
log_info("Baud rate command detected, expect command complete event next");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user