Skip to content

Commit a36147c

Browse files
andysannashif
authored andcommitted
drivers: lora: Factor out sx12xx common functionality
LoRa radios supported by LoRaMAC-Node have a lot of common functionality. Zephyr's LoRa implementation for the SX1276 uses LoRaMAC-Nodes Radio HAL to implement API functionality like send and recv. The exact same functionality will be used by the SX126x driver. Facilitate sharing by moving that to a separate source file. Signed-off-by: Andreas Sandberg <andreas@sandberg.pp.se>
1 parent 69fac5c commit a36147c

File tree

4 files changed

+163
-108
lines changed

4 files changed

+163
-108
lines changed

drivers/lora/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ zephyr_library_named(loramac-node)
44

55
zephyr_library_sources_ifdef(CONFIG_LORA_SHELL shell.c)
66
zephyr_library_sources_ifdef(CONFIG_HAS_SEMTECH_RADIO_DRIVERS hal_common.c)
7+
zephyr_library_sources_ifdef(CONFIG_HAS_SEMTECH_RADIO_DRIVERS sx12xx_common.c)
78
zephyr_library_sources_ifdef(CONFIG_LORA_SX1276 sx1276.c)

drivers/lora/sx1276.c

Lines changed: 12 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <drivers/lora.h>
1111
#include <drivers/spi.h>
1212
#include <zephyr.h>
13+
#include "sx12xx_common.h"
1314

1415
/* LoRaMac-node specific includes */
1516
#include <sx1276/sx1276.h>
@@ -49,18 +50,12 @@ static const struct sx1276_dio sx1276_dios[] = { SX1276_DIO_GPIO_INIT(0) };
4950

5051
#define SX1276_MAX_DIO ARRAY_SIZE(sx1276_dios)
5152

52-
struct sx1276_data {
53+
static struct sx1276_data {
5354
struct device *reset;
5455
struct device *spi;
5556
struct spi_config spi_cfg;
5657
struct device *dio_dev[SX1276_MAX_DIO];
5758
struct k_work dio_work[SX1276_MAX_DIO];
58-
struct k_sem data_sem;
59-
RadioEvents_t sx1276_event;
60-
uint8_t *rx_buf;
61-
uint8_t rx_len;
62-
int8_t snr;
63-
int16_t rssi;
6459
} dev_data;
6560

6661
bool SX1276CheckRfFrequency(uint32_t frequency)
@@ -289,97 +284,6 @@ void SX1276SetRfTxPower(int8_t power)
289284
}
290285
}
291286

