Mbed OS Reference
Loading...
Searching...
No Matches
SX1276_LoRaRadio.h
1/**
2 / _____) _ | |
3( (____ _____ ____ _| |_ _____ ____| |__
4 \____ \| ___ | (_ _) ___ |/ ___) _ \
5 _____) ) ____| | | || |_| ____( (___| | | |
6(______/|_____)_|_|_| \__)_____)\____)_| |_|
7 (C)2013 Semtech
8 ___ _____ _ ___ _ _____ ___ ___ ___ ___
9/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
10\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
11|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
12embedded.connectivity.solutions===============
13
14Description: LoRaWAN stack layer that controls both MAC and PHY underneath
15
16License: Revised BSD License, see LICENSE.TXT file include in the project
17
18Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
19
20
21Copyright (c) 2017, Arm Limited and affiliates.
22
23SPDX-License-Identifier: BSD-3-Clause
24*/
25
26#ifndef SX1276_LORARADIO_H_
27#define SX1276_LORARADIO_H_
28
29#if DEVICE_SPI
30
31#include "PinNames.h"
32#include "InterruptIn.h"
33#include "DigitalOut.h"
34#include "DigitalInOut.h"
35#include "SPI.h"
36#include "rtos/Mutex.h"
37#ifdef MBED_CONF_RTOS_PRESENT
38#include "rtos/Thread.h"
39#endif
40
41#include "lorawan/LoRaRadio.h"
42
43#ifdef MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE
44#define MAX_DATA_BUFFER_SIZE_SX1276 MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE
45#else
46#define MAX_DATA_BUFFER_SIZE_SX1276 255
47#endif
48
49#if DEVICE_LPTICKER
50#include "LowPowerTimeout.h"
51#define ALIAS_LORAWAN_TIMER mbed::LowPowerTimeout
52#else
53#include "Timeout.h"
54#define ALIAS_LORAWAN_TIMER mbed::Timeout
55#endif
56
57/**
58 * Radio driver implementation for Semtech SX1272 plus variants.
59 * Supports only SPI at the moment. Implements pure virtual LoRaRadio class.
60 */
62public:
63 /**
64 * Use this constructor if pin definitions are provided manually.
65 * The pins that are marked NC are optional. It is assumed that these
66 * pins are not connected until/unless configured otherwise.
67 *
68 * Note: Pin ant_switch is equivalent to RxTx pin at
69 * https://developer.mbed.org/components/SX1276MB1xAS/.
70 * Reading the state of this pin indicates if the radio module type is
71 * SX1276MB1LAS(North American frequency band supported) or SX1276MAS
72 * (European frequency band supported).
73 * Pin dio4 can be mapped to multiple pins on the board, please refer to
74 * schematic of your board. For reference look at
75 * https://developer.mbed.org/components/SX1276MB1xAS/
76 *
77 * Most of the radio module control pins are not being used at the moment as
78 * the SX1276MB1xAS shield has not connected them. For consistency and future
79 * use we are leaving the pins in the constructor. For example, if in some
80 * setting SX1276 radio module gets connected to an external power amplifier
81 * or radio latch controls are connected.
82 */
83 SX1276_LoRaRadio(PinName mosi = MBED_CONF_SX1276_LORA_DRIVER_SPI_MOSI,
84 PinName miso = MBED_CONF_SX1276_LORA_DRIVER_SPI_MISO,
85 PinName sclk = MBED_CONF_SX1276_LORA_DRIVER_SPI_SCLK,
86 PinName nss = MBED_CONF_SX1276_LORA_DRIVER_SPI_CS,
87 PinName reset = MBED_CONF_SX1276_LORA_DRIVER_RESET,
88 PinName dio0 = MBED_CONF_SX1276_LORA_DRIVER_DIO0,
89 PinName dio1 = MBED_CONF_SX1276_LORA_DRIVER_DIO1,
90 PinName dio2 = MBED_CONF_SX1276_LORA_DRIVER_DIO2,
91 PinName dio3 = MBED_CONF_SX1276_LORA_DRIVER_DIO3,
92 PinName dio4 = MBED_CONF_SX1276_LORA_DRIVER_DIO4,
93 PinName dio5 = MBED_CONF_SX1276_LORA_DRIVER_DIO5,
94 PinName rf_switch_ctl1 = MBED_CONF_SX1276_LORA_DRIVER_RF_SWITCH_CTL1,
95 PinName rf_switch_ctl2 = MBED_CONF_SX1276_LORA_DRIVER_RF_SWITCH_CTL2,
96 PinName txctl = MBED_CONF_SX1276_LORA_DRIVER_TXCTL,
97 PinName rxctl = MBED_CONF_SX1276_LORA_DRIVER_RXCTL,
98 PinName ant_switch = MBED_CONF_SX1276_LORA_DRIVER_ANT_SWITCH,
99 PinName pwr_amp_ctl = MBED_CONF_SX1276_LORA_DRIVER_PWR_AMP_CTL,
100 PinName tcxo = MBED_CONF_SX1276_LORA_DRIVER_TCXO
101 );
102
103 /**
104 * Destructor
105 */
107
108 /**
109 * Registers radio events with the Mbed LoRaWAN stack and
110 * undergoes initialization steps if any
111 *
112 * @param events Structure containing the driver callback functions
113 */
114 virtual void init_radio(radio_events_t *events);
115
116 /**
117 * Resets the radio module
118 */
119 virtual void radio_reset();
120
121 /**
122 * Put the RF module in sleep mode
123 */
124 virtual void sleep(void);
125
126 /**
127 * Sets the radio in standby mode
128 */
129 virtual void standby(void);
130
131 void set_rx_config(radio_modems_t modem, uint32_t bandwidth,
132 uint32_t datarate, uint8_t coderate,
133 uint32_t bandwidth_afc, uint16_t preamble_len,
134 uint16_t symb_timeout, bool fix_len,
135 uint8_t payload_len,
136 bool crc_on, bool freq_hop_on, uint8_t hop_period,
137 bool iq_inverted, bool rx_continuous) override;
138
139 /**
140 * Sets the transmission parameters
141 *
142 * @param modem Radio modem to be used [0: FSK, 1: LoRa]
143 * @param power Sets the output power [dBm]
144 * @param fdev Sets the frequency deviation ( FSK only )
145 * FSK : [Hz]
146 * LoRa: 0
147 * @param bandwidth Sets the bandwidth ( LoRa only )
148 * FSK : 0
149 * LoRa: [0: 125 kHz, 1: 250 kHz,
150 * 2: 500 kHz, 3: Reserved]
151 * @param datarate Sets the Datarate
152 * FSK : 600..300000 bits/s
153 * LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
154 * 10: 1024, 11: 2048, 12: 4096 chips]
155 * @param coderate Sets the coding rate ( LoRa only )
156 * FSK : N/A ( set to 0 )
157 * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
158 * @param preamble_len Sets the preamble length
159 * @param fix_len Fixed length packets [0: variable, 1: fixed]
160 * @param crc_on Enables disables the CRC [0: OFF, 1: ON]
161 * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only)
162 * @param hop_period Number of symbols bewteen each hop (LoRa only)
163 * @param iq_inverted Inverts IQ signals ( LoRa only )
164 * FSK : N/A ( set to 0 )
165 * LoRa: [0: not inverted, 1: inverted]
166 * @param timeout Transmission timeout [ms]
167 */
168 virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev,
169 uint32_t bandwidth, uint32_t datarate,
170 uint8_t coderate, uint16_t preamble_len,
171 bool fix_len, bool crc_on, bool freq_hop_on,
172 uint8_t hop_period, bool iq_inverted, uint32_t timeout);
173
174 /**
175 * Sends the buffer of size
176 *
177 * Prepares the packet to be sent and sets the radio in transmission
178 *
179 * @param buffer Buffer pointer
180 * @param size Buffer size
181 */
182 virtual void send(uint8_t *buffer, uint8_t size);
183
184 /**
185 * For backwards compatibility
186 */
187 virtual void receive(uint32_t timeout)
188 {
189 (void) timeout;
190 receive();
191 }
192
193 /**
194 * Sets the radio to receive
195 *
196 * All necessary configuration options for reception are set in
197 * 'set_rx_config(parameters)' API.
198 */
199 virtual void receive(void);
200
201 /**
202 * Sets the carrier frequency
203 *
204 * @param freq Channel RF frequency
205 */
206 virtual void set_channel(uint32_t freq);
207
208 /**
209 * Generates a 32 bits random value based on the RSSI readings
210 *
211 * Remark this function sets the radio in LoRa modem mode and disables
212 * all interrupts.
213 * After calling this function either Radio.SetRxConfig or
214 * Radio.SetTxConfig functions must be called.
215 *
216 * @return 32 bits random value
217 */
218 virtual uint32_t random(void);
219
220 radio_state_t get_status(void) override;
221
222 /**
223 * Sets the maximum payload length
224 *
225 * @param modem Radio modem to be used [0: FSK, 1: LoRa]
226 * @param max Maximum payload length in bytes
227 */
228 virtual void set_max_payload_length(radio_modems_t modem, uint8_t max);
229
230 /**
231 * Sets the network to public or private
232 *
233 * Updates the sync byte. Applies to LoRa modem only
234 *
235 * @param enable if true, it enables a public network
236 */
237 virtual void set_public_network(bool enable);
238
239 /**
240 * Computes the packet time on air for the given payload
241 *
242 * Remark can only be called once SetRxConfig or SetTxConfig have been called
243 *
244 * @param modem Radio modem to be used [0: FSK, 1: LoRa]
245 * @param pkt_len Packet payload length
246 * @return Computed airTime for the given packet payload length
247 */
248 virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len);
249
250 /**
251 * Perform carrier sensing
252 *
253 * Checks for a certain time if the RSSI is above a given threshold.
254 * This threshold determines if there is already a transmission going on
255 * in the channel or not.
256 *
257 * @param modem Type of the radio modem
258 * @param freq Carrier frequency
259 * @param rssi_threshold Threshold value of RSSI
260 * @param max_carrier_sense_time time to sense the channel
261 *
262 * @return true if there is no active transmission
263 * in the channel, false otherwise
264 */
266 uint32_t freq,
267 int16_t rssi_threshold,
268 uint32_t max_carrier_sense_time);
269
270 /**
271 * Sets the radio in CAD mode
272 *
273 */
274 virtual void start_cad(void);
275
276 /**
277 * Check if the given RF is in range
278 *
279 * @param frequency frequency needed to be checked
280 */
281 virtual bool check_rf_frequency(uint32_t frequency);
282
283 /** Sets the radio in continuous wave transmission mode
284 *
285 * @param freq Channel RF frequency
286 * @param power Sets the output power [dBm]
287 * @param time Transmission mode timeout [s]
288 */
289 virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time);
290
291 /**
292 * Acquire exclusive access
293 */
294 virtual void lock(void);
295
296 /**
297 * Release exclusive access
298 */
299 virtual void unlock(void);
300
301private:
302
303 // SPI and chip select control
304 mbed::SPI _spi;
305 mbed::DigitalOut _chip_select;
306
307 // module rest control
308 mbed::DigitalInOut _reset_ctl;
309
310 // Interrupt controls
311 mbed::InterruptIn _dio0_ctl;
312 mbed::InterruptIn _dio1_ctl;
313 mbed::InterruptIn _dio2_ctl;
314 mbed::InterruptIn _dio3_ctl;
315 mbed::InterruptIn _dio4_ctl;
316 mbed::InterruptIn _dio5_ctl;
317
318 // Radio specific controls
319 mbed::DigitalOut _rf_switch_ctl1;
320 mbed::DigitalOut _rf_switch_ctl2;
321 mbed::DigitalOut _txctl;
322 mbed::DigitalOut _rxctl;
323 mbed::DigitalInOut _ant_switch;
324 mbed::DigitalOut _pwr_amp_ctl;
325 mbed::DigitalOut _tcxo;
326
327 // Contains all RF control pin names
328 // This storage is needed even after assigning the
329 // pins to corresponding object, as the driver needs to know
330 // which control pins are connected and which are not. This
331 // variation is inherent to driver because of target configuration.
332 rf_ctrls _rf_ctrls;
333
334 // We need these PinNames as not all modules have those connected
335 PinName _dio4_pin;
336 PinName _dio5_pin;
337
338 // Structure containing all user and network specified settings
339 // for radio module
340 radio_settings_t _rf_settings;
341
342 // Structure containing function pointers to the stack callbacks
343 radio_events_t *_radio_events;
344
345 // Data buffer used for both TX and RX
346 // Size of this buffer is configurable via Mbed config system
347 // Default is 255 bytes
348 uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX1276];
349
350 // TX timer in ms. This timer is used as a fail safe for TX.
351 // If the chip fails to transmit, its a fatal error, reflecting
352 // some catastrophic bus failure etc. We wish to have the control
353 // back from the driver in such a case.
354 ALIAS_LORAWAN_TIMER tx_timeout_timer;
355
356#ifdef MBED_CONF_RTOS_PRESENT
357 // Thread to handle interrupts
358 rtos::Thread irq_thread;
359#endif
360
361 // Access protection
362 rtos::Mutex mutex;
363
364 uint8_t radio_variant;
365
366 // helper functions
367 void setup_registers();
368 void default_antenna_switch_ctrls();
369 void set_antenna_switch(uint8_t operation_mode);
370 void setup_spi();
371 void gpio_init();
372 void gpio_deinit();
373 void setup_interrupts();
374 void set_operation_mode(uint8_t operation_mode);
375 void set_low_power_mode();
376 void set_sx1276_variant_type();
377 uint8_t get_pa_conf_reg(uint32_t channel);
378 void set_rf_tx_power(int8_t power);
379 int16_t get_rssi(radio_modems_t modem);
380 uint8_t get_fsk_bw_reg_val(uint32_t bandwidth);
381 void write_to_register(uint8_t addr, uint8_t data);
382 void write_to_register(uint8_t addr, uint8_t *data, uint8_t size);
383 uint8_t read_register(uint8_t addr);
384 void read_register(uint8_t addr, uint8_t *buffer, uint8_t size);
385 void write_fifo(uint8_t *buffer, uint8_t size);
386 void read_fifo(uint8_t *buffer, uint8_t size);
387 void transmit(uint32_t timeout);
388 void rf_irq_task(void);
389 void set_modem(uint8_t modem);
390 void rx_chain_calibration(void);
391
392 // ISRs
393 void dio0_irq_isr();
394 void dio1_irq_isr();
395 void dio2_irq_isr();
396 void dio3_irq_isr();
397 void dio4_irq_isr();
398 void dio5_irq_isr();
399 void timeout_irq_isr();
400
401 // Handlers called by thread in response to signal
402 void handle_dio0_irq();
403 void handle_dio1_irq();
404 void handle_dio2_irq();
405 void handle_dio3_irq();
406 void handle_dio4_irq();
407 void handle_dio5_irq();
408 void handle_timeout_irq();
409};
410
411#endif // DEVICE_SPI
412
413#endif // SX1276_LORARADIO_H_
Interface for the radios, containing the main functions that a radio needs, and five callback functio...
Definition: LoRaRadio.h:441
Radio driver implementation for Semtech SX1272 plus variants.
virtual bool check_rf_frequency(uint32_t frequency)
Check if the given RF is in range.
virtual void set_public_network(bool enable)
Sets the network to public or private.
virtual ~SX1276_LoRaRadio()
Destructor.
void set_rx_config(radio_modems_t modem, uint32_t bandwidth, uint32_t datarate, uint8_t coderate, uint32_t bandwidth_afc, uint16_t preamble_len, uint16_t symb_timeout, bool fix_len, uint8_t payload_len, bool crc_on, bool freq_hop_on, uint8_t hop_period, bool iq_inverted, bool rx_continuous) override
Sets reception parameters.
virtual void set_channel(uint32_t freq)
Sets the carrier frequency.
virtual void receive(uint32_t timeout)
For backwards compatibility.
virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len)
Computes the packet time on air for the given payload.
radio_state_t get_status(void) override
Gets the radio status.
virtual void unlock(void)
Release exclusive access.
virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, uint32_t bandwidth, uint32_t datarate, uint8_t coderate, uint16_t preamble_len, bool fix_len, bool crc_on, bool freq_hop_on, uint8_t hop_period, bool iq_inverted, uint32_t timeout)
Sets the transmission parameters.
virtual void receive(void)
Sets the radio to receive.
virtual void send(uint8_t *buffer, uint8_t size)
Sends the buffer of size.
SX1276_LoRaRadio(PinName mosi=MBED_CONF_SX1276_LORA_DRIVER_SPI_MOSI, PinName miso=MBED_CONF_SX1276_LORA_DRIVER_SPI_MISO, PinName sclk=MBED_CONF_SX1276_LORA_DRIVER_SPI_SCLK, PinName nss=MBED_CONF_SX1276_LORA_DRIVER_SPI_CS, PinName reset=MBED_CONF_SX1276_LORA_DRIVER_RESET, PinName dio0=MBED_CONF_SX1276_LORA_DRIVER_DIO0, PinName dio1=MBED_CONF_SX1276_LORA_DRIVER_DIO1, PinName dio2=MBED_CONF_SX1276_LORA_DRIVER_DIO2, PinName dio3=MBED_CONF_SX1276_LORA_DRIVER_DIO3, PinName dio4=MBED_CONF_SX1276_LORA_DRIVER_DIO4, PinName dio5=MBED_CONF_SX1276_LORA_DRIVER_DIO5, PinName rf_switch_ctl1=MBED_CONF_SX1276_LORA_DRIVER_RF_SWITCH_CTL1, PinName rf_switch_ctl2=MBED_CONF_SX1276_LORA_DRIVER_RF_SWITCH_CTL2, PinName txctl=MBED_CONF_SX1276_LORA_DRIVER_TXCTL, PinName rxctl=MBED_CONF_SX1276_LORA_DRIVER_RXCTL, PinName ant_switch=MBED_CONF_SX1276_LORA_DRIVER_ANT_SWITCH, PinName pwr_amp_ctl=MBED_CONF_SX1276_LORA_DRIVER_PWR_AMP_CTL, PinName tcxo=MBED_CONF_SX1276_LORA_DRIVER_TCXO)
Use this constructor if pin definitions are provided manually.
virtual bool perform_carrier_sense(radio_modems_t modem, uint32_t freq, int16_t rssi_threshold, uint32_t max_carrier_sense_time)
Perform carrier sensing.
virtual void init_radio(radio_events_t *events)
Registers radio events with the Mbed LoRaWAN stack and undergoes initialization steps if any.
virtual void sleep(void)
Put the RF module in sleep mode.
virtual void standby(void)
Sets the radio in standby mode.
virtual void radio_reset()
Resets the radio module.
virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time)
Sets the radio in continuous wave transmission mode.
virtual uint32_t random(void)
Generates a 32 bits random value based on the RSSI readings.
virtual void lock(void)
Acquire exclusive access.
virtual void set_max_payload_length(radio_modems_t modem, uint8_t max)
Sets the maximum payload length.
virtual void start_cad(void)
Sets the radio in CAD mode.
A digital input/output, used for setting or reading a bi-directional pin.
Definition: DigitalInOut.h:40
A digital output, used for setting the state of a pin.
Definition: DigitalOut.h:55
A digital interrupt input, used to call a function on a rising or falling edge.
Definition: InterruptIn.h:65
An SPI Master, used for communicating with SPI slave devices.
Definition: SPI.h:263
The Mutex class is used to synchronize the execution of threads.
Definition: Mutex.h:70
The Thread class allow defining, creating, and controlling thread functions in the system.
Definition: Thread.h:92
enum radio_state radio_state_t
Radio driver internal state.
enum modem_type radio_modems_t
Type of modem.
Reporting functions for upper layers.
Definition: LoRaRadio.h:390
Global radio settings.
Definition: LoRaRadio.h:348
Structure to hold RF controls for LoRa Radio.
Definition: LoRaRadio.h:36