Merge pull request #11518 from MukundGitHub/origin

Cypress Cordio Driver Update
pull/11614/head
Martin Kojtal 2019-09-30 15:27:26 +02:00 committed by GitHub
commit d9a141e50a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 175 additions and 30 deletions

View File

@ -29,7 +29,7 @@ CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, Pi
bt_host_wake_name(bt_host_wake_name),
bt_device_wake_name(bt_device_wake_name),
bt_host_wake(bt_host_wake_name, PIN_INPUT, PullNone, 0),
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullDefault, 1),
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullNone, 1),
host_wake_irq_event(host_wake_irq),
dev_wake_irq_event(dev_wake_irq)
{
@ -61,9 +61,10 @@ CyH4TransportDriver::~CyH4TransportDriver()
void CyH4TransportDriver::bt_host_wake_irq_handler(void)
{
sleep_manager_lock_deep_sleep();
CyH4TransportDriver::on_controller_irq();
sleep_manager_unlock_deep_sleep();
uart.attach(
callback(this, &CyH4TransportDriver::on_controller_irq),
SerialBase::RxIrq
);
}
void CyH4TransportDriver::initialize()
@ -72,6 +73,8 @@ void CyH4TransportDriver::initialize()
InterruptIn *host_wake_pin;
#endif
sleep_manager_lock_deep_sleep();
uart.format(
/* bits */ 8,
/* parity */ SerialBase::None,
@ -90,6 +93,7 @@ void CyH4TransportDriver::initialize()
);
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
if (bt_host_wake_name != NC) {
//Register IRQ for Host WAKE
host_wake_pin = new InterruptIn(bt_host_wake_name);
if (host_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
@ -97,6 +101,7 @@ void CyH4TransportDriver::initialize()
} else {
host_wake_pin->rise(callback(this, &CyH4TransportDriver::bt_host_wake_irq_handler));
}
}
#endif
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
@ -106,6 +111,7 @@ void CyH4TransportDriver::initialize()
if (bt_device_wake_name != NC)
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
}
sleep_manager_unlock_deep_sleep();
rtos::ThisThread::sleep_for(500);
}
@ -115,6 +121,7 @@ uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
{
uint16_t i = 0;
sleep_manager_lock_deep_sleep();
assert_bt_dev_wake();
while (i < len + 1) {
@ -125,11 +132,22 @@ uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
}
deassert_bt_dev_wake();
sleep_manager_unlock_deep_sleep();
return len;
}
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
void CyH4TransportDriver::on_host_stack_inactivity()
{
if (enabled_powersave) {
uart.attach(NULL, SerialBase::RxIrq);
}
}
#endif
void CyH4TransportDriver::on_controller_irq()
{
sleep_manager_lock_deep_sleep();
assert_bt_dev_wake();
while (uart.readable()) {
@ -138,31 +156,43 @@ void CyH4TransportDriver::on_controller_irq()
}
deassert_bt_dev_wake();
sleep_manager_unlock_deep_sleep();
}
void CyH4TransportDriver::assert_bt_dev_wake()
{
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
if (enabled_powersave) {
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
} else {
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
}
}
#endif
}
void CyH4TransportDriver::deassert_bt_dev_wake()
{
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
if (enabled_powersave) {
wait_us(5000); /* remove and replace when uart tx transmit complete api is available */
//De-assert bt_device_wake
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
} else {
bt_device_wake = WAKE_EVENT_ACTIVE_LOW;
}
}
#endif
}
void CyH4TransportDriver::update_uart_baud_rate(int baud)
{
uart.baud(baud);
}
bool CyH4TransportDriver::get_enabled_powersave()
{
return (enabled_powersave);

View File

@ -66,6 +66,12 @@ public:
void bt_host_wake_irq_handler();
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
void on_host_stack_inactivity();
#endif
void update_uart_baud_rate(int baud);
bool get_enabled_powersave();
uint8_t get_host_wake_irq_event();
uint8_t get_dev_wake_irq_event();
@ -101,10 +107,15 @@ private:
} // namespace ble
#define DEF_BT_BAUD_RATE (115200)
#define DEF_BT_3M_BAUD_RATE (3000000) /* Both Host and BT device have to be adapt to this */
#define WAKE_EVENT_ACTIVE_HIGH ( 1 ) /* Interrupt Rising Edge */
#define WAKE_EVENT_ACTIVE_LOW ( 0 ) /* Interrupt Falling Edge */
#if (defined(TARGET_CY8CPROTO_062_4343W))
#define BT_UART_NO_3M_SUPPORT ( 1 )
#endif
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_default_h4_transport_driver();
ble::vendor::cypress_ble::CyH4TransportDriver& ble_cordio_get_h4_transport_driver();
#endif

View File