292-
static int sx1276_lora_send(struct device *dev, uint8_t *data, uint32_t data_len)
293-
{
294-
Radio.SetMaxPayloadLength(MODEM_LORA, data_len);
295-
296-
Radio.Send(data, data_len);
297-
298-
return 0;
299-
}
300-
301-
static void sx1276_tx_done(void)
302-
{
303-
Radio.Sleep();
304-
}
305-
306-
static void sx1276_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
307-
{
308-
Radio.Sleep();
309-
310-
dev_data.rx_buf = payload;
311-
dev_data.rx_len = size;
312-
dev_data.rssi = rssi;
313-
dev_data.snr = snr;
314-
315-
k_sem_give(&dev_data.data_sem);
316-
}
317-
318-
static int sx1276_lora_recv(struct device *dev, uint8_t *data, uint8_t size,
319-
k_timeout_t timeout, int16_t *rssi, int8_t *snr)
320-
{
321-
int ret;
322-
323-
Radio.SetMaxPayloadLength(MODEM_LORA, 255);
324-
Radio.Rx(0);
325-
326-
ret = k_sem_take(&dev_data.data_sem, timeout);
327-
if (ret < 0) {
328-
LOG_ERR("Receive timeout!");
329-
return ret;
330-
}
331-
332-
/* Only copy the bytes that can fit the buffer, drop the rest */
333-
if (dev_data.rx_len > size)
334-
dev_data.rx_len = size;
335-
336-
/*
337-
* FIXME: We are copying the global buffer here, so it might get
338-
* overwritten inbetween when a new packet comes in. Use some
339-
* wise method to fix this!
340-
*/
341-
memcpy(data, dev_data.rx_buf, dev_data.rx_len);
342-
343-
if (rssi != NULL) {
344-
*rssi = dev_data.rssi;
345-
}
346-
347-
if (snr != NULL) {
348-
*snr = dev_data.snr;
349-
}
350-
351-
return dev_data.rx_len;
352-
}
353-
354-
static int sx1276_lora_config(struct device *dev,
355-
struct lora_modem_config *config)
356-
{
357-
358-
Radio.SetChannel(config->frequency);
359-
360-
if (config->tx) {
361-
Radio.SetTxConfig(MODEM_LORA, config->tx_power, 0,
362-
config->bandwidth, config->datarate,
363-
config->coding_rate, config->preamble_len,
364-
false, true, 0, 0, false, 4000);
365-
} else {
366-
/* TODO: Get symbol timeout value from config parameters */
367-
Radio.SetRxConfig(MODEM_LORA, config->bandwidth,
368-
config->datarate, config->coding_rate,
369-
0, config->preamble_len, 10, false, 0,
370-
false, 0, 0, false, true);
371-
}
372-
373-
return 0;
374-
}
375-
376-
static int sx1276_lora_test_cw(struct device *dev, uint32_t frequency,
377-
int8_t tx_power, uint16_t duration)
378-
{
379-
Radio.SetTxContinuousWave(frequency, tx_power, duration);
380-
return 0;
381-
}
382-
383287
/* Initialize Radio driver callbacks */
384288
const struct Radio_s Radio = {
385289
.Init = SX1276Init,
@@ -456,22 +360,22 @@ static int sx1276_lora_init(struct device *dev)
456360
return -EIO;
457361
}
458362

459-
k_sem_init(&dev_data.data_sem, 0, UINT_MAX);
460-
461-
dev_data.sx1276_event.TxDone = sx1276_tx_done;
462-
dev_data.sx1276_event.RxDone = sx1276_rx_done;
463-
Radio.Init(&dev_data.sx1276_event);
464-
465363
LOG_INF("SX1276 Version:%02x found", regval);
466364

365+
ret = sx12xx_init(dev);
366+
if (ret < 0) {
367+
LOG_ERR("Failed to initialize SX12xx common");
368+
return ret;
369+
}
370+
467371
return 0;
468372
}
469373

470374
static const struct lora_driver_api sx1276_lora_api = {
471-
.config = sx1276_lora_config,
472-
.send = sx1276_lora_send,
473-
.recv = sx1276_lora_recv,
474-
.test_cw = sx1276_lora_test_cw,
375+
.config = sx12xx_lora_config,
376+
.send = sx12xx_lora_send,
377+
.recv = sx12xx_lora_recv,
378+
.test_cw = sx12xx_lora_test_cw,
475379
};
476380

