Commit 4b370fb5 authored by Jordan Yates's avatar Jordan Yates Committed by Christopher Friedt
Browse files

lora: sx12xx_common: transition to k_poll_signal


Transition the receive synchronisation method from a single driver
semaphore to a function specific k_poll_signal. This is required to
allow the modem to be released without introducing race conditions on
the signalling mechanism.

Without this change, the RX can either be signalled before the modem is
released, unblocking the calling thread before the modem is put back to
sleep, or after the modem is released, in which case a second thread
could start using the semaphore before the original thread is signalled.
Signed-off-by: default avatarJordan Yates <jordan.yates@data61.csiro.au>
parent f397361c
......@@ -9,6 +9,7 @@
menuconfig LORA
bool "LoRa support [EXPERIMENTAL]"
select REQUIRES_FULL_LIBC
select POLL
help
Include LoRa drivers in the system configuration.
......
......@@ -18,7 +18,7 @@
LOG_MODULE_REGISTER(sx12xx_common, CONFIG_LORA_LOG_LEVEL);
static struct sx12xx_data {
struct k_sem data_sem;
struct k_poll_signal *operation_done;
RadioEvents_t events;
uint8_t *rx_buf;
uint8_t rx_len;
......@@ -26,7 +26,7 @@ static struct sx12xx_data {
int16_t rssi;
} dev_data;
int __sx12xx_configure_pin(const struct device * *dev, const char *controller,
int __sx12xx_configure_pin(const struct device **dev, const char *controller,
gpio_pin_t pin, gpio_flags_t flags)
{
int err;
......@@ -57,7 +57,9 @@ static void sx12xx_ev_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
dev_data.rssi = rssi;
dev_data.snr = snr;
k_sem_give(&dev_data.data_sem);
if (dev_data.operation_done) {
k_poll_signal_raise(dev_data.operation_done, 0);
}
}
static void sx12xx_ev_tx_done(void)
......@@ -78,15 +80,24 @@ int sx12xx_lora_send(const struct device *dev, uint8_t *data,
int sx12xx_lora_recv(const struct device *dev, uint8_t *data, uint8_t size,
k_timeout_t timeout, int16_t *rssi, int8_t *snr)
{
struct k_poll_signal done = K_POLL_SIGNAL_INITIALIZER(done);
struct k_poll_event evt = K_POLL_EVENT_INITIALIZER(
K_POLL_TYPE_SIGNAL,
K_POLL_MODE_NOTIFY_ONLY,
&done);
int ret;
/* Store operation signal */
dev_data.operation_done = &done;
Radio.SetMaxPayloadLength(MODEM_LORA, 255);
Radio.Rx(0);
ret = k_sem_take(&dev_data.data_sem, timeout);
ret = k_poll(&evt, 1, timeout);
if (ret < 0) {
LOG_INF("Receive timeout");
/* Manually transition to sleep mode on timeout */
dev_data.operation_done = NULL;
Radio.Sleep();
return ret;
}
......@@ -145,8 +156,6 @@ int sx12xx_lora_test_cw(const struct device *dev, uint32_t frequency,
int sx12xx_init(const struct device *dev)
{
k_sem_init(&dev_data.data_sem, 0, K_SEM_MAX_LIMIT);
dev_data.events.TxDone = sx12xx_ev_tx_done;
dev_data.events.RxDone = sx12xx_ev_rx_done;
Radio.Init(&dev_data.events);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment