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