1 /*!
2  * \file      sx1276.h
3  *
4  * \brief     SX1276 driver implementation
5  *
6  * \copyright Revised BSD License, see section \ref LICENSE.
7  *
8  * \code
9  *                ______                              _
10  *               / _____)             _              | |
11  *              ( (____  _____ ____ _| |_ _____  ____| |__
12  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
13  *               _____) ) ____| | | || |_| ____( (___| | | |
14  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
15  *              (C)2013-2017 Semtech
16  *
17  * \endcode
18  *
19  * \author    Miguel Luis ( Semtech )
20  *
21  * \author    Gregory Cristian ( Semtech )
22  */
23 #ifndef __SX1276_H__
24 #define __SX1276_H__
25 
26 #ifdef __cplusplus
27 extern "C"
28 {
29 #endif
30 
31 #include <stdint.h>
32 #include <stdbool.h>
33 #include "gpio.h"
34 #include "spi.h"
35 #include "radio.h"
36 #include "sx1276Regs-Fsk.h"
37 #include "sx1276Regs-LoRa.h"
38 
39 /*!
40  * Radio wake-up time from sleep
41  */
42 #define RADIO_WAKEUP_TIME                           1 // [ms]
43 
44 /*!
45  * Sync word for Private LoRa networks
46  */
47 #define LORA_MAC_PRIVATE_SYNCWORD                   0x12
48 
49 /*!
50  * Sync word for Public LoRa networks
51  */
52 #define LORA_MAC_PUBLIC_SYNCWORD                    0x34
53 
54 /*!
55  * Radio FSK modem parameters
56  */
57 typedef struct
58 {
59     int8_t   Power;
60     uint32_t Fdev;
61     uint32_t Bandwidth;
62     uint32_t BandwidthAfc;
63     uint32_t Datarate;
64     uint16_t PreambleLen;
65     bool     FixLen;
66     uint8_t  PayloadLen;
67     bool     CrcOn;
68     bool     IqInverted;
69     bool     RxContinuous;
70     uint32_t TxTimeout;
71     uint32_t RxSingleTimeout;
72 }RadioFskSettings_t;
73 
74 /*!
75  * Radio FSK packet handler state
76  */
77 typedef struct
78 {
79     uint8_t  PreambleDetected;
80     uint8_t  SyncWordDetected;
81     int8_t   RssiValue;
82     int32_t  AfcValue;
83     uint8_t  RxGain;
84     uint16_t Size;
85     uint16_t NbBytes;
86     uint8_t  FifoThresh;
87     uint8_t  ChunkSize;
88 }RadioFskPacketHandler_t;
89 
90 /*!
91  * Radio LoRa modem parameters
92  */
93 typedef struct
94 {
95     int8_t   Power;
96     uint32_t Bandwidth;
97     uint32_t Datarate;
98     bool     LowDatarateOptimize;
99     uint8_t  Coderate;
100     uint16_t PreambleLen;
101     bool     FixLen;
102     uint8_t  PayloadLen;
103     bool     CrcOn;
104     bool     FreqHopOn;
105     uint8_t  HopPeriod;
106     bool     IqInverted;
107     bool     RxContinuous;
108     uint32_t TxTimeout;
109     bool     PublicNetwork;
110 }RadioLoRaSettings_t;
111 
112 /*!
113  * Radio LoRa packet handler state
114  */
115 typedef struct
116 {
117     int8_t SnrValue;
118     int16_t RssiValue;
119     uint8_t Size;
120 }RadioLoRaPacketHandler_t;
121 
122 /*!
123  * Radio Settings
124  */
125 typedef struct
126 {
127     RadioState_t             State;
128     RadioModems_t            Modem;
129     uint32_t                 Channel;
130     RadioFskSettings_t       Fsk;
131     RadioFskPacketHandler_t  FskPacketHandler;
132     RadioLoRaSettings_t      LoRa;
133     RadioLoRaPacketHandler_t LoRaPacketHandler;
134 }RadioSettings_t;
135 
136 /*!
137  * Radio hardware and global parameters
138  */
139 typedef struct SX1276_s
140 {
141     Gpio_t        Reset;
142     Gpio_t        DIO0;
143     Gpio_t        DIO1;
144     Gpio_t        DIO2;
145     Gpio_t        DIO3;
146     Gpio_t        DIO4;
147     Gpio_t        DIO5;
148     Spi_t         Spi;
149     RadioSettings_t Settings;
150 }SX1276_t;
151 
152 /*!
153  * Hardware IO IRQ callback function definition
154  */
155 typedef void ( DioIrqHandler )( void* context );
156 
157 /*
158  * SX1276 definitions
159  */
160 
161 /*!
162  * ============================================================================
163  * Public functions prototypes
164  * ============================================================================
165  */
166 
167 /*!
168  * \brief Initializes the radio
169  *
170  * \param [IN] events Structure containing the driver callback functions
171  */
172 void SX1276Init( RadioEvents_t *events );
173 
174 /*!
175  * Return current radio status
176  *
177  * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
178  */
179 RadioState_t SX1276GetStatus( void );
180 
181 /*!
182  * \brief Configures the radio with the given modem
183  *
184  * \param [IN] modem Modem to be used [0: FSK, 1: LoRa]
185  */
186 void SX1276SetModem( RadioModems_t modem );
187 
188 /*!
189  * \brief Sets the channel configuration
190  *
191  * \param [IN] freq         Channel RF frequency
192  */
193 void SX1276SetChannel( uint32_t freq );
194 
195 /*!
196  * \brief Checks if the channel is free for the given time
197  *
198  * \remark The FSK modem is always used for this task as we can select the Rx bandwidth at will.
199  *
200  * \param [IN] freq                Channel RF frequency in Hertz
201  * \param [IN] rxBandwidth         Rx bandwidth in Hertz
202  * \param [IN] rssiThresh          RSSI threshold in dBm
203  * \param [IN] maxCarrierSenseTime Max time in milliseconds while the RSSI is measured
204  *
205  * \retval isFree         [true: Channel is free, false: Channel is not free]
206  */
207 bool SX1276IsChannelFree( uint32_t freq, uint32_t rxBandwidth, int16_t rssiThresh, uint32_t maxCarrierSenseTime );
208 
209 /*!
210  * \brief Generates a 32 bits random value based on the RSSI readings
211  *
212  * \remark This function sets the radio in LoRa modem mode and disables
213  *         all interrupts.
214  *         After calling this function either SX1276SetRxConfig or
215  *         SX1276SetTxConfig functions must be called.
216  *
217  * \retval randomValue    32 bits random value
218  */
219 uint32_t SX1276Random( void );
220 
221 /*!
222  * \brief Sets the reception parameters
223  *
224  * \remark When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
225  *
226  * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
227  * \param [IN] bandwidth    Sets the bandwidth
228  *                          FSK : >= 2600 and <= 250000 Hz
229  *                          LoRa: [0: 125 kHz, 1: 250 kHz,
230  *                                 2: 500 kHz, 3: Reserved]
231  * \param [IN] datarate     Sets the Datarate
232  *                          FSK : 600..300000 bits/s
233  *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
234  *                                10: 1024, 11: 2048, 12: 4096  chips]
235  * \param [IN] coderate     Sets the coding rate (LoRa only)
236  *                          FSK : N/A ( set to 0 )
237  *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
238  * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only)
239  *                          FSK : >= 2600 and <= 250000 Hz
240  *                          LoRa: N/A ( set to 0 )
241  * \param [IN] preambleLen  Sets the Preamble length
242  *                          FSK : Number of bytes
243  *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
244  * \param [IN] symbTimeout  Sets the RxSingle timeout value
245  *                          FSK : timeout number of bytes
246  *                          LoRa: timeout in symbols
247  * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
248  * \param [IN] payloadLen   Sets payload length when fixed length is used
249  * \param [IN] crcOn        Enables/Disables the CRC [0: OFF, 1: ON]
250  * \param [IN] freqHopOn    Enables disables the intra-packet frequency hopping
251  *                          FSK : N/A ( set to 0 )
252  *                          LoRa: [0: OFF, 1: ON]
253  * \param [IN] hopPeriod    Number of symbols between each hop
254  *                          FSK : N/A ( set to 0 )
255  *                          LoRa: Number of symbols
256  * \param [IN] iqInverted   Inverts IQ signals (LoRa only)
257  *                          FSK : N/A ( set to 0 )
258  *                          LoRa: [0: not inverted, 1: inverted]
259  * \param [IN] rxContinuous Sets the reception in continuous mode
260  *                          [false: single mode, true: continuous mode]
261  */
262 void SX1276SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
263                          uint32_t datarate, uint8_t coderate,
264                          uint32_t bandwidthAfc, uint16_t preambleLen,
265                          uint16_t symbTimeout, bool fixLen,
266                          uint8_t payloadLen,
267                          bool crcOn, bool freqHopOn, uint8_t hopPeriod,
268                          bool iqInverted, bool rxContinuous );
269 
270 /*!
271  * \brief Sets the transmission parameters
272  *
273  * \remark When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
274  *
275  * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
276  * \param [IN] power        Sets the output power [dBm]
277  * \param [IN] fdev         Sets the frequency deviation (FSK only)
278  *                          FSK : [Hz]
279  *                          LoRa: 0
280  * \param [IN] bandwidth    Sets the bandwidth (LoRa only)
281  *                          FSK : 0
282  *                          LoRa: [0: 125 kHz, 1: 250 kHz,
283  *                                 2: 500 kHz, 3: Reserved]
284  * \param [IN] datarate     Sets the Datarate
285  *                          FSK : 600..300000 bits/s
286  *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
287  *                                10: 1024, 11: 2048, 12: 4096  chips]
288  * \param [IN] coderate     Sets the coding rate (LoRa only)
289  *                          FSK : N/A ( set to 0 )
290  *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
291  * \param [IN] preambleLen  Sets the preamble length
292  *                          FSK : Number of bytes
293  *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
294  * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
295  * \param [IN] crcOn        Enables disables the CRC [0: OFF, 1: ON]
296  * \param [IN] freqHopOn    Enables disables the intra-packet frequency hopping
297  *                          FSK : N/A ( set to 0 )
298  *                          LoRa: [0: OFF, 1: ON]
299  * \param [IN] hopPeriod    Number of symbols between each hop
300  *                          FSK : N/A ( set to 0 )
301  *                          LoRa: Number of symbols
302  * \param [IN] iqInverted   Inverts IQ signals (LoRa only)
303  *                          FSK : N/A ( set to 0 )
304  *                          LoRa: [0: not inverted, 1: inverted]
305  * \param [IN] timeout      Transmission timeout [ms]
306  */
307 void SX1276SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
308                         uint32_t bandwidth, uint32_t datarate,
309                         uint8_t coderate, uint16_t preambleLen,
310                         bool fixLen, bool crcOn, bool freqHopOn,
311                         uint8_t hopPeriod, bool iqInverted, uint32_t timeout );
312 
313 /*!
314  * \brief Computes the packet time on air in ms for the given payload
315  *
316  * \Remark Can only be called once SetRxConfig or SetTxConfig have been called
317  *
318  * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
319  * \param [IN] bandwidth    Sets the bandwidth
320  *                          FSK : >= 2600 and <= 250000 Hz
321  *                          LoRa: [0: 125 kHz, 1: 250 kHz,
322  *                                 2: 500 kHz, 3: Reserved]
323  * \param [IN] datarate     Sets the Datarate
324  *                          FSK : 600..300000 bits/s
325  *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
326  *                                10: 1024, 11: 2048, 12: 4096  chips]
327  * \param [IN] coderate     Sets the coding rate (LoRa only)
328  *                          FSK : N/A ( set to 0 )
329  *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
330  * \param [IN] preambleLen  Sets the Preamble length
331  *                          FSK : Number of bytes
332  *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
333  * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
334  * \param [IN] payloadLen   Sets payload length when fixed length is used
335  * \param [IN] crcOn        Enables/Disables the CRC [0: OFF, 1: ON]
336  *
337  * \retval airTime        Computed airTime (ms) for the given packet payload length
338  */
339 uint32_t SX1276GetTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
340                               uint32_t datarate, uint8_t coderate,
341                               uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
342                               bool crcOn );
343 
344 /*!
345  * \brief Sends the buffer of size. Prepares the packet to be sent and sets
346  *        the radio in transmission
347  *
348  * \param [IN]: buffer     Buffer pointer
349  * \param [IN]: size       Buffer size
350  */
351 void SX1276Send( uint8_t *buffer, uint8_t size );
352 
353 /*!
354  * \brief Sets the radio in sleep mode
355  */
356 void SX1276SetSleep( void );
357 
358 /*!
359  * \brief Sets the radio in standby mode
360  */
361 void SX1276SetStby( void );
362 
363 /*!
364  * \brief Sets the radio in reception mode for the given time
365  * \param [IN] timeout Reception timeout [ms] [0: continuous, others timeout]
366  */
367 void SX1276SetRx( uint32_t timeout );
368 
369 /*!
370  * \brief Start a Channel Activity Detection
371  */
372 void SX1276StartCad( void );
373 
374 /*!
375  * \brief Sets the radio in continuous wave transmission mode
376  *
377  * \param [IN]: freq       Channel RF frequency
378  * \param [IN]: power      Sets the output power [dBm]
379  * \param [IN]: time       Transmission mode timeout [s]
380  */
381 void SX1276SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time );
382 
383 /*!
384  * \brief Reads the current RSSI value
385  *
386  * \retval rssiValue Current RSSI value in [dBm]
387  */
388 int16_t SX1276ReadRssi( RadioModems_t modem );
389 
390 /*!
391  * \brief Writes the radio register at the specified address
392  *
393  * \param [IN]: addr Register address
394  * \param [IN]: data New register value
395  */
396 void SX1276Write( uint32_t addr, uint8_t data );
397 
398 /*!
399  * \brief Reads the radio register at the specified address
400  *
401  * \param [IN]: addr Register address
402  * \retval data Register value
403  */
404 uint8_t SX1276Read( uint32_t addr );
405 
406 /*!
407  * \brief Writes multiple radio registers starting at address
408  *
409  * \param [IN] addr   First Radio register address
410  * \param [IN] buffer Buffer containing the new register's values
411  * \param [IN] size   Number of registers to be written
412  */
413 void SX1276WriteBuffer( uint32_t addr, uint8_t *buffer, uint8_t size );
414 
415 /*!
416  * \brief Reads multiple radio registers starting at address
417  *
418  * \param [IN] addr First Radio register address
419  * \param [OUT] buffer Buffer where to copy the registers data
420  * \param [IN] size Number of registers to be read
421  */
422 void SX1276ReadBuffer( uint32_t addr, uint8_t *buffer, uint8_t size );
423 
424 /*!
425  * \brief Sets the maximum payload length.
426  *
427  * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
428  * \param [IN] max        Maximum payload length in bytes
429  */
430 void SX1276SetMaxPayloadLength( RadioModems_t modem, uint8_t max );
431 
432 /*!
433  * \brief Sets the network to public or private. Updates the sync byte.
434  *
435  * \remark Applies to LoRa modem only
436  *
437  * \param [IN] enable if true, it enables a public network
438  */
439 void SX1276SetPublicNetwork( bool enable );
440 
441 /*!
442  * \brief Gets the time required for the board plus radio to get out of sleep.[ms]
443  *
444  * \retval time Radio plus board wakeup time in ms.
445  */
446 uint32_t SX1276GetWakeupTime( void );
447 
448 #ifdef __cplusplus
449 }
450 #endif
451 
452 #endif // __SX1276_H__
453