Mistake on this page?
Report an issue in GitHub or email us
SX1276_LoRaRadio.h
1 /**
2  / _____) _ | |
3 ( (____ _____ ____ _| |_ _____ ____| |__
4  \____ \| ___ | (_ _) ___ |/ ___) _ \
5  _____) ) ____| | | || |_| ____( (___| | | |
6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
7  (C)2013 Semtech
8  ___ _____ _ ___ _ _____ ___ ___ ___ ___
9 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
10 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
11 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
12 embedded.connectivity.solutions===============
13 
14 Description: LoRaWAN stack layer that controls both MAC and PHY underneath
15 
16 License: Revised BSD License, see LICENSE.TXT file include in the project
17 
18 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
19 
20 
21 Copyright (c) 2017, Arm Limited and affiliates.
22 
23 SPDX-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 "platform/PlatformMutex.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  */
61 class SX1276_LoRaRadio: public LoRaRadio {
62 public:
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  */
106  virtual ~SX1276_LoRaRadio();
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  /**
132  * Sets the reception parameters
133  *
134  * @param modem Radio modem to be used [0: FSK, 1: LoRa]
135  * @param bandwidth Sets the bandwidth
136  * FSK : >= 2600 and <= 250000 Hz
137  * LoRa: [0: 125 kHz, 1: 250 kHz,
138  * 2: 500 kHz, 3: Reserved]
139  * @param datarate Sets the Datarate
140  * FSK : 600..300000 bits/s
141  * LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
142  * 10: 1024, 11: 2048, 12: 4096 chips]
143  * @param coderate Sets the coding rate ( LoRa only )
144  * FSK : N/A ( set to 0 )
145  * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
146  * @param bandwidth_afc Sets the AFC Bandwidth ( FSK only )
147  * FSK : >= 2600 and <= 250000 Hz
148  * LoRa: N/A ( set to 0 )
149  * @param preamble_len Sets the Preamble length ( LoRa only )
150  * FSK : N/A ( set to 0 )
151  * LoRa: Length in symbols ( the hardware adds 4 more symbols )
152  * @param symb_timeout Sets the RxSingle timeout value
153  * FSK : timeout number of bytes
154  * LoRa: timeout in symbols
155  * @param fixLen Fixed length packets [0: variable, 1: fixed]
156  * @param payload_len Sets payload length when fixed lenght is used
157  * @param crc_on Enables/Disables the CRC [0: OFF, 1: ON]
158  * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only)
159  * @param hop_period Number of symbols bewteen each hop (LoRa only)
160  * @param iq_inverted Inverts IQ signals ( LoRa only )
161  * FSK : N/A ( set to 0 )
162  * LoRa: [0: not inverted, 1: inverted]
163  * @param rx_continuous Sets the reception in continuous mode
164  * [false: single mode, true: continuous mode]
165  */
166  virtual void set_rx_config(radio_modems_t modem, uint32_t bandwidth,
167  uint32_t datarate, uint8_t coderate,
168  uint32_t bandwidth_afc, uint16_t preamble_len,
169  uint16_t symb_timeout, bool fix_len,
170  uint8_t payload_len,
171  bool crc_on, bool freq_hop_on, uint8_t hop_period,
172  bool iq_inverted, bool rx_continuous);
173 
174  /**
175  * Sets the transmission parameters
176  *
177  * @param modem Radio modem to be used [0: FSK, 1: LoRa]
178  * @param power Sets the output power [dBm]
179  * @param fdev Sets the frequency deviation ( FSK only )
180  * FSK : [Hz]
181  * LoRa: 0
182  * @param bandwidth Sets the bandwidth ( LoRa only )
183  * FSK : 0
184  * LoRa: [0: 125 kHz, 1: 250 kHz,
185  * 2: 500 kHz, 3: Reserved]
186  * @param datarate Sets the Datarate
187  * FSK : 600..300000 bits/s
188  * LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
189  * 10: 1024, 11: 2048, 12: 4096 chips]
190  * @param coderate Sets the coding rate ( LoRa only )
191  * FSK : N/A ( set to 0 )
192  * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
193  * @param preamble_len Sets the preamble length
194  * @param fix_len Fixed length packets [0: variable, 1: fixed]
195  * @param crc_on Enables disables the CRC [0: OFF, 1: ON]
196  * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only)
197  * @param hop_period Number of symbols bewteen each hop (LoRa only)
198  * @param iq_inverted Inverts IQ signals ( LoRa only )
199  * FSK : N/A ( set to 0 )
200  * LoRa: [0: not inverted, 1: inverted]
201  * @param timeout Transmission timeout [ms]
202  */
203  virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev,
204  uint32_t bandwidth, uint32_t datarate,
205  uint8_t coderate, uint16_t preamble_len,
206  bool fix_len, bool crc_on, bool freq_hop_on,
207  uint8_t hop_period, bool iq_inverted, uint32_t timeout);
208 
209  /**
210  * Sends the buffer of size
211  *
212  * Prepares the packet to be sent and sets the radio in transmission
213  *
214  * @param buffer Buffer pointer
215  * @param size Buffer size
216  */
217  virtual void send(uint8_t *buffer, uint8_t size);
218 
219  /**
220  * For backwards compatibility
221  */
222  virtual void receive(uint32_t timeout)
223  {
224  (void) timeout;
225  receive();
226  }
227 
228  /**
229  * Sets the radio to receive
230  *
231  * All necessary configuration options for reception are set in
232  * 'set_rx_config(parameters)' API.
233  */
234  virtual void receive(void);
235 
236  /**
237  * Sets the carrier frequency
238  *
239  * @param freq Channel RF frequency
240  */
241  virtual void set_channel(uint32_t freq);
242 
243  /**
244  * Generates a 32 bits random value based on the RSSI readings
245  *
246  * Remark this function sets the radio in LoRa modem mode and disables
247  * all interrupts.
248  * After calling this function either Radio.SetRxConfig or
249  * Radio.SetTxConfig functions must be called.
250  *
251  * @return 32 bits random value
252  */
253  virtual uint32_t random(void);
254 
255  /**
256  * Get radio status
257  *
258  * @param status Radio status [RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
259  * @return Return current radio status
260  */
261  virtual uint8_t get_status(void);
262 
263  /**
264  * Sets the maximum payload length
265  *
266  * @param modem Radio modem to be used [0: FSK, 1: LoRa]
267  * @param max Maximum payload length in bytes
268  */
269  virtual void set_max_payload_length(radio_modems_t modem, uint8_t max);
270 
271  /**
272  * Sets the network to public or private
273  *
274  * Updates the sync byte. Applies to LoRa modem only
275  *
276  * @param enable if true, it enables a public network
277  */
278  virtual void set_public_network(bool enable);
279 
280  /**
281  * Computes the packet time on air for the given payload
282  *
283  * Remark can only be called once SetRxConfig or SetTxConfig have been called
284  *
285  * @param modem Radio modem to be used [0: FSK, 1: LoRa]
286  * @param pkt_len Packet payload length
287  * @return Computed airTime for the given packet payload length
288  */
289  virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len);
290 
291  /**
292  * Perform carrier sensing
293  *
294  * Checks for a certain time if the RSSI is above a given threshold.
295  * This threshold determines if there is already a transmission going on
296  * in the channel or not.
297  *
298  * @param modem Type of the radio modem
299  * @param freq Carrier frequency
300  * @param rssi_threshold Threshold value of RSSI
301  * @param max_carrier_sense_time time to sense the channel
302  *
303  * @return true if there is no active transmission
304  * in the channel, false otherwise
305  */
306  virtual bool perform_carrier_sense(radio_modems_t modem,
307  uint32_t freq,
308  int16_t rssi_threshold,
309  uint32_t max_carrier_sense_time);
310 
311  /**
312  * Sets the radio in CAD mode
313  *
314  */
315  virtual void start_cad(void);
316 
317  /**
318  * Check if the given RF is in range
319  *
320  * @param frequency frequency needed to be checked
321  */
322  virtual bool check_rf_frequency(uint32_t frequency);
323 
324  /** Sets the radio in continuous wave transmission mode
325  *
326  * @param freq Channel RF frequency
327  * @param power Sets the output power [dBm]
328  * @param time Transmission mode timeout [s]
329  */
330  virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time);
331 
332  /**
333  * Acquire exclusive access
334  */
335  virtual void lock(void);
336 
337  /**
338  * Release exclusive access
339  */
340  virtual void unlock(void);
341 
342 private:
343 
344  // SPI and chip select control
345  mbed::SPI _spi;
346  mbed::DigitalOut _chip_select;
347 
348  // module rest control
349  mbed::DigitalInOut _reset_ctl;
350 
351  // Interrupt controls
352  mbed::InterruptIn _dio0_ctl;
353  mbed::InterruptIn _dio1_ctl;
354  mbed::InterruptIn _dio2_ctl;
355  mbed::InterruptIn _dio3_ctl;
356  mbed::InterruptIn _dio4_ctl;
357  mbed::InterruptIn _dio5_ctl;
358 
359  // Radio specific controls
360  mbed::DigitalOut _rf_switch_ctl1;
361  mbed::DigitalOut _rf_switch_ctl2;
362  mbed::DigitalOut _txctl;
363  mbed::DigitalOut _rxctl;
364  mbed::DigitalInOut _ant_switch;
365  mbed::DigitalOut _pwr_amp_ctl;
366  mbed::DigitalOut _tcxo;
367 
368  // Contains all RF control pin names
369  // This storage is needed even after assigning the
370  // pins to corresponding object, as the driver needs to know
371  // which control pins are connected and which are not. This
372  // variation is inherent to driver because of target configuration.
373  rf_ctrls _rf_ctrls;
374 
375  // We need these PinNames as not all modules have those connected
376  PinName _dio4_pin;
377  PinName _dio5_pin;
378 
379  // Structure containing all user and network specified settings
380  // for radio module
381  radio_settings_t _rf_settings;
382 
383  // Structure containing function pointers to the stack callbacks
384  radio_events_t *_radio_events;
385 
386  // Data buffer used for both TX and RX
387  // Size of this buffer is configurable via Mbed config system
388  // Default is 255 bytes
389  uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX1276];
390 
391  // TX timer in ms. This timer is used as a fail safe for TX.
392  // If the chip fails to transmit, its a fatal error, reflecting
393  // some catastrophic bus failure etc. We wish to have the control
394  // back from the driver in such a case.
395  ALIAS_LORAWAN_TIMER tx_timeout_timer;
396 
397 #ifdef MBED_CONF_RTOS_PRESENT
398  // Thread to handle interrupts
399  rtos::Thread irq_thread;
400 #endif
401 
402  // Access protection
403  PlatformMutex mutex;
404 
405  uint8_t radio_variant;
406 
407  // helper functions
408  void setup_registers();
409  void default_antenna_switch_ctrls();
410  void set_antenna_switch(uint8_t operation_mode);
411  void setup_spi();
412  void gpio_init();
413  void gpio_deinit();
414  void setup_interrupts();
415  void set_operation_mode(uint8_t operation_mode);
416  void set_low_power_mode();
417  void set_sx1276_variant_type();
418  uint8_t get_pa_conf_reg(uint32_t channel);
419  void set_rf_tx_power(int8_t power);
420  int16_t get_rssi(radio_modems_t modem);
421  uint8_t get_fsk_bw_reg_val(uint32_t bandwidth);
422  void write_to_register(uint8_t addr, uint8_t data);
423  void write_to_register(uint8_t addr, uint8_t *data, uint8_t size);
424  uint8_t read_register(uint8_t addr);
425  void read_register(uint8_t addr, uint8_t *buffer, uint8_t size);
426  void write_fifo(uint8_t *buffer, uint8_t size);
427  void read_fifo(uint8_t *buffer, uint8_t size);
428  void transmit(uint32_t timeout);
429  void rf_irq_task(void);
430  void set_modem(uint8_t modem);
431  void rx_chain_calibration(void);
432 
433  // ISRs
434  void dio0_irq_isr();
435  void dio1_irq_isr();
436  void dio2_irq_isr();
437  void dio3_irq_isr();
438  void dio4_irq_isr();
439  void dio5_irq_isr();
440  void timeout_irq_isr();
441 
442  // Handlers called by thread in response to signal
443  void handle_dio0_irq();
444  void handle_dio1_irq();
445  void handle_dio2_irq();
446  void handle_dio3_irq();
447  void handle_dio4_irq();
448  void handle_dio5_irq();
449  void handle_timeout_irq();
450 };
451 
452 #endif // DEVICE_SPI
453 
454 #endif // SX1276_LORARADIO_H_
The Thread class allow defining, creating, and controlling thread functions in the system...
Definition: Thread.h:92
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 set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time)
Sets the radio in continuous wave transmission mode.
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 void start_cad(void)
Sets the radio in CAD mode.
enum modem_type radio_modems_t
Type of modem.
Structure to hold RF controls for LoRa Radio.
Definition: LoRaRadio.h:35
virtual void receive(uint32_t timeout)
For backwards compatibility.
virtual bool check_rf_frequency(uint32_t frequency)
Check if the given RF is in range.
virtual void unlock(void)
Release exclusive access.
virtual void standby(void)
Sets the radio in standby mode.
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.
A digital input/output, used for setting or reading a bi-directional pin.
Definition: DigitalInOut.h:36
virtual void radio_reset()
Resets the radio module.
The PlatformMutex class is used to synchronize the execution of threads.
Definition: PlatformMutex.h:47
virtual void set_max_payload_length(radio_modems_t modem, uint8_t max)
Sets the maximum payload length.
virtual void set_public_network(bool enable)
Sets the network to public or private.
virtual void set_channel(uint32_t freq)
Sets the carrier frequency.
Reporting functions for upper layers.
Definition: LoRaRadio.h:389
virtual ~SX1276_LoRaRadio()
Destructor.
virtual void send(uint8_t *buffer, uint8_t size)
Sends the buffer of size.
virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len)
Computes the packet time on air for the given payload.
virtual uint32_t random(void)
Generates a 32 bits random value based on the RSSI readings.
virtual uint8_t get_status(void)
Get radio status.
A digital interrupt input, used to call a function on a rising or falling edge.
Definition: InterruptIn.h:65
A digital output, used for setting the state of a pin.
Definition: DigitalOut.h:51
virtual 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)
Sets the reception parameters.
A SPI Master, used for communicating with SPI slave devices.
Definition: SPI.h:98
virtual void init_radio(radio_events_t *events)
Registers radio events with the Mbed LoRaWAN stack and undergoes initialization steps if any...
Global radio settings.
Definition: LoRaRadio.h:347
virtual void lock(void)
Acquire exclusive access.
virtual void sleep(void)
Put the RF module in sleep mode.
Radio driver implementation for Semtech SX1272 plus variants.
Interface for the radios, containing the main functions that a radio needs, and five callback functio...
Definition: LoRaRadio.h:440
virtual void receive(void)
Sets the radio to receive.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.