@@ -316,10 +316,12 @@ struct sx127x_dev_s
316316 bool pa_force ; /* Force PA BOOST pin select */
317317#endif
318318#ifdef CONFIG_LPWAN_SX127X_RXSUPPORT
319- uint32_t rx_timeout ; /* RX timeout (not supported) */
319+ uint32_t rx_timeout ; /* RX timeout in milliseconds */
320320 uint16_t rx_fifo_len ; /* Number of bytes stored in fifo */
321321 uint16_t nxt_read ; /* Next read index */
322322 uint16_t nxt_write ; /* Next write index */
323+ clock_t last_rx_tick ; /* Ticks since last RX event to detect timeout */
324+ struct work_s rx_watchdog ; /* Watchdog to detect timeout */
323325
324326 /* Circular RX packet buffer */
325327
@@ -1276,6 +1278,50 @@ static int sx127x_poll(FAR struct file *filep, FAR struct pollfd *fds,
12761278#endif
12771279}
12781280
1281+ /****************************************************************************
1282+ * Name: sx127x_rx_watchdog
1283+ *
1284+ * Description:
1285+ * Watchdog to detect SX127x RX communication stall
1286+ *
1287+ ****************************************************************************/
1288+
1289+ #ifdef CONFIG_LPWAN_SX127X_RXSUPPORT
1290+ static void sx127x_rx_watchdog (FAR void * arg )
1291+ {
1292+ FAR struct sx127x_dev_s * dev = (FAR struct sx127x_dev_s * ) arg ;
1293+ clock_t now = clock_systime_ticks ();
1294+
1295+ if (dev -> opmode == SX127X_OPMODE_RX &&
1296+ (now - dev -> last_rx_tick ) > MSEC2TICK (dev -> rx_timeout ))
1297+ {
1298+ wlerr ("RX stall detected, restarting RX\n" );
1299+
1300+ /* Leave RX mode to clear AFC + bit sync */
1301+
1302+ sx127x_opmode_set (dev , SX127X_OPMODE_STANDBY );
1303+
1304+ /* datasheet-safe delay */
1305+
1306+ up_udelay (100 );
1307+
1308+ /* Re-enter RX */
1309+
1310+ sx127x_opmode_set (dev , SX127X_OPMODE_RX );
1311+
1312+ /* Avoid using old RX tick, otherwise it always will fail */
1313+
1314+ dev -> last_rx_tick = now ;
1315+ }
1316+
1317+ /* Reschedule watchdog */
1318+
1319+ work_queue (LPWORK , & dev -> rx_watchdog ,
1320+ sx127x_rx_watchdog , dev ,
1321+ MSEC2TICK (dev -> rx_timeout ));
1322+ }
1323+ #endif
1324+
12791325/****************************************************************************
12801326 * Name: sx127x_lora_isr0_process
12811327 *
@@ -1471,6 +1517,21 @@ static int sx127x_fskook_isr0_process(FAR struct sx127x_dev_s *dev)
14711517 ret = sx127x_fskook_rxhandle (dev );
14721518 if (ret > 0 )
14731519 {
1520+ /* Should we take care of RX timeout? */
1521+
1522+ if (dev -> rx_timeout > 0 )
1523+ {
1524+ /* Keep a track of last RX time to detect timeout */
1525+
1526+ dev -> last_rx_tick = clock_systime_ticks ();
1527+
1528+ /* Prepare the work queue to take care of RX timeout */
1529+
1530+ work_queue (LPWORK , & dev -> rx_watchdog ,
1531+ sx127x_rx_watchdog , dev ,
1532+ MSEC2TICK (dev -> rx_timeout ));
1533+ }
1534+
14741535 if (dev -> pfd )
14751536 {
14761537 /* Data available for input */
@@ -4614,6 +4675,9 @@ int sx127x_register(FAR struct spi_dev_s *spi,
46144675 dev -> crcon = CONFIG_LPWAN_SX127X_CRCON ;
46154676#ifdef CONFIG_LPWAN_SX127X_FSKOOK
46164677 dev -> fskook .fixlen = false;
4678+ # ifdef CONFIG_LPWAN_SX127X_TXSUPPORT
4679+ dev -> rx_timeout = CONFIG_LPWAN_SX127X_RX_TIMEOUT ;
4680+ # endif
46174681#endif
46184682#ifdef CONFIG_LPWAN_SX127X_LORA
46194683 dev -> lora .invert_iq = false;
0 commit comments