Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CYW43XXX: Add generic transport layer #14227

Merged
merged 3 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
#include "CyH4TransportDriver.h"
#include "mbed_power_mgmt.h"
#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"
#include <chrono>
Expand All @@ -32,8 +36,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),
Expand All @@ -47,10 +55,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),
Expand Down Expand Up @@ -107,16 +118,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();
Expand All @@ -129,6 +155,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 };
Expand All @@ -137,6 +183,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;

Expand All @@ -160,6 +207,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
Expand All @@ -170,6 +218,7 @@ void CyH4TransportDriver::terminate()
CYHAL_ISR_PRIORITY_DEFAULT,
false
);
#endif

if(bt_host_wake.is_connected())
{
Expand All @@ -182,7 +231,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)
Expand All @@ -194,11 +247,25 @@ 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)
/* 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

deassert_bt_dev_wake();
sleep_manager_unlock_deep_sleep();
Expand Down Expand Up @@ -234,8 +301,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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand All @@ -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;
pennam marked this conversation as resolved.
Show resolved Hide resolved
#else
cyhal_uart_t uart;
PinName cts;
PinName rts;
PinName tx;
PinName rx;
#endif
PinName cts;
PinName rts;
PinName bt_host_wake_name;
PinName bt_device_wake_name;

Expand Down