1 /*!
2  * \file      radio.h
3  *
4  * \brief     Radio driver API definition
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 __RADIO_H__
24 #define __RADIO_H__
25 
26 #ifdef __cplusplus
27 extern "C"
28 {
29 #endif
30 
31 #include <stdint.h>
32 #include <stdbool.h>
33 
34 /*!
35  * Radio driver supported modems
36  */
37 typedef enum
38 {
39     MODEM_FSK = 0,
40     MODEM_LORA,
41 }RadioModems_t;
42 
43 /*!
44  * Radio driver internal state machine states definition
45  */
46 typedef enum
47 {
48     RF_IDLE = 0,   //!< The radio is idle
49     RF_RX_RUNNING, //!< The radio is in reception state
50     RF_TX_RUNNING, //!< The radio is in transmission state
51     RF_CAD,        //!< The radio is doing channel activity detection
52 }RadioState_t;
53 
54 /*!
55  * \brief Radio driver callback functions
56  */
57 typedef struct
58 {
59     /*!
60      * \brief  Tx Done callback prototype.
61      */
62     void    ( *TxDone )( void );
63     /*!
64      * \brief  Tx Timeout callback prototype.
65      */
66     void    ( *TxTimeout )( void );
67     /*!
68      * \brief Rx Done callback prototype.
69      *
70      * \param [IN] payload Received buffer pointer
71      * \param [IN] size    Received buffer size
72      * \param [IN] rssi    RSSI value computed while receiving the frame [dBm]
73      * \param [IN] snr     SNR value computed while receiving the frame [dB]
74      *                     FSK : N/A ( set to 0 )
75      *                     LoRa: SNR value in dB
76      */
77     void    ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
78     /*!
79      * \brief  Rx Timeout callback prototype.
80      */
81     void    ( *RxTimeout )( void );
82     /*!
83      * \brief Rx Error callback prototype.
84      */
85     void    ( *RxError )( void );
86     /*!
87      * \brief  FHSS Change Channel callback prototype.
88      *
89      * \param [IN] currentChannel   Index number of the current channel
90      */
91     void ( *FhssChangeChannel )( uint8_t currentChannel );
92 
93     /*!
94      * \brief CAD Done callback prototype.
95      *
96      * \param [IN] channelDetected    Channel Activity detected during the CAD
97      */
98     void ( *CadDone ) ( bool channelActivityDetected );
99 
100     /*!
101      * \brief  Gnss Done Done callback prototype.
102     */
103     void    ( *GnssDone )( void );
104 
105     /*!
106      * \brief  Gnss Done Done callback prototype.
107     */
108     void    ( *WifiDone )( void );
109 }RadioEvents_t;
110 
111 /*!
112  * \brief Radio driver definition
113  */
114 struct Radio_s
115 {
116     /*!
117      * \brief Initializes the radio
118      *
119      * \param [IN] events Structure containing the driver callback functions
120      */
121     void    ( *Init )( RadioEvents_t *events );
122     /*!
123      * Return current radio status
124      *
125      * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
126      */
127     RadioState_t ( *GetStatus )( void );
128     /*!
129      * \brief Configures the radio with the given modem
130      *
131      * \param [IN] modem Modem to be used [0: FSK, 1: LoRa]
132      */
133     void    ( *SetModem )( RadioModems_t modem );
134     /*!
135      * \brief Sets the channel frequency
136      *
137      * \param [IN] freq         Channel RF frequency
138      */
139     void    ( *SetChannel )( uint32_t freq );
140     /*!
141      * \brief Checks if the channel is free for the given time
142      *
143      * \remark The FSK modem is always used for this task as we can select the Rx bandwidth at will.
144      *
145      * \param [IN] freq                Channel RF frequency in Hertz
146      * \param [IN] rxBandwidth         Rx bandwidth in Hertz
147      * \param [IN] rssiThresh          RSSI threshold in dBm
148      * \param [IN] maxCarrierSenseTime Max time in milliseconds while the RSSI is measured
149      *
150      * \retval isFree         [true: Channel is free, false: Channel is not free]
151      */
152     bool    ( *IsChannelFree )( uint32_t freq, uint32_t rxBandwidth, int16_t rssiThresh, uint32_t maxCarrierSenseTime );
153     /*!
154      * \brief Generates a 32 bits random value based on the RSSI readings
155      *
156      * \remark This function sets the radio in LoRa modem mode and disables
157      *         all interrupts.
158      *         After calling this function either Radio.SetRxConfig or
159      *         Radio.SetTxConfig functions must be called.
160      *
161      * \retval randomValue    32 bits random value
162      */
163     uint32_t ( *Random )( void );
164     /*!
165      * \brief Sets the reception parameters
166      *
167      * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
168      * \param [IN] bandwidth    Sets the bandwidth
169      *                          FSK : >= 2600 and <= 250000 Hz
170      *                          LoRa: [0: 125 kHz, 1: 250 kHz,
171      *                                 2: 500 kHz, 3: Reserved]
172      * \param [IN] datarate     Sets the Datarate
173      *                          FSK : 600..300000 bits/s
174      *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
175      *                                10: 1024, 11: 2048, 12: 4096  chips]
176      * \param [IN] coderate     Sets the coding rate (LoRa only)
177      *                          FSK : N/A ( set to 0 )
178      *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
179      * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only)
180      *                          FSK : >= 2600 and <= 250000 Hz
181      *                          LoRa: N/A ( set to 0 )
182      * \param [IN] preambleLen  Sets the Preamble length
183      *                          FSK : Number of bytes
184      *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
185      * \param [IN] symbTimeout  Sets the RxSingle timeout value
186      *                          FSK : timeout in number of bytes
187      *                          LoRa: timeout in symbols
188      * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
189      * \param [IN] payloadLen   Sets payload length when fixed length is used
190      * \param [IN] crcOn        Enables/Disables the CRC [0: OFF, 1: ON]
191      * \param [IN] freqHopOn    Enables disables the intra-packet frequency hopping
192      *                          FSK : N/A ( set to 0 )
193      *                          LoRa: [0: OFF, 1: ON]
194      * \param [IN] hopPeriod    Number of symbols between each hop
195      *                          FSK : N/A ( set to 0 )
196      *                          LoRa: Number of symbols
197      * \param [IN] iqInverted   Inverts IQ signals (LoRa only)
198      *                          FSK : N/A ( set to 0 )
199      *                          LoRa: [0: not inverted, 1: inverted]
200      * \param [IN] rxContinuous Sets the reception in continuous mode
201      *                          [false: single mode, true: continuous mode]
202      */
203     void    ( *SetRxConfig )( RadioModems_t modem, uint32_t bandwidth,
204                               uint32_t datarate, uint8_t coderate,
205                               uint32_t bandwidthAfc, uint16_t preambleLen,
206                               uint16_t symbTimeout, bool fixLen,
207                               uint8_t payloadLen,
208                               bool crcOn, bool freqHopOn, uint8_t hopPeriod,
209                               bool iqInverted, bool rxContinuous );
210     /*!
211      * \brief Sets the transmission parameters
212      *
213      * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
214      * \param [IN] power        Sets the output power [dBm]
215      * \param [IN] fdev         Sets the frequency deviation (FSK only)
216      *                          FSK : [Hz]
217      *                          LoRa: 0
218      * \param [IN] bandwidth    Sets the bandwidth (LoRa only)
219      *                          FSK : 0
220      *                          LoRa: [0: 125 kHz, 1: 250 kHz,
221      *                                 2: 500 kHz, 3: Reserved]
222      * \param [IN] datarate     Sets the Datarate
223      *                          FSK : 600..300000 bits/s
224      *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
225      *                                10: 1024, 11: 2048, 12: 4096  chips]
226      * \param [IN] coderate     Sets the coding rate (LoRa only)
227      *                          FSK : N/A ( set to 0 )
228      *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
229      * \param [IN] preambleLen  Sets the preamble length
230      *                          FSK : Number of bytes
231      *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
232      * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
233      * \param [IN] crcOn        Enables disables the CRC [0: OFF, 1: ON]
234      * \param [IN] freqHopOn    Enables disables the intra-packet frequency hopping
235      *                          FSK : N/A ( set to 0 )
236      *                          LoRa: [0: OFF, 1: ON]
237      * \param [IN] hopPeriod    Number of symbols between each hop
238      *                          FSK : N/A ( set to 0 )
239      *                          LoRa: Number of symbols
240      * \param [IN] iqInverted   Inverts IQ signals (LoRa only)
241      *                          FSK : N/A ( set to 0 )
242      *                          LoRa: [0: not inverted, 1: inverted]
243      * \param [IN] timeout      Transmission timeout [ms]
244      */
245     void    ( *SetTxConfig )( RadioModems_t modem, int8_t power, uint32_t fdev,
246                               uint32_t bandwidth, uint32_t datarate,
247                               uint8_t coderate, uint16_t preambleLen,
248                               bool fixLen, bool crcOn, bool freqHopOn,
249                               uint8_t hopPeriod, bool iqInverted, uint32_t timeout );
250     /*!
251      * \brief Checks if the given RF frequency is supported by the hardware
252      *
253      * \param [IN] frequency RF frequency to be checked
254      * \retval isSupported [true: supported, false: unsupported]
255      */
256     bool    ( *CheckRfFrequency )( uint32_t frequency );
257     /*!
258      * \brief Computes the packet time on air in ms for the given payload
259      *
260      * \Remark Can only be called once SetRxConfig or SetTxConfig have been called
261      *
262      * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
263      * \param [IN] bandwidth    Sets the bandwidth
264      *                          FSK : >= 2600 and <= 250000 Hz
265      *                          LoRa: [0: 125 kHz, 1: 250 kHz,
266      *                                 2: 500 kHz, 3: Reserved]
267      * \param [IN] datarate     Sets the Datarate
268      *                          FSK : 600..300000 bits/s
269      *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
270      *                                10: 1024, 11: 2048, 12: 4096  chips]
271      * \param [IN] coderate     Sets the coding rate (LoRa only)
272      *                          FSK : N/A ( set to 0 )
273      *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
274      * \param [IN] preambleLen  Sets the Preamble length
275      *                          FSK : Number of bytes
276      *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
277      * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
278      * \param [IN] payloadLen   Sets payload length when fixed length is used
279      * \param [IN] crcOn        Enables/Disables the CRC [0: OFF, 1: ON]
280      *
281      * \retval airTime        Computed airTime (ms) for the given packet payload length
282      */
283     uint32_t  ( *TimeOnAir )( RadioModems_t modem, uint32_t bandwidth,
284                               uint32_t datarate, uint8_t coderate,
285                               uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
286                               bool crcOn );
287     /*!
288      * \brief Sends the buffer of size. Prepares the packet to be sent and sets
289      *        the radio in transmission
290      *
291      * \param [IN]: buffer     Buffer pointer
292      * \param [IN]: size       Buffer size
293      */
294     void    ( *Send )( uint8_t *buffer, uint8_t size );
295     /*!
296      * \brief Sets the radio in sleep mode
297      */
298     void    ( *Sleep )( void );
299     /*!
300      * \brief Sets the radio in standby mode
301      */
302     void    ( *Standby )( void );
303     /*!
304      * \brief Sets the radio in reception mode for the given time
305      * \param [IN] timeout Reception timeout [ms]
306      *                     [0: continuous, others timeout]
307      */
308     void    ( *Rx )( uint32_t timeout );
309     /*!
310      * \brief Start a Channel Activity Detection
311      */
312     void    ( *StartCad )( void );
313     /*!
314      * \brief Sets the radio in continuous wave transmission mode
315      *
316      * \param [IN]: freq       Channel RF frequency
317      * \param [IN]: power      Sets the output power [dBm]
318      * \param [IN]: time       Transmission mode timeout [s]
319      */
320     void    ( *SetTxContinuousWave )( uint32_t freq, int8_t power, uint16_t time );
321     /*!
322      * \brief Reads the current RSSI value
323      *
324      * \retval rssiValue Current RSSI value in [dBm]
325      */
326     int16_t ( *Rssi )( RadioModems_t modem );
327     /*!
328      * \brief Writes the radio register at the specified address
329      *
330      * \param [IN]: addr Register address
331      * \param [IN]: data New register value
332      */
333     void    ( *Write )( uint32_t addr, uint8_t data );
334     /*!
335      * \brief Reads the radio register at the specified address
336      *
337      * \param [IN]: addr Register address
338      * \retval data Register value
339      */
340     uint8_t ( *Read )( uint32_t addr );
341     /*!
342      * \brief Writes multiple radio registers starting at address
343      *
344      * \param [IN] addr   First Radio register address
345      * \param [IN] buffer Buffer containing the new register's values
346      * \param [IN] size   Number of registers to be written
347      */
348     void    ( *WriteBuffer )( uint32_t addr, uint8_t *buffer, uint8_t size );
349     /*!
350      * \brief Reads multiple radio registers starting at address
351      *
352      * \param [IN] addr First Radio register address
353      * \param [OUT] buffer Buffer where to copy the registers data
354      * \param [IN] size Number of registers to be read
355      */
356     void    ( *ReadBuffer )( uint32_t addr, uint8_t *buffer, uint8_t size );
357     /*!
358      * \brief Sets the maximum payload length.
359      *
360      * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
361      * \param [IN] max        Maximum payload length in bytes
362      */
363     void    ( *SetMaxPayloadLength )( RadioModems_t modem, uint8_t max );
364     /*!
365      * \brief Sets the network to public or private. Updates the sync byte.
366      *
367      * \remark Applies to LoRa modem only
368      *
369      * \param [IN] enable if true, it enables a public network
370      */
371     void    ( *SetPublicNetwork )( bool enable );
372     /*!
373      * \brief Gets the time required for the board plus radio to get out of sleep.[ms]
374      *
375      * \retval time Radio plus board wakeup time in ms.
376      */
377     uint32_t  ( *GetWakeupTime )( void );
378     /*!
379      * \brief Process radio irq
380      */
381     void ( *IrqProcess )( void );
382     /*
383      * The next functions are available only on SX126x radios.
384      */
385     /*!
386      * \brief Sets the radio in reception mode with Max LNA gain for the given time
387      *
388      * \remark Available on SX126x radios only.
389      *
390      * \param [IN] timeout Reception timeout [ms]
391      *                     [0: continuous, others timeout]
392      */
393     void    ( *RxBoosted )( uint32_t timeout );
394     /*!
395      * \brief Sets the Rx duty cycle management parameters
396      *
397      * \remark Available on SX126x radios only.
398      *
399      * \param [in]  rxTime        Structure describing reception timeout value
400      * \param [in]  sleepTime     Structure describing sleep timeout value
401      */
402     void ( *SetRxDutyCycle ) ( uint32_t rxTime, uint32_t sleepTime );
403 };
404 
405 /*!
406  * \brief Radio driver
407  *
408  * \remark This variable is defined and initialized in the specific radio
409  *         board implementation
410  */
411 extern const struct Radio_s Radio;
412 
413 #ifdef __cplusplus
414 }
415 #endif
416 
417 #endif // __RADIO_H__
418