forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsx12xx_common.c
161 lines (129 loc) · 3.46 KB
/
sx12xx_common.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* Copyright (c) 2019 Manivannan Sadhasivam
* Copyright (c) 2020 Grinn
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <drivers/gpio.h>
#include <drivers/lora.h>
#include <logging/log.h>
#include <zephyr.h>
/* LoRaMac-node specific includes */
#include <radio.h>
#include "sx12xx_common.h"
LOG_MODULE_REGISTER(sx12xx_common, CONFIG_LORA_LOG_LEVEL);
static struct sx12xx_data {
struct k_sem data_sem;
RadioEvents_t events;
uint8_t *rx_buf;
uint8_t rx_len;
int8_t snr;
int16_t rssi;
} dev_data;
int __sx12xx_configure_pin(const struct device * *dev, const char *controller,
gpio_pin_t pin, gpio_flags_t flags)
{
int err;
*dev = device_get_binding(controller);
if (!(*dev)) {
LOG_ERR("Cannot get pointer to %s device", controller);
return -EIO;
}
err = gpio_pin_configure(*dev, pin, flags);
if (err) {
LOG_ERR("Cannot configure gpio %s %d: %d", controller, pin,
err);
return err;
}
return 0;
}
static void sx12xx_ev_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
int8_t snr)
{
Radio.Sleep();
dev_data.rx_buf = payload;
dev_data.rx_len = size;
dev_data.rssi = rssi;
dev_data.snr = snr;
k_sem_give(&dev_data.data_sem);
}
static void sx12xx_ev_tx_done(void)
{
Radio.Sleep();
}
int sx12xx_lora_send(const struct device *dev, uint8_t *data,
uint32_t data_len)
{
Radio.SetMaxPayloadLength(MODEM_LORA, data_len);
Radio.Send(data, data_len);
return 0;
}
int sx12xx_lora_recv(const struct device *dev, uint8_t *data, uint8_t size,
k_timeout_t timeout, int16_t *rssi, int8_t *snr)
{
int ret;
Radio.SetMaxPayloadLength(MODEM_LORA, 255);
Radio.Rx(0);
ret = k_sem_take(&dev_data.data_sem, timeout);
if (ret < 0) {
LOG_ERR("Receive timeout!");
return ret;
}
/* Only copy the bytes that can fit the buffer, drop the rest */
if (dev_data.rx_len > size)
dev_data.rx_len = size;
/*
* FIXME: We are copying the global buffer here, so it might get
* overwritten inbetween when a new packet comes in. Use some
* wise method to fix this!
*/
memcpy(data, dev_data.rx_buf, dev_data.rx_len);
if (rssi != NULL) {
*rssi = dev_data.rssi;
}
if (snr != NULL) {
*snr = dev_data.snr;
}
return dev_data.rx_len;
}
int sx12xx_lora_config(const struct device *dev,
struct lora_modem_config *config)
{
Radio.SetChannel(config->frequency);
if (config->tx) {
Radio.SetTxConfig(MODEM_LORA, config->tx_power, 0,
config->bandwidth, config->datarate,
config->coding_rate, config->preamble_len,
false, true, 0, 0, false, 4000);
} else {
/* TODO: Get symbol timeout value from config parameters */
Radio.SetRxConfig(MODEM_LORA, config->bandwidth,
config->datarate, config->coding_rate,
0, config->preamble_len, 10, false, 0,
false, 0, 0, false, true);
}
return 0;
}
int sx12xx_lora_test_cw(const struct device *dev, uint32_t frequency,
int8_t tx_power,
uint16_t duration)
{
Radio.SetTxContinuousWave(frequency, tx_power, duration);
return 0;
}
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);
/*
* Automatically place the radio into sleep mode upon boot.
* The required `lora_config` call before transmission or reception
* will bring the radio out of sleep mode before it is used. The radio
* is automatically placed back into sleep mode upon TX or RX
* completion.
*/
Radio.Sleep();
return 0;
}