Skip to content

Commit 7e79623

Browse files
committed
Removed a hardcoded timeout in CyH4TransportDriver.cpp
Replaced a hardcoded timeout in CyH4TransportDriver.cpp with a cypress hal function. The cypress PUTC hal API only blocks until data has been send into the HW buffer, not until all data has been out of the HW buffer. Modified an API to block untill all tx transmit is complete. This allows the removal of a hardcoded timeout in CyH4TransportDriver.cpp that waits for data int the HW buffer to be sent.
1 parent d128ff4 commit 7e79623

File tree

3 files changed

+37
-44
lines changed

3 files changed

+37
-44
lines changed

features/FEATURE_BLE/targets/TARGET_Cypress/COMPONENT_CYW43XXX/CyH4TransportDriver.cpp

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,28 @@ namespace cypress_ble {
2525

2626

2727
CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud, PinName bt_host_wake_name, PinName bt_device_wake_name, uint8_t host_wake_irq, uint8_t dev_wake_irq) :
28-
uart(tx, rx, baud), cts(cts), rts(rts),
28+
cts(cts), rts(rts),
2929
bt_host_wake_name(bt_host_wake_name),
3030
bt_device_wake_name(bt_device_wake_name),
3131
bt_host_wake(bt_host_wake_name, PIN_INPUT, PullNone, 0),
3232
bt_device_wake(bt_device_wake_name, PIN_OUTPUT, PullNone, 1),
3333
host_wake_irq_event(host_wake_irq),
3434
dev_wake_irq_event(dev_wake_irq)
3535
{
36+
cyhal_uart_init(&uart, tx, rx, NULL, NULL);
3637
enabled_powersave = true;
3738
bt_host_wake_active = false;
3839
}
3940

4041
CyH4TransportDriver::CyH4TransportDriver(PinName tx, PinName rx, PinName cts, PinName rts, int baud) :
41-
uart(tx, rx, baud),
4242
cts(cts),
4343
rts(rts),
4444
bt_host_wake_name(NC),
4545
bt_device_wake_name(NC),
4646
bt_host_wake(bt_host_wake_name),
4747
bt_device_wake(bt_device_wake_name)
4848
{
49+
cyhal_uart_init(&uart, tx, rx, NULL, NULL);
4950
enabled_powersave = false;
5051
bt_host_wake_active = false;
5152
sleep_manager_lock_deep_sleep();
@@ -93,6 +94,21 @@ void CyH4TransportDriver::bt_host_wake_fall_irq_handler(void)
9394
}
9495
}
9596

97+
static void on_controller_irq(void *callback_arg, cyhal_uart_event_t event)
98+
{
99+
(void)(event);
100+
cyhal_uart_t *uart_obj = (cyhal_uart_t *)callback_arg;
101+
sleep_manager_lock_deep_sleep();
102+
103+
while (cyhal_uart_readable(uart_obj)) {
104+
uint8_t char_received;
105+
cyhal_uart_getc(uart_obj, &char_received, 0);
106+
CyH4TransportDriver::on_data_received(&char_received, 1);
107+
}
108+
109+
sleep_manager_unlock_deep_sleep();
110+
}
111+
96112
void CyH4TransportDriver::initialize()
97113
{
98114
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
@@ -101,24 +117,11 @@ void CyH4TransportDriver::initialize()
101117

102118
sleep_manager_lock_deep_sleep();
103119

104-
uart.format(
105-
/* bits */ 8,
106-
/* parity */ SerialBase::None,
107-
/* stop bit */ 1
108-
);
109-
110-
uart.set_flow_control(
111-
/* flow */ SerialBase::RTSCTS,
112-
/* rts */ rts,
113-
/* cts */ cts
114-
);
115-
116-
uart.attach(
117-
callback(this, &CyH4TransportDriver::on_controller_irq),
118-
SerialBase::RxIrq
119-
);
120-
121-
sleep_manager_unlock_deep_sleep();
120+
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 };
121+
cyhal_uart_configure(&uart, &uart_cfg);
122+
cyhal_uart_set_flow_control(&uart, cts, rts);
123+
cyhal_uart_register_callback(&uart, &on_controller_irq, &uart);
124+
cyhal_uart_enable_event(&uart, CYHAL_UART_IRQ_RX_NOT_EMPTY, CYHAL_ISR_PRIORITY_DEFAULT, true);
122125

