CYW43XXX: Add generic transport layer

pull/14227/head
Martino Facchin 2020-10-28 14:51:48 +01:00 committed by pennam
parent 8a19e3ecfc
commit c0a8e41719
2 changed files with 83 additions and 7 deletions

View File

@ -20,7 +20,9 @@
#include "CyH4TransportDriver.h" #include "CyH4TransportDriver.h"
#include "mbed_power_mgmt.h" #include "mbed_power_mgmt.h"
#include "drivers/InterruptIn.h" #include "drivers/InterruptIn.h"
#if !defined(CYW43XXX_UNBUFFERED_UART)
#include "cybsp_types.h" #include "cybsp_types.h"
#endif
#include "Callback.h" #include "Callback.h"
#include "rtos/ThisThread.h" #include "rtos/ThisThread.h"
#include <chrono> #include <chrono>
@ -32,8 +34,12 @@ namespace cypress_ble {
using namespace std::chrono_literals; 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) : 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), tx(tx), rx(rx),
#endif
cts(cts), rts(rts),
bt_host_wake_name(bt_host_wake_name), bt_host_wake_name(bt_host_wake_name),
bt_device_wake_name(bt_device_wake_name), bt_device_wake_name(bt_device_wake_name),
bt_power(bt_power_name, PIN_OUTPUT, PullNone, 0), 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; bt_host_wake_active = false;
} }
CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, PinName bt_power_name, int baud) : CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, PinName bt_power_name, int baud) :
cts(cts), #if defined(CYW43XXX_UNBUFFERED_UART)
rts(rts), uart(tx, rx),
#else
tx(tx), rx(rx), tx(tx), rx(rx),
#endif
cts(cts), rts(rts),
bt_host_wake_name(NC), bt_host_wake_name(NC),
bt_device_wake_name(NC), bt_device_wake_name(NC),
bt_power(bt_power_name, PIN_OUTPUT, PullNone, 0), 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) static void on_controller_irq(void *callback_arg, cyhal_uart_event_t event)
#endif
{ {
#if !defined(CYW43XXX_UNBUFFERED_UART)
(void)(event); (void)(event);
cyhal_uart_t *uart_obj = (cyhal_uart_t *)callback_arg; cyhal_uart_t *uart_obj = (cyhal_uart_t *)callback_arg;
#endif
sleep_manager_lock_deep_sleep(); 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)) { while (cyhal_uart_readable(uart_obj)) {
uint8_t char_received; uint8_t char_received;
cyhal_uart_getc(uart_obj, &char_received, 0); cyhal_uart_getc(uart_obj, &char_received, 0);
CyH4TransportDriver::on_data_received(&char_received, 1); CyH4TransportDriver::on_data_received(&char_received, 1);
#endif
} }
sleep_manager_unlock_deep_sleep(); sleep_manager_unlock_deep_sleep();
@ -129,6 +153,26 @@ void CyH4TransportDriver::initialize()
bt_power = 0; bt_power = 0;
rtos::ThisThread::sleep_for(1ms); 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); 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 }; 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_clear(&uart);
cyhal_uart_register_callback(&uart, &on_controller_irq, &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); cyhal_uart_enable_event(&uart, CYHAL_UART_IRQ_RX_NOT_EMPTY, CYHAL_ISR_PRIORITY_DEFAULT, true);
#endif
bt_power = 1; bt_power = 1;
@ -160,6 +205,7 @@ void CyH4TransportDriver::initialize()
void CyH4TransportDriver::terminate() 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_event_t enable_irq_event = (cyhal_uart_event_t)(CYHAL_UART_IRQ_RX_DONE
| CYHAL_UART_IRQ_TX_DONE | CYHAL_UART_IRQ_TX_DONE
| CYHAL_UART_IRQ_RX_NOT_EMPTY | CYHAL_UART_IRQ_RX_NOT_EMPTY
@ -170,6 +216,7 @@ void CyH4TransportDriver::terminate()
CYHAL_ISR_PRIORITY_DEFAULT, CYHAL_ISR_PRIORITY_DEFAULT,
false false
); );
#endif
if(bt_host_wake.is_connected()) 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 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); cyhal_uart_free(&uart);
#endif
} }
uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData) 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) { while (i < len + 1) {
uint8_t to_write = i == 0 ? type : pData[i - 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); while (cyhal_uart_writable(&uart) == 0);
cyhal_uart_putc(&uart, to_write); cyhal_uart_putc(&uart, to_write);
#endif
++i; ++i;
} }
#if defined(CYW43XXX_UNBUFFERED_UART)
while (uart.writeable() == 0);
#else
while(cyhal_uart_is_tx_active(&uart)); while(cyhal_uart_is_tx_active(&uart));
#endif
deassert_bt_dev_wake(); deassert_bt_dev_wake();
sleep_manager_unlock_deep_sleep(); sleep_manager_unlock_deep_sleep();
@ -234,8 +294,12 @@ void CyH4TransportDriver::deassert_bt_dev_wake()
void CyH4TransportDriver::update_uart_baud_rate(int baud) void CyH4TransportDriver::update_uart_baud_rate(int baud)
{ {
#if defined(CYW43XXX_UNBUFFERED_UART)
uart.baud((uint32_t)baud);
#else
uint32_t ignore; uint32_t ignore;
cyhal_uart_set_baud(&uart, (uint32_t)baud, &ignore); cyhal_uart_set_baud(&uart, (uint32_t)baud, &ignore);
#endif
} }
bool CyH4TransportDriver::get_enabled_powersave() bool CyH4TransportDriver::get_enabled_powersave()

View File

@ -24,7 +24,12 @@
#include "ble/driver/CordioHCITransportDriver.h" #include "ble/driver/CordioHCITransportDriver.h"
#include "drivers/DigitalInOut.h" #include "drivers/DigitalInOut.h"
#include "drivers/InterruptIn.h" #include "drivers/InterruptIn.h"
#if defined(CYW43XXX_UNBUFFERED_UART)
#include "drivers/UnbufferedSerial.h"
#else
#include "cyhal_uart.h" #include "cyhal_uart.h"
#endif
namespace ble { namespace ble {
namespace vendor { namespace vendor {
@ -82,6 +87,10 @@ private:
void assert_bt_dev_wake(); void assert_bt_dev_wake();
void deassert_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. // Use HAL serial because Cypress UART is buffered.
// The PUTC function does not actually blocks until data is fully transmitted, // The PUTC function does not actually blocks until data is fully transmitted,
// it only blocks until data gets into HW buffer. // it only blocks until data gets into HW buffer.
@ -89,12 +98,15 @@ private:
// However UART APIs does not prevent the BT radio from going to sleep. // 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. // 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. // 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; cyhal_uart_t uart;
PinName cts; #endif
PinName rts;
PinName tx; PinName tx;
PinName rx; PinName rx;
PinName cts;
PinName rts;
PinName bt_host_wake_name; PinName bt_host_wake_name;
PinName bt_device_wake_name; PinName bt_device_wake_name;