Skip to content

Commit 6ebf1b8

Browse files
committed
drivers/sx127x: Add RX Timeout support
This commit adds support to fix RX timeout for SX127x, it is done leaving the RX mode, entering in stanby mode and returning to RX mode. It is enough to fix the AFC and get communication working again. Signed-off-by: Alan C. Assis <acassis@gmail.com>
1 parent 9ad3ef6 commit 6ebf1b8

2 files changed

Lines changed: 77 additions & 1 deletion

File tree

drivers/wireless/lpwan/sx127x/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ config LPWAN_SX127X_RXFIFO_DATA_LEN
5050
int "SX127X RX FIFO data length"
5151
default 64
5252

53+
config LPWAN_SX127X_RX_TIMEOUT
54+
int "SX127X RX Timeout in Milliseconds"
55+
default 10000
56+
---help---
57+
If device stopped receiving data for more than
58+
LPWAN_SX127X_RX_TIMEOUT milliseconds it means the
59+
frequency drift is too high that AFC failed to fix
60+
the reception frequency. So if we leave the RX mode,
61+
entering in standby and returning will clear the
62+
AFC and fix the communication again.
63+
If you don't want to use RX timeout set it to -1.
64+
5365
endif #LPWAN_SX127X_RXSUPPORT
5466

5567
config LPWAN_SX127X_TXSUPPORT

drivers/wireless/lpwan/sx127x/sx127x.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)