477381
DEVICE_AND_API_INIT(sx1276_lora, DT_INST_LABEL(0),

drivers/lora/sx12xx_common.c

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright (c) 2019 Manivannan Sadhasivam
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <drivers/lora.h>
8+
#include <logging/log.h>
9+
#include <zephyr.h>
10+
11+
/* LoRaMac-node specific includes */
12+
#include <radio.h>
13+
14+
LOG_MODULE_REGISTER(sx12xx_common, CONFIG_LORA_LOG_LEVEL);
15+
16+
static struct sx12xx_data {
17+
struct k_sem data_sem;
18+
RadioEvents_t events;
19+
uint8_t *rx_buf;
20+
uint8_t rx_len;
21+
int8_t snr;
22+
int16_t rssi;
23+
} dev_data;
24+
25+
static void sx12xx_ev_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
26+
int8_t snr)
27+
{
28+
Radio.Sleep();
29+
30+
dev_data.rx_buf = payload;
31+
dev_data.rx_len = size;
32+
dev_data.rssi = rssi;
33+
dev_data.snr = snr;
34+
35+
k_sem_give(&dev_data.data_sem);
36+
}
37+
38+
static void sx12xx_ev_tx_done(void)
39+
{
40+
Radio.Sleep();
41+
}
42+
43+
int sx12xx_lora_send(struct device *dev, uint8_t *data, uint32_t data_len)
44+
{
45+
Radio.SetMaxPayloadLength(MODEM_LORA, data_len);
46+
47+
Radio.Send(data, data_len);
48+
49+
return 0;
50+
}
51+
52+
int sx12xx_lora_recv(struct device *dev, uint8_t *data, uint8_t size,
53+
k_timeout_t timeout, int16_t *rssi, int8_t *snr)
54+
{
55+
int ret;
56+
57+
Radio.SetMaxPayloadLength(MODEM_LORA, 255);
58+
Radio.Rx(0);
59+
60+
ret = k_sem_take(&dev_data.data_sem, timeout);
61+
if (ret < 0) {
62+
LOG_ERR("Receive timeout!");
63+
return ret;
64+
}
65+
66+
/* Only copy the bytes that can fit the buffer, drop the rest */
67+
if (dev_data.rx_len > size)
68+
dev_data.rx_len = size;
69+
70+
/*
71+
* FIXME: We are copying the global buffer here, so it might get
72+
* overwritten inbetween when a new packet comes in. Use some
73+
* wise method to fix this!
74+
*/
75+
memcpy(data, dev_data.rx_buf, dev_data.rx_len);
76+
77+
if (rssi != NULL) {
78+
*rssi = dev_data.rssi;
79+
}
80+
81+
if (snr != NULL) {
82+
*snr = dev_data.snr;
83+
}
84+
85+
return dev_data.rx_len;
86+
}
87+
88+
int sx12xx_lora_config(struct device *dev, struct lora_modem_config *config)
89+
{
90+
Radio.SetChannel(config->frequency);
91+
92+
if (config->tx) {
93+
Radio.SetTxConfig(MODEM_LORA, config->tx_power, 0,
94+
config->bandwidth, config->datarate,
95+
config->coding_rate, config->preamble_len,
96+
false, true, 0, 0, false, 4000);
97+
} else {
98+
/* TODO: Get symbol timeout value from config parameters */
99+
Radio.SetRxConfig(MODEM_LORA, config->bandwidth,
100+
config->datarate, config->coding_rate,
101+
0, config->preamble_len, 10, false, 0,
102+
false, 0, 0, false, true);
103+
}
104+
105+
return 0;
106+
}
107+
108+
int sx12xx_lora_test_cw(struct device *dev, uint32_t frequency, int8_t tx_power,
109+
uint16_t duration)
110+
{
111+
Radio.SetTxContinuousWave(frequency, tx_power, duration);
112+
return 0;
113+
}
114+
115+
int sx12xx_init(struct device *dev)
116+
{
117+
k_sem_init(&dev_data.data_sem, 0, UINT_MAX);
118+
119+
dev_data.events.TxDone = sx12xx_ev_tx_done;
120+
dev_data.events.RxDone = sx12xx_ev_rx_done;
121+
Radio.Init(&dev_data.events);
122+
123+
return 0;
124+
}

drivers/lora/sx12xx_common.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2020 Andreas Sandberg
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_DRIVERS_SX12XX_COMMON_H_
8+
#define ZEPHYR_DRIVERS_SX12XX_COMMON_H_
9+
10+
#include <zephyr/types.h>
11+
#include <drivers/lora.h>
12+
#include <device.h>
13+
14+
int sx12xx_lora_send(struct device *dev, uint8_t *data, uint32_t data_len);
15+
16+
int sx12xx_lora_recv(struct device *dev, uint8_t *data, uint8_t size,
17+
k_timeout_t timeout, int16_t *rssi, int8_t *snr);
18+
19+
int sx12xx_lora_config(struct device *dev, struct lora_modem_config *config);
20+
21+
int sx12xx_lora_test_cw(struct device *dev, uint32_t frequency, int8_t tx_power,
22+
uint16_t duration);
23+
24+
int sx12xx_init(struct device *dev);
25+
26+
#endif /* ZEPHYR_DRIVERS_SX12XX_COMMON_H_ */

0 commit comments

Comments
 (0)