From a150fb6bb76d3813f8b58e377636da749be7d811 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Mon, 6 Apr 2020 14:25:59 +0200 Subject: [PATCH] drivers: lora: sx1276: call DIO handlers in workqueue DIO handlers defined in loramac-node are quite complex. Additionally they call read/write operations over SPI with the sx1276 chip. This cannot work properly in interrupt context, so call DIO handlers in system workqueue instead. Signed-off-by: Marcin Niestroj --- drivers/lora/sx1276.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/lora/sx1276.c b/drivers/lora/sx1276.c index 2b1b8b53fff..9498ca91772 100644 --- a/drivers/lora/sx1276.c +++ b/drivers/lora/sx1276.c @@ -55,6 +55,7 @@ struct sx1276_data { struct device *spi; struct spi_config spi_cfg; struct device *dio_dev[SX1276_MAX_DIO]; + struct k_work dio_work[SX1276_MAX_DIO]; struct k_sem data_sem; RadioEvents_t sx1276_event; u8_t *rx_buf; @@ -156,6 +157,13 @@ void DelayMsMcu(uint32_t ms) k_sleep(ms); } +static void sx1276_dio_work_handle(struct k_work *work) +{ + int dio = work - dev_data.dio_work; + + (*DioIrq[dio])(NULL); +} + static void sx1276_irq_callback(struct device *dev, struct gpio_callback *cb, u32_t pins) { @@ -166,7 +174,7 @@ static void sx1276_irq_callback(struct device *dev, for (i = 0; i < SX1276_MAX_DIO; i++) { if (dev == dev_data.dio_dev[i] && pin == sx1276_dios[i].pin) { - (*DioIrq[i])(NULL); + k_work_submit(&dev_data.dio_work[i]); } } } @@ -189,6 +197,8 @@ void SX1276IoIrqInit(DioIrqHandler **irqHandlers) return; } + k_work_init(&dev_data.dio_work[i], sx1276_dio_work_handle); + gpio_pin_configure(dev_data.dio_dev[i], sx1276_dios[i].pin, GPIO_INPUT | GPIO_INT_DEBOUNCE | sx1276_dios[i].flags);