@ -29,20 +29,35 @@
extern const int brcm_patch_ram_length;
extern const uint8_t brcm_patchram_buf[];
#ifndef BT_UART_NO_3M_SUPPORT
static const uint8_t pre_brcm_patchram_buf[] = {
// RESET followed by download mini driver cmd
// RESET followed by update uart baudrate
0x03, 0x0C, 0x00,
0x18, 0xFC, 0x06, 0x00, 0x00, 0xC0, 0xC6, 0x2D, 0x00, //update uart baudrate 3 mbp
};
#else /* BT_UART_NO_3M_SUPPORT */
static const uint8_t pre_brcm_patchram_buf[] = {
// RESET cmd
0x03, 0x0C, 0x00,
};
#endif /* BT_UART_NO_3M_SUPPORT */
static const uint8_t pre_brcm_patchram_buf2[] = {
//download mini driver
0x2E, 0xFC, 0x00,
};
static const uint8_t post_brcm_patchram_buf[] = {
// RESET cmd
0x03, 0x0C, 0x00,
};
static const int pre_brcm_patch_ram_length = sizeof(pre_brcm_patchram_buf);
static const int pre_brcm_patch_ram_length2 = sizeof(pre_brcm_patchram_buf2);
static const int post_brcm_patch_ram_length = sizeof(post_brcm_patchram_buf);
#define HCI_RESET_RAND_CNT 4
#define HCI_VS_CMD_UPDATE_UART_BAUD_RATE 0xFC18
#define HCI_VS_CMD_SET_SLEEP_MODE 0xFC27
@ -55,7 +70,7 @@ namespace cypress {
class HCIDriver : public cordio::CordioHCIDriver {
public:
HCIDriver(
cordio::CordioHCITransportDriver& transport_driver,
ble::vendor::cypress_ble::CyH4TransportDriver& transport_driver,
PinName bt_power_name,
bool ps_enabled,
uint8_t host_wake_irq,
@ -70,7 +85,8 @@ public:
service_pack_ptr(0),
service_pack_length(0),
service_pack_next(),
service_pack_transfered(false) {
service_pack_transfered(false),
cy_transport_driver(transport_driver) {
}
virtual cordio::buf_pool_desc_t get_buffer_pool_description()
@ -81,6 +97,9 @@ public:
virtual void do_initialize()
{
//Prevent PSoC6 to enter deep-sleep till BT initialization is complete
sleep_manager_lock_deep_sleep();
rtos::ThisThread::sleep_for(500);
bt_power = 1;
rtos::ThisThread::sleep_for(500);
}
@ -113,6 +132,42 @@ public:
/* decode opcode */
switch (opcode) {
case HCI_VS_CMD_UPDATE_UART_BAUD_RATE:
#ifndef BT_UART_NO_3M_SUPPORT
cy_transport_driver.update_uart_baud_rate(DEF_BT_3M_BAUD_RATE);
#endif /* BT_UART_NO_3M_SUPPORT */
#ifdef CY_DEBUG
HciReadLocalVerInfoCmd();
#else
set_sleep_mode();
#endif
break;
#ifdef CY_DEBUG
case HCI_OPCODE_READ_LOCAL_VER_INFO:
uint8_t hci_version;
uint8_t hci_revision;
uint8_t lmp_revision;
uint16_t manufacturer_name;
BSTREAM_TO_UINT8(hci_version, pMsg);
BSTREAM_TO_UINT8(hci_revision, pMsg);
BSTREAM_TO_UINT8(lmp_revision, pMsg);
BSTREAM_TO_UINT16(manufacturer_name, pMsg);
if(hci_revision == 0 || manufacturer_name == 0xF)
{
printf("bt firmware download failed, rom code is being used\n");
}
else
{
printf("bt firmware download success\n");
}
set_sleep_mode();
break;
#endif
// Note: Reset is handled by ack_service_pack.
case HCI_VS_CMD_SET_SLEEP_MODE:
HciWriteLeHostSupport();
@ -263,20 +318,42 @@ public:
}
}
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
virtual void on_host_stack_inactivity(void)
{
cy_transport_driver.on_host_stack_inactivity();
}
#endif
private:
// send pre_brcm_patchram_buf
// send pre_brcm_patchram_buf issue hci reset and update baud rate on 43012
void prepare_service_pack_transfert(void)
{
service_pack_ptr = pre_brcm_patchram_buf;
service_pack_length = pre_brcm_patch_ram_length;
service_pack_next = &HCIDriver::prepare_service_pack_transfert2;
service_pack_index = 0;
service_pack_transfered = false;
send_service_pack_command();
}
// Called one pre_brcm_patchram_buf has been transferred; send pre_brcm_patchram_buf2 update uart baudrate
// on PSoC6 to send hci download minidriver
void prepare_service_pack_transfert2(void)
{
#ifndef BT_UART_NO_3M_SUPPORT
cy_transport_driver.update_uart_baud_rate(DEF_BT_3M_BAUD_RATE);
#endif /* BT_UART_NO_3M_SUPPORT */
service_pack_ptr = pre_brcm_patchram_buf2;
service_pack_length = pre_brcm_patch_ram_length2;
service_pack_next = &HCIDriver::start_service_pack_transfert;
service_pack_index = 0;
service_pack_transfered = false;
send_service_pack_command();
}
// Called once pre_brcm_patchram_buf has been transferred; send brcm_patchram_buf
// Called once pre_brcm_patchram_buf2 has been transferred; send brcm_patchram_buf
void start_service_pack_transfert(void)
{
service_pack_ptr = brcm_patchram_buf;
@ -290,6 +367,7 @@ private:
// Called once brcm_patchram_buf has been transferred; send post_brcm_patchram_buf
void post_service_pack_transfert(void)
{
cy_transport_driver.update_uart_baud_rate(DEF_BT_BAUD_RATE);
service_pack_ptr = post_brcm_patchram_buf;
service_pack_length = post_brcm_patch_ram_length;
service_pack_next = &HCIDriver::terminate_service_pack_transfert;;
@ -307,7 +385,12 @@ private:
service_pack_next = NULL;
service_pack_index = 0;
service_pack_transfered = true;
#ifndef BT_UART_NO_3M_SUPPORT
HciUpdateUartBaudRate();
#else /* BT_UART_NO_3M_SUPPORT */
set_sleep_mode();
#endif /* BT_UART_NO_3M_SUPPORT */
sleep_manager_unlock_deep_sleep();
}
void send_service_pack_command(void)
@ -354,7 +437,11 @@ private:
pBuf[HCI_CMD_HDR_LEN] = 0x00; // no sleep
}
pBuf[HCI_CMD_HDR_LEN + 1] = 0x00; // no idle threshold host (N/A)
if (is_powersave_on()) {
pBuf[HCI_CMD_HDR_LEN + 2] = 0x05; // no idle threshold HC (N/A)
} else {
pBuf[HCI_CMD_HDR_LEN + 2] = 0x00; // no idle threshold HC (N/A)
}
if (is_powersave_on()) {
pBuf[HCI_CMD_HDR_LEN + 3] = dev_wake_irq; // BT WAKE
} else {
@ -363,7 +450,7 @@ private:
if (is_powersave_on()) {
pBuf[HCI_CMD_HDR_LEN + 4] = host_wake_irq; // HOST WAKE
} else {
pBuf[HCI_CMD_HDR_LEN + 3] = 0x00; // BT WAKE
pBuf[HCI_CMD_HDR_LEN + 4] = 0x00; // HOST WAKE
}
pBuf[HCI_CMD_HDR_LEN + 5] = 0x00; // Sleep during SCO
pBuf[HCI_CMD_HDR_LEN + 6] = 0x00; // Combining sleep mode and SCM
@ -371,7 +458,23 @@ private:
pBuf[HCI_CMD_HDR_LEN + 8] = 0x00; // Active connection handling on suspend
pBuf[HCI_CMD_HDR_LEN + 9] = 0x00; // resume timeout
pBuf[HCI_CMD_HDR_LEN + 10] = 0x00; // break to host
pBuf[HCI_CMD_HDR_LEN + 10] = 0x00; // Pulsed host wake
pBuf[HCI_CMD_HDR_LEN + 11] = 0x00; // Pulsed host wake
hciCmdSend(pBuf);
}
}
// 0x18, 0xFC, 0x06, 0x00, 0x00, 0xC0, 0xC6, 0x2D, 0x00, //update uart baudrate 3 mbp
void HciUpdateUartBaudRate()
{
uint8_t *pBuf;
if ((pBuf = hciCmdAlloc(HCI_VS_CMD_UPDATE_UART_BAUD_RATE, 6)) != NULL)
{
pBuf[HCI_CMD_HDR_LEN] = 0x00; // encoded_baud_rate
pBuf[HCI_CMD_HDR_LEN + 1] = 0x00; // use_encoded_form
pBuf[HCI_CMD_HDR_LEN + 2] = 0xC0; // explicit baud rate bit 0-7
pBuf[HCI_CMD_HDR_LEN + 3] = 0xC6; // explicit baud rate bit 8-15
pBuf[HCI_CMD_HDR_LEN + 4] = 0x2D; // explicit baud rate bit 16-23
pBuf[HCI_CMD_HDR_LEN + 5] = 0x00; // explicit baud rate bit 24-31
hciCmdSend(pBuf);
}
}
@ -440,6 +543,7 @@ private:
int service_pack_length;
void (HCIDriver::*service_pack_next)();
bool service_pack_transfered;
ble::vendor::cypress_ble::CyH4TransportDriver& cy_transport_driver;
};