Line data Source code
1 1 : /*
2 : * Copyright (c) 2019 Manivannan Sadhasivam
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Public LoRa driver APIs
10 : */
11 : #ifndef ZEPHYR_INCLUDE_DRIVERS_LORA_H_
12 : #define ZEPHYR_INCLUDE_DRIVERS_LORA_H_
13 :
14 : /**
15 : * @file
16 : * @brief Public LoRa APIs
17 : * @defgroup lora_api LoRa APIs
18 : * @since 2.2
19 : * @version 0.1.0
20 : * @ingroup io_interfaces
21 : * @{
22 : */
23 :
24 : #include <stdint.h>
25 : #include <zephyr/kernel.h>
26 : #include <zephyr/device.h>
27 :
28 : #ifdef __cplusplus
29 : extern "C" {
30 : #endif
31 :
32 : /**
33 : * @brief LoRa signal bandwidth
34 : */
35 0 : enum lora_signal_bandwidth {
36 : BW_125_KHZ = 0,
37 : BW_250_KHZ,
38 : BW_500_KHZ,
39 : };
40 :
41 : /**
42 : * @brief LoRa data-rate
43 : */
44 0 : enum lora_datarate {
45 : SF_6 = 6,
46 : SF_7,
47 : SF_8,
48 : SF_9,
49 : SF_10,
50 : SF_11,
51 : SF_12,
52 : };
53 :
54 : /**
55 : * @brief LoRa coding rate
56 : */
57 0 : enum lora_coding_rate {
58 : CR_4_5 = 1,
59 : CR_4_6 = 2,
60 : CR_4_7 = 3,
61 : CR_4_8 = 4,
62 : };
63 :
64 : /**
65 : * @struct lora_modem_config
66 : * Structure containing the configuration of a LoRa modem
67 : */
68 1 : struct lora_modem_config {
69 : /** Frequency in Hz to use for transceiving */
70 1 : uint32_t frequency;
71 :
72 : /** The bandwidth to use for transceiving */
73 1 : enum lora_signal_bandwidth bandwidth;
74 :
75 : /** The data-rate to use for transceiving */
76 1 : enum lora_datarate datarate;
77 :
78 : /** The coding rate to use for transceiving */
79 1 : enum lora_coding_rate coding_rate;
80 :
81 : /** Length of the preamble */
82 1 : uint16_t preamble_len;
83 :
84 : /** TX-power in dBm to use for transmission */
85 1 : int8_t tx_power;
86 :
87 : /** Set to true for transmission, false for receiving */
88 1 : bool tx;
89 :
90 : /**
91 : * Invert the In-Phase and Quadrature (IQ) signals. Normally this
92 : * should be set to false. In advanced use-cases where a
93 : * differentation is needed between "uplink" and "downlink" traffic,
94 : * the IQ can be inverted to create two different channels on the
95 : * same frequency
96 : */
97 1 : bool iq_inverted;
98 :
99 : /**
100 : * Sets the sync-byte to use:
101 : * - false: for using the private network sync-byte
102 : * - true: for using the public network sync-byte
103 : * The public network sync-byte is only intended for advanced usage.
104 : * Normally the private network sync-byte should be used for peer
105 : * to peer communications and the LoRaWAN APIs should be used for
106 : * interacting with a public network.
107 : */
108 1 : bool public_network;
109 : };
110 :
111 : /**
112 : * @cond INTERNAL_HIDDEN
113 : *
114 : * For internal driver use only, skip these in public documentation.
115 : */
116 :
117 : /**
118 : * @typedef lora_recv_cb()
119 : * @brief Callback API for receiving data asynchronously
120 : *
121 : * @see lora_recv() for argument descriptions.
122 : */
123 : typedef void (*lora_recv_cb)(const struct device *dev, uint8_t *data, uint16_t size,
124 : int16_t rssi, int8_t snr, void *user_data);
125 :
126 : /**
127 : * @typedef lora_api_config()
128 : * @brief Callback API for configuring the LoRa module
129 : *
130 : * @see lora_config() for argument descriptions.
131 : */
132 : typedef int (*lora_api_config)(const struct device *dev,
133 : struct lora_modem_config *config);
134 :
135 : /**
136 : * @typedef lora_api_send()
137 : * @brief Callback API for sending data over LoRa
138 : *
139 : * @see lora_send() for argument descriptions.
140 : */
141 : typedef int (*lora_api_send)(const struct device *dev,
142 : uint8_t *data, uint32_t data_len);
143 :
144 : /**
145 : * @typedef lora_api_send_async()
146 : * @brief Callback API for sending data asynchronously over LoRa
147 : *
148 : * @see lora_send_async() for argument descriptions.
149 : */
150 : typedef int (*lora_api_send_async)(const struct device *dev,
151 : uint8_t *data, uint32_t data_len,
152 : struct k_poll_signal *async);
153 :
154 : /**
155 : * @typedef lora_api_recv()
156 : * @brief Callback API for receiving data over LoRa
157 : *
158 : * @see lora_recv() for argument descriptions.
159 : */
160 : typedef int (*lora_api_recv)(const struct device *dev, uint8_t *data,
161 : uint8_t size,
162 : k_timeout_t timeout, int16_t *rssi, int8_t *snr);
163 :
164 : /**
165 : * @typedef lora_api_recv_async()
166 : * @brief Callback API for receiving data asynchronously over LoRa
167 : *
168 : * @param dev Modem to receive data on.
169 : * @param cb Callback to run on receiving data.
170 : */
171 : typedef int (*lora_api_recv_async)(const struct device *dev, lora_recv_cb cb,
172 : void *user_data);
173 :
174 : /**
175 : * @typedef lora_api_test_cw()
176 : * @brief Callback API for transmitting a continuous wave
177 : *
178 : * @see lora_test_cw() for argument descriptions.
179 : */
180 : typedef int (*lora_api_test_cw)(const struct device *dev, uint32_t frequency,
181 : int8_t tx_power, uint16_t duration);
182 :
183 : __subsystem struct lora_driver_api {
184 : lora_api_config config;
185 : lora_api_send send;
186 : lora_api_send_async send_async;
187 : lora_api_recv recv;
188 : lora_api_recv_async recv_async;
189 : lora_api_test_cw test_cw;
190 : };
191 :
192 : /** @endcond */
193 :
194 : /**
195 : * @brief Configure the LoRa modem
196 : *
197 : * @param dev LoRa device
198 : * @param config Data structure containing the intended configuration for the
199 : modem
200 : * @return 0 on success, negative on error
201 : */
202 1 : static inline int lora_config(const struct device *dev,
203 : struct lora_modem_config *config)
204 : {
205 : const struct lora_driver_api *api =
206 : (const struct lora_driver_api *)dev->api;
207 :
208 : return api->config(dev, config);
209 : }
210 :
211 : /**
212 : * @brief Send data over LoRa
213 : *
214 : * @note This blocks until transmission is complete.
215 : *
216 : * @param dev LoRa device
217 : * @param data Data to be sent
218 : * @param data_len Length of the data to be sent
219 : * @return 0 on success, negative on error
220 : */
221 1 : static inline int lora_send(const struct device *dev,
222 : uint8_t *data, uint32_t data_len)
223 : {
224 : const struct lora_driver_api *api =
225 : (const struct lora_driver_api *)dev->api;
226 :
227 : return api->send(dev, data, data_len);
228 : }
229 :
230 : /**
231 : * @brief Asynchronously send data over LoRa
232 : *
233 : * @note This returns immediately after starting transmission, and locks
234 : * the LoRa modem until the transmission completes.
235 : *
236 : * @param dev LoRa device
237 : * @param data Data to be sent
238 : * @param data_len Length of the data to be sent
239 : * @param async A pointer to a valid and ready to be signaled
240 : * struct k_poll_signal. (Note: if NULL this function will not
241 : * notify the end of the transmission).
242 : * @return 0 on success, negative on error
243 : */
244 1 : static inline int lora_send_async(const struct device *dev,
245 : uint8_t *data, uint32_t data_len,
246 : struct k_poll_signal *async)
247 : {
248 : const struct lora_driver_api *api =
249 : (const struct lora_driver_api *)dev->api;
250 :
251 : return api->send_async(dev, data, data_len, async);
252 : }
253 :
254 : /**
255 : * @brief Receive data over LoRa
256 : *
257 : * @note This is a blocking call.
258 : *
259 : * @param dev LoRa device
260 : * @param data Buffer to hold received data
261 : * @param size Size of the buffer to hold the received data. Max size
262 : allowed is 255.
263 : * @param timeout Duration to wait for a packet.
264 : * @param rssi RSSI of received data
265 : * @param snr SNR of received data
266 : * @return Length of the data received on success, negative on error
267 : */
268 1 : static inline int lora_recv(const struct device *dev, uint8_t *data,
269 : uint8_t size,
270 : k_timeout_t timeout, int16_t *rssi, int8_t *snr)
271 : {
272 : const struct lora_driver_api *api =
273 : (const struct lora_driver_api *)dev->api;
274 :
275 : return api->recv(dev, data, size, timeout, rssi, snr);
276 : }
277 :
278 : /**
279 : * @brief Receive data asynchronously over LoRa
280 : *
281 : * Receive packets continuously under the configuration previously setup
282 : * by @ref lora_config.
283 : *
284 : * Reception is cancelled by calling this function again with @p cb = NULL.
285 : * This can be done within the callback handler.
286 : *
287 : * @param dev Modem to receive data on.
288 : * @param cb Callback to run on receiving data. If NULL, any pending
289 : * asynchronous receptions will be cancelled.
290 : * @param user_data User data passed to callback
291 : * @return 0 when reception successfully setup, negative on error
292 : */
293 1 : static inline int lora_recv_async(const struct device *dev, lora_recv_cb cb,
294 : void *user_data)
295 : {
296 : const struct lora_driver_api *api =
297 : (const struct lora_driver_api *)dev->api;
298 :
299 : return api->recv_async(dev, cb, user_data);
300 : }
301 :
302 : /**
303 : * @brief Transmit an unmodulated continuous wave at a given frequency
304 : *
305 : * @note Only use this functionality in a test setup where the
306 : * transmission does not interfere with other devices.
307 : *
308 : * @param dev LoRa device
309 : * @param frequency Output frequency (Hertz)
310 : * @param tx_power TX power (dBm)
311 : * @param duration Transmission duration in seconds.
312 : * @return 0 on success, negative on error
313 : */
314 1 : static inline int lora_test_cw(const struct device *dev, uint32_t frequency,
315 : int8_t tx_power, uint16_t duration)
316 : {
317 : const struct lora_driver_api *api =
318 : (const struct lora_driver_api *)dev->api;
319 :
320 : if (api->test_cw == NULL) {
321 : return -ENOSYS;
322 : }
323 :
324 : return api->test_cw(dev, frequency, tx_power, duration);
325 : }
326 :
327 : #ifdef __cplusplus
328 : }
329 : #endif
330 :
331 : /**
332 : * @}
333 : */
334 :
335 : #endif /* ZEPHYR_INCLUDE_DRIVERS_LORA_H_ */
|