From c0a8e41719a1384dd2a0b31975ffcb41b5d4b39b Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 28 Oct 2020 14:51:48 +0100 Subject: [PATCH 1/3] CYW43XXX: Add generic transport layer --- .../CyH4TransportDriver.cpp | 72 +++++++++++++++++-- .../COMPONENT_CYW43XXX/CyH4TransportDriver.h | 18 ++++- 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp b/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp index 8b9639dac89..f46cc0c125c 100644 --- a/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp +++ b/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp @@ -20,7 +20,9 @@ #include "CyH4TransportDriver.h" #include "mbed_power_mgmt.h" #include "drivers/InterruptIn.h" +#if !defined(CYW43XXX_UNBUFFERED_UART) #include "cybsp_types.h" +#endif #include "Callback.h" #include "rtos/ThisThread.h" #include @@ -32,8 +34,12 @@ namespace cypress_ble { using namespace std::chrono_literals; CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, PinName bt_power_name, int baud, PinName bt_host_wake_name, PinName bt_device_wake_name, uint8_t host_wake_irq, uint8_t dev_wake_irq) : - cts(cts), rts(rts), +#if defined(CYW43XXX_UNBUFFERED_UART) + uart(tx, rx), +#else tx(tx), rx(rx), +#endif + cts(cts), rts(rts), bt_host_wake_name(bt_host_wake_name), bt_device_wake_name(bt_device_wake_name), bt_power(bt_power_name, PIN_OUTPUT, PullNone, 0), @@ -47,10 +53,13 @@ CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, Pi bt_host_wake_active = false; } -CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, PinName bt_power_name, int baud) : - cts(cts), - rts(rts), +CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, PinName bt_power_name, int baud) : +#if defined(CYW43XXX_UNBUFFERED_UART) + uart(tx, rx), +#else tx(tx), rx(rx), +#endif + cts(cts), rts(rts), bt_host_wake_name(NC), bt_device_wake_name(NC), bt_power(bt_power_name, PIN_OUTPUT, PullNone, 0), @@ -107,16 +116,31 @@ void CyH4TransportDriver::bt_host_wake_fall_irq_handler(void) } } +#if defined(CYW43XXX_UNBUFFERED_UART) +void CyH4TransportDriver::on_controller_irq() +#else static void on_controller_irq(void *callback_arg, cyhal_uart_event_t event) +#endif { +#if !defined(CYW43XXX_UNBUFFERED_UART) (void)(event); cyhal_uart_t *uart_obj = (cyhal_uart_t *)callback_arg; +#endif + sleep_manager_lock_deep_sleep(); +#if defined(CYW43XXX_UNBUFFERED_UART) + while (uart.readable()) { + uint8_t char_received; + if (uart.read(&char_received, 1)) { + CordioHCITransportDriver::on_data_received(&char_received, 1); + } +#else while (cyhal_uart_readable(uart_obj)) { uint8_t char_received; cyhal_uart_getc(uart_obj, &char_received, 0); CyH4TransportDriver::on_data_received(&char_received, 1); +#endif } sleep_manager_unlock_deep_sleep(); @@ -129,6 +153,26 @@ void CyH4TransportDriver::initialize() bt_power = 0; rtos::ThisThread::sleep_for(1ms); +#if defined(CYW43XXX_UNBUFFERED_UART) + uart.baud(DEF_BT_BAUD_RATE); + + uart.format( + /* bits */ 8, + /* parity */ mbed::SerialBase::None, + /* stop bit */ 1 + ); + + uart.set_flow_control( + /* flow */ mbed::SerialBase::RTSCTS, + /* rts */ rts, + /* cts */ cts + ); + + uart.attach( + mbed::callback(this, &CyH4TransportDriver::on_controller_irq), + mbed::SerialBase::RxIrq + ); +#else cyhal_uart_init(&uart, tx, rx, NULL, NULL); const cyhal_uart_cfg_t uart_cfg = { .data_bits = 8, .stop_bits = 1, .parity = CYHAL_UART_PARITY_NONE, .rx_buffer = NULL, .rx_buffer_size = 0 }; @@ -137,6 +181,7 @@ void CyH4TransportDriver::initialize() cyhal_uart_clear(&uart); cyhal_uart_register_callback(&uart, &on_controller_irq, &uart); cyhal_uart_enable_event(&uart, CYHAL_UART_IRQ_RX_NOT_EMPTY, CYHAL_ISR_PRIORITY_DEFAULT, true); +#endif bt_power = 1; @@ -160,6 +205,7 @@ void CyH4TransportDriver::initialize() void CyH4TransportDriver::terminate() { +#if !defined(CYW43XXX_UNBUFFERED_UART) cyhal_uart_event_t enable_irq_event = (cyhal_uart_event_t)(CYHAL_UART_IRQ_RX_DONE | CYHAL_UART_IRQ_TX_DONE | CYHAL_UART_IRQ_RX_NOT_EMPTY @@ -170,6 +216,7 @@ void CyH4TransportDriver::terminate() CYHAL_ISR_PRIORITY_DEFAULT, false ); +#endif if(bt_host_wake.is_connected()) { @@ -182,7 +229,11 @@ void CyH4TransportDriver::terminate() bt_power = 0; //BT_POWER is an output, should not be freed only set inactive +#if defined(CYW43XXX_UNBUFFERED_UART) + uart.close(); +#else cyhal_uart_free(&uart); +#endif } uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData) @@ -194,11 +245,20 @@ uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData) while (i < len + 1) { uint8_t to_write = i == 0 ? type : pData[i - 1]; +#if defined(CYW43XXX_UNBUFFERED_UART) + while (uart.writeable() == 0); + uart.write(&to_write, 1); +#else while (cyhal_uart_writable(&uart) == 0); cyhal_uart_putc(&uart, to_write); +#endif ++i; } +#if defined(CYW43XXX_UNBUFFERED_UART) + while (uart.writeable() == 0); +#else while(cyhal_uart_is_tx_active(&uart)); +#endif deassert_bt_dev_wake(); sleep_manager_unlock_deep_sleep(); @@ -234,8 +294,12 @@ void CyH4TransportDriver::deassert_bt_dev_wake() void CyH4TransportDriver::update_uart_baud_rate(int baud) { +#if defined(CYW43XXX_UNBUFFERED_UART) + uart.baud((uint32_t)baud); +#else uint32_t ignore; cyhal_uart_set_baud(&uart, (uint32_t)baud, &ignore); +#endif } bool CyH4TransportDriver::get_enabled_powersave() diff --git a/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h b/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h index bac796b2eff..23968241882 100644 --- a/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h +++ b/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h @@ -24,7 +24,12 @@ #include "ble/driver/CordioHCITransportDriver.h" #include "drivers/DigitalInOut.h" #include "drivers/InterruptIn.h" + +#if defined(CYW43XXX_UNBUFFERED_UART) +#include "drivers/UnbufferedSerial.h" +#else #include "cyhal_uart.h" +#endif namespace ble { namespace vendor { @@ -81,6 +86,10 @@ class CyH4TransportDriver : public CordioHCITransportDriver { private: void assert_bt_dev_wake(); void deassert_bt_dev_wake(); + +#if defined(CYW43XXX_UNBUFFERED_UART) + void on_controller_irq(); +#endif // Use HAL serial because Cypress UART is buffered. // The PUTC function does not actually blocks until data is fully transmitted, @@ -89,12 +98,15 @@ class CyH4TransportDriver : public CordioHCITransportDriver { // However UART APIs does not prevent the BT radio from going to sleep. // Use the HAL APIs to prevent the radio from going to sleep until UART transmition is complete. // Mbed layer has no API that distinguish between data in HW buffer v.s. data already transmitted. - +#if defined(CYW43XXX_UNBUFFERED_UART) + mbed::UnbufferedSerial uart; +#else cyhal_uart_t uart; - PinName cts; - PinName rts; +#endif PinName tx; PinName rx; + PinName cts; + PinName rts; PinName bt_host_wake_name; PinName bt_device_wake_name; From c1d33d23aead7752d333fccc0f12f8d803cc4c94 Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 8 Feb 2021 11:14:51 +0100 Subject: [PATCH 2/3] exclude tx and rx if CYW43XXX_UNBUFFERED_UART is defined --- .../ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h b/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h index 23968241882..8babd0abec4 100644 --- a/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h +++ b/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.h @@ -102,9 +102,9 @@ class CyH4TransportDriver : public CordioHCITransportDriver { mbed::UnbufferedSerial uart; #else cyhal_uart_t uart; -#endif PinName tx; PinName rx; +#endif PinName cts; PinName rts; PinName bt_host_wake_name; From dc4fb8d74b6f5afb8af1b30dd9b9e3f7dff382b8 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 11 May 2021 16:27:08 +0200 Subject: [PATCH 3/3] Use fixed wait time --- .../COMPONENT_CYW43XXX/CyH4TransportDriver.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp b/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp index f46cc0c125c..148872aa6d3 100644 --- a/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp +++ b/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp @@ -22,6 +22,8 @@ #include "drivers/InterruptIn.h" #if !defined(CYW43XXX_UNBUFFERED_UART) #include "cybsp_types.h" +#else +#include "mbed_wait_api.h" #endif #include "Callback.h" #include "rtos/ThisThread.h" @@ -255,7 +257,12 @@ uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData) ++i; } #if defined(CYW43XXX_UNBUFFERED_UART) - while (uart.writeable() == 0); +/* Assuming a 16 byte FIFO as worst case this will ensure all bytes are sent before deasserting bt_dev_wake */ +#ifndef BT_UART_NO_3M_SUPPORT + wait_us(50); // 3000000 bps +#else + rtos::ThisThread::sleep_for(2ms); // 115200 bps +#endif #else while(cyhal_uart_is_tx_active(&uart)); #endif