123126
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
124127
if (bt_host_wake_name != NC) {
@@ -150,28 +153,17 @@ uint16_t CyH4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
150153

151154
while (i < len + 1) {
152155
uint8_t to_write = i == 0 ? type : pData[i - 1];
153-
while (uart.writeable() == 0);
154-
uart.putc(to_write);
156+
while (cyhal_uart_writable(&uart) == 0);
157+
cyhal_uart_putc(&uart, to_write);
155158
++i;
156159
}
160+
while(cyhal_uart_is_tx_active(&uart));
157161

158162
deassert_bt_dev_wake();
159163
sleep_manager_unlock_deep_sleep();
160164
return len;
161165
}
162166

163-
void CyH4TransportDriver::on_controller_irq()
164-
{
165-
sleep_manager_lock_deep_sleep();
166-
167-
while (uart.readable()) {
168-
uint8_t char_received = uart.getc();
169-
on_data_received(&char_received, 1);
170-
}
171-
172-
sleep_manager_unlock_deep_sleep();
173-
}
174-
175167
void CyH4TransportDriver::assert_bt_dev_wake()
176168
{
177169
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
@@ -189,8 +181,6 @@ void CyH4TransportDriver::deassert_bt_dev_wake()
189181
{
190182
#if (defined(MBED_TICKLESS) && DEVICE_SLEEP && DEVICE_LPTICKER)
191183
if (enabled_powersave) {
192-
wait_us(5000); /* remove and replace when uart tx transmit complete api is available */
193-
//De-assert bt_device_wake
194184
if (dev_wake_irq_event == WAKE_EVENT_ACTIVE_LOW) {
195185
bt_device_wake = WAKE_EVENT_ACTIVE_HIGH;
196186
} else {
@@ -203,7 +193,8 @@ void CyH4TransportDriver::deassert_bt_dev_wake()
203193

204194
void CyH4TransportDriver::update_uart_baud_rate(int baud)
205195
{
206-
uart.baud(baud);
196+
uint32_t ignore;
197+
cyhal_uart_set_baud(&uart, (uint32_t)baud, &ignore);
207198
}
208199

209200
bool CyH4TransportDriver::get_enabled_powersave()

features/FEATURE_BLE/targets/TARGET_Cypress/COMPONENT_CYW43XXX/CyH4TransportDriver.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,17 @@ class CyH4TransportDriver : public cordio::CordioHCITransportDriver {
7878
uint8_t get_dev_wake_irq_event();
7979

8080
private:
81-
void on_controller_irq();
8281
void assert_bt_dev_wake();
8382
void deassert_bt_dev_wake();
8483

85-
// Use RawSerial as opposed to Serial as we don't require the locking primitives
86-
// provided by the Serial class (access to the UART should be exclusive to this driver)
87-
// Furthermore, we access the peripheral in interrupt context which would clash
88-
// with Serial's locking facilities
89-
RawSerial uart;
84+
// Use HAL serial because Cypress UART is buffered.
85+
// The PUTC function does not actually blocks until data is fully transmitted,
86+
// it only blocks until data gets into HW buffer.
87+
// The UART APIs prevents sleep while there are data in the HW buffer.
88+
// However UART APIs does not prevent the BT radio from going to sleep.
89+
// Use the HAL APIs to prevent the radio from going to sleep until UART transmition is complete.
90+
91+
cyhal_uart_t uart;
9092
PinName cts;
9193
PinName rts;
9294
PinName bt_host_wake_name;

targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/src/cyhal_uart.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ cy_rslt_t cyhal_uart_read_async(cyhal_uart_t *obj, void *rx, size_t length)
634634

635635
bool cyhal_uart_is_tx_active(cyhal_uart_t *obj)
636636
{
637-
return (0UL != (obj->context.txStatus & CY_SCB_UART_TRANSMIT_ACTIVE));
637+
return (0UL != (obj->context.txStatus & CY_SCB_UART_TRANSMIT_ACTIVE)) || !Cy_SCB_IsTxComplete(obj->base);
638638
}
639639

640640
bool cyhal_uart_is_rx_active(cyhal_uart_t *obj)

0 commit comments

Comments
 (0)