Skip to content

Commit b8045fb

Browse files
authored
Merge pull request #12164 from shuopeng-deng/pr-dev/remove-hardcoded-timeout-in-cypress-bt-code
Pr dev/remove hardcoded timeout in cypress bt code
2 parents adcd006 + 1d54f66 commit b8045fb

File tree

3 files changed

+38
-44
lines changed

3 files changed

+38
-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: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,18 @@ 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+
// Mbed layer has no API that distinguish between data in HW buffer v.s. data already transmitted.
91+
92+
cyhal_uart_t uart;
9093
PinName cts;
9194
PinName rts;
9295
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)