Skip to content

Commit 5ee993f

Browse files
committed
drv/bluetooth/stm32_cc2640: work around SRDY timing issue
This fixes an issue where Bluetooth would hang forever waiting for the SRDY signal to transition. See comments in code for details. Issue: pybricks/support#306
1 parent 11f19bc commit 5ee993f

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1237,8 +1237,22 @@ PROCESS_THREAD(pbdrv_bluetooth_spi_process, ev, data) {
12371237
&read_buf[NPI_SPI_HEADER_LEN], xfer_size);
12381238
PROCESS_WAIT_UNTIL(spi_xfer_complete);
12391239

1240+
// HACK: SRDY can transition from low and back to high in the time
1241+
// between we set MRDY and when we read SRDY again. So we use a timer
1242+
// prevent a lockup in case we miss detecting the transitions.
1243+
1244+
// See Δt6 + Δt7 in the timing diagram at:
1245+
// https://dev.ti.com/tirex/explore/content/simplelink_cc13x2_26x2_sdk_3_10_00_53/docs/ble5stack/ble_user_guide/html/ble-stack-common/npi-index.html#npi-handshake
1246+
1247+
// This document suggests that this timing varies from 0.181ms to 1.2 ms.
1248+
// http://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/538/3583.BLE-SPI-Driver-Design-External.pdf
1249+
1250+
// REVISIT: maybe there is a way to get individual oneshots for the
1251+
// rising and falling edges of the interrupt instead of the timer hack?
1252+
1253+
etimer_set(&timer, clock_from_msec(2));
12401254
spi_set_mrdy(false);
1241-
PROCESS_WAIT_UNTIL(!spi_srdy);
1255+
PROCESS_WAIT_UNTIL(!spi_srdy || (ev == PROCESS_EVENT_TIMER && etimer_expired(&timer)));
12421256

12431257
// set to 0 to indicate that xfer is complete
12441258
write_xfer_size = 0;

0 commit comments

Comments
 (0)