mirror of https://github.com/ARMmbed/mbed-os.git
CYW43XXX: Add generic transport layer
parent
8a19e3ecfc
commit
c0a8e41719
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue