SX1278 RA-01, RA-02 LoRa library

  1. This code is deprecated. Use this: https://github.com/luk6xff/DevLibs/tree/master/LORA instead.
Committer:
igbt6
Date:
Sat Nov 16 16:34:57 2019 +0000
Revision:
0:4e8ef5758455
SX1278 - RA-01 Lora library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
igbt6 0:4e8ef5758455 1 /**
igbt6 0:4e8ef5758455 2 * @brief: Implementation of a SX1278 radio functions
igbt6 0:4e8ef5758455 3 * @author: luk6xff based on SEMTCH code: https://github.com/Lora-net/LoRaMac-node
igbt6 0:4e8ef5758455 4 * @email: luszko@op.pl
igbt6 0:4e8ef5758455 5 * @date: 2019-11-15
igbt6 0:4e8ef5758455 6 */
igbt6 0:4e8ef5758455 7 #include "registers.h"
igbt6 0:4e8ef5758455 8 #include "sx1278.h"
igbt6 0:4e8ef5758455 9
igbt6 0:4e8ef5758455 10 #include <math.h>
igbt6 0:4e8ef5758455 11 #include <string.h>
igbt6 0:4e8ef5758455 12
igbt6 0:4e8ef5758455 13 /**
igbt6 0:4e8ef5758455 14 * ============================================================================
igbt6 0:4e8ef5758455 15 * @brief Private global constants
igbt6 0:4e8ef5758455 16 * ============================================================================
igbt6 0:4e8ef5758455 17 */
igbt6 0:4e8ef5758455 18 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 19 /**
igbt6 0:4e8ef5758455 20 * Precomputed FSK bandwidth registers values
igbt6 0:4e8ef5758455 21 */
igbt6 0:4e8ef5758455 22 static const BandwidthMap_t SX1278FskBandwidths[] =
igbt6 0:4e8ef5758455 23 {
igbt6 0:4e8ef5758455 24 { 2600 , 0x17 },
igbt6 0:4e8ef5758455 25 { 3100 , 0x0F },
igbt6 0:4e8ef5758455 26 { 3900 , 0x07 },
igbt6 0:4e8ef5758455 27 { 5200 , 0x16 },
igbt6 0:4e8ef5758455 28 { 6300 , 0x0E },
igbt6 0:4e8ef5758455 29 { 7800 , 0x06 },
igbt6 0:4e8ef5758455 30 { 10400 , 0x15 },
igbt6 0:4e8ef5758455 31 { 12500 , 0x0D },
igbt6 0:4e8ef5758455 32 { 15600 , 0x05 },
igbt6 0:4e8ef5758455 33 { 20800 , 0x14 },
igbt6 0:4e8ef5758455 34 { 25000 , 0x0C },
igbt6 0:4e8ef5758455 35 { 31300 , 0x04 },
igbt6 0:4e8ef5758455 36 { 41700 , 0x13 },
igbt6 0:4e8ef5758455 37 { 50000 , 0x0B },
igbt6 0:4e8ef5758455 38 { 62500 , 0x03 },
igbt6 0:4e8ef5758455 39 { 83333 , 0x12 },
igbt6 0:4e8ef5758455 40 { 100000, 0x0A },
igbt6 0:4e8ef5758455 41 { 125000, 0x02 },
igbt6 0:4e8ef5758455 42 { 166700, 0x11 },
igbt6 0:4e8ef5758455 43 { 200000, 0x09 },
igbt6 0:4e8ef5758455 44 { 250000, 0x01 },
igbt6 0:4e8ef5758455 45 { 300000, 0x00 }, // Invalid Bandwidth
igbt6 0:4e8ef5758455 46 };
igbt6 0:4e8ef5758455 47
igbt6 0:4e8ef5758455 48 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 49 /**
igbt6 0:4e8ef5758455 50 * @brief Precomputed LORA bandwidth registers values
igbt6 0:4e8ef5758455 51 */
igbt6 0:4e8ef5758455 52 static const BandwidthMap_t SX1278LoRaBandwidths[] =
igbt6 0:4e8ef5758455 53 {
igbt6 0:4e8ef5758455 54 { 7800, 0 }, // 7.8 kHz requires TCXO
igbt6 0:4e8ef5758455 55 { 10400, 1 }, // 10.4 kHz requires TCXO
igbt6 0:4e8ef5758455 56 { 15600, 2 }, // 15.6 kHz requires TCXO
igbt6 0:4e8ef5758455 57 { 20800, 3 }, // 20.8 kHz requires TCXO
igbt6 0:4e8ef5758455 58 { 31250, 4 }, // 31.25 kHz requires TCXO
igbt6 0:4e8ef5758455 59 { 41700, 5 }, // 41.7 kHz requires TCXO
igbt6 0:4e8ef5758455 60 { 62500, 6 }, // 62.5 kHz requires TCXO
igbt6 0:4e8ef5758455 61 { 125000, 7 }, // 125 kHz the LoRa protocol default
igbt6 0:4e8ef5758455 62 { 250000, 8 }, // 250 kHz
igbt6 0:4e8ef5758455 63 { 500000, 9 }, // 500 kHz
igbt6 0:4e8ef5758455 64 { 600000, 10 },// Invalid Bandwidth, reserved
igbt6 0:4e8ef5758455 65 };
igbt6 0:4e8ef5758455 66
igbt6 0:4e8ef5758455 67 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 68 /**
igbt6 0:4e8ef5758455 69 * @brief Radio hardware registers initialization definition
igbt6 0:4e8ef5758455 70 */
igbt6 0:4e8ef5758455 71 static const RadioRegisters_t SX1278RadioRegsInit[] =
igbt6 0:4e8ef5758455 72 { \
igbt6 0:4e8ef5758455 73 { MODEM_FSK , REG_LNA , 0x23 },\
igbt6 0:4e8ef5758455 74 { MODEM_FSK , REG_RXCONFIG , 0x1E },\
igbt6 0:4e8ef5758455 75 { MODEM_FSK , REG_RSSICONFIG , 0xD2 },\
igbt6 0:4e8ef5758455 76 { MODEM_FSK , REG_AFCFEI , 0x01 },\
igbt6 0:4e8ef5758455 77 { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },\
igbt6 0:4e8ef5758455 78 { MODEM_FSK , REG_OSC , 0x07 },\
igbt6 0:4e8ef5758455 79 { MODEM_FSK , REG_SYNCCONFIG , 0x12 },\
igbt6 0:4e8ef5758455 80 { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },\
igbt6 0:4e8ef5758455 81 { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },\
igbt6 0:4e8ef5758455 82 { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },\
igbt6 0:4e8ef5758455 83 { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },\
igbt6 0:4e8ef5758455 84 { MODEM_FSK , REG_FIFOTHRESH , 0x8F },\
igbt6 0:4e8ef5758455 85 { MODEM_FSK , REG_IMAGECAL , 0x02 },\
igbt6 0:4e8ef5758455 86 { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },\
igbt6 0:4e8ef5758455 87 { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },\
igbt6 0:4e8ef5758455 88 { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\
igbt6 0:4e8ef5758455 89 };
igbt6 0:4e8ef5758455 90
igbt6 0:4e8ef5758455 91
igbt6 0:4e8ef5758455 92 /**
igbt6 0:4e8ef5758455 93 * ============================================================================
igbt6 0:4e8ef5758455 94 * @brief Private functions prototypes
igbt6 0:4e8ef5758455 95 * ============================================================================
igbt6 0:4e8ef5758455 96 */
igbt6 0:4e8ef5758455 97
igbt6 0:4e8ef5758455 98 /**
igbt6 0:4e8ef5758455 99 * @brief Performs the Rx chain calibration for LF and HF bands
igbt6 0:4e8ef5758455 100 * @note Must be called just after the reset so all registers are at their
igbt6 0:4e8ef5758455 101 * default values
igbt6 0:4e8ef5758455 102 */
igbt6 0:4e8ef5758455 103 static void RxChainCalibration(void);
igbt6 0:4e8ef5758455 104
igbt6 0:4e8ef5758455 105 /**
igbt6 0:4e8ef5758455 106 * Returns the known FSK bandwidth registers value
igbt6 0:4e8ef5758455 107 *
igbt6 0:4e8ef5758455 108 * @param [IN] bandwidth Bandwidth value in Hz
igbt6 0:4e8ef5758455 109 * @retval regValue Bandwidth register value.
igbt6 0:4e8ef5758455 110 */
igbt6 0:4e8ef5758455 111 static uint8_t GetFskBandwidthRegValue(uint32_t bandwidth);
igbt6 0:4e8ef5758455 112
igbt6 0:4e8ef5758455 113 /**
igbt6 0:4e8ef5758455 114 * Returns the known LORA bandwidth registers value
igbt6 0:4e8ef5758455 115 *
igbt6 0:4e8ef5758455 116 * @param [IN] bandwidth Bandwidth value in Hz
igbt6 0:4e8ef5758455 117 * @retval regValue Bandwidth register value.
igbt6 0:4e8ef5758455 118 */
igbt6 0:4e8ef5758455 119 static uint8_t GetLoRaBandwidthRegValue(uint32_t bandwidth);
igbt6 0:4e8ef5758455 120
igbt6 0:4e8ef5758455 121
igbt6 0:4e8ef5758455 122 /**
igbt6 0:4e8ef5758455 123 * @brief DIO 0 IRQ callback
igbt6 0:4e8ef5758455 124 */
igbt6 0:4e8ef5758455 125 static void OnDio0Irq();
igbt6 0:4e8ef5758455 126
igbt6 0:4e8ef5758455 127 /**
igbt6 0:4e8ef5758455 128 * @brief DIO 1 IRQ callback
igbt6 0:4e8ef5758455 129 */
igbt6 0:4e8ef5758455 130 static void OnDio1Irq();
igbt6 0:4e8ef5758455 131
igbt6 0:4e8ef5758455 132 /**
igbt6 0:4e8ef5758455 133 * @brief DIO 2 IRQ callback
igbt6 0:4e8ef5758455 134 */
igbt6 0:4e8ef5758455 135 static void OnDio2Irq();
igbt6 0:4e8ef5758455 136
igbt6 0:4e8ef5758455 137 /**
igbt6 0:4e8ef5758455 138 * @brief DIO 3 IRQ callback
igbt6 0:4e8ef5758455 139 */
igbt6 0:4e8ef5758455 140 static void OnDio3Irq();
igbt6 0:4e8ef5758455 141
igbt6 0:4e8ef5758455 142 /**
igbt6 0:4e8ef5758455 143 * @brief DIO 4 IRQ callback
igbt6 0:4e8ef5758455 144 */
igbt6 0:4e8ef5758455 145 static void OnDio4Irq();
igbt6 0:4e8ef5758455 146
igbt6 0:4e8ef5758455 147 /**
igbt6 0:4e8ef5758455 148 * @brief DIO 5 IRQ callback
igbt6 0:4e8ef5758455 149 */
igbt6 0:4e8ef5758455 150 static void OnDio5Irq();
igbt6 0:4e8ef5758455 151
igbt6 0:4e8ef5758455 152 /**
igbt6 0:4e8ef5758455 153 * @brief Tx & Rx timeout timer callback
igbt6 0:4e8ef5758455 154 */
igbt6 0:4e8ef5758455 155 static void OnTimeoutIrq();
igbt6 0:4e8ef5758455 156
igbt6 0:4e8ef5758455 157
igbt6 0:4e8ef5758455 158
igbt6 0:4e8ef5758455 159 /**
igbt6 0:4e8ef5758455 160 * ============================================================================
igbt6 0:4e8ef5758455 161 * @brief Private global variables
igbt6 0:4e8ef5758455 162 * ============================================================================
igbt6 0:4e8ef5758455 163 */
igbt6 0:4e8ef5758455 164
igbt6 0:4e8ef5758455 165 /**
igbt6 0:4e8ef5758455 166 * Radio callbacks variable
igbt6 0:4e8ef5758455 167 */
igbt6 0:4e8ef5758455 168 static RadioEvents_t* RadioEvents;
igbt6 0:4e8ef5758455 169
igbt6 0:4e8ef5758455 170 /**
igbt6 0:4e8ef5758455 171 * Reception buffer
igbt6 0:4e8ef5758455 172 */
igbt6 0:4e8ef5758455 173 static uint8_t RxTxBuffer[RX_BUFFER_SIZE];
igbt6 0:4e8ef5758455 174
igbt6 0:4e8ef5758455 175 /**
igbt6 0:4e8ef5758455 176 * Hardware DIO IRQ functions
igbt6 0:4e8ef5758455 177 */
igbt6 0:4e8ef5758455 178 DioIrqHandler dioIrq[] = { OnDio0Irq, OnDio1Irq,
igbt6 0:4e8ef5758455 179 OnDio2Irq, OnDio3Irq,
igbt6 0:4e8ef5758455 180 OnDio4Irq, NULL };
igbt6 0:4e8ef5758455 181
igbt6 0:4e8ef5758455 182 /**
igbt6 0:4e8ef5758455 183 * Radio settings
igbt6 0:4e8ef5758455 184 */
igbt6 0:4e8ef5758455 185 RadioSettings_t settings;
igbt6 0:4e8ef5758455 186
igbt6 0:4e8ef5758455 187
igbt6 0:4e8ef5758455 188
igbt6 0:4e8ef5758455 189 /**
igbt6 0:4e8ef5758455 190 * ============================================================================
igbt6 0:4e8ef5758455 191 * @brief Public functions definitions
igbt6 0:4e8ef5758455 192 * ============================================================================
igbt6 0:4e8ef5758455 193 */
igbt6 0:4e8ef5758455 194 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 195 bool SX1278Init(RadioEvents_t *events)
igbt6 0:4e8ef5758455 196 {
igbt6 0:4e8ef5758455 197 RadioEvents = events;
igbt6 0:4e8ef5758455 198
igbt6 0:4e8ef5758455 199 if (SX1278Read(REG_VERSION) == 0x00)
igbt6 0:4e8ef5758455 200 {
igbt6 0:4e8ef5758455 201 return false;
igbt6 0:4e8ef5758455 202 }
igbt6 0:4e8ef5758455 203
igbt6 0:4e8ef5758455 204 SX1278Reset();
igbt6 0:4e8ef5758455 205 RxChainCalibration();
igbt6 0:4e8ef5758455 206 SX1278SetOpMode(RF_OPMODE_SLEEP);
igbt6 0:4e8ef5758455 207
igbt6 0:4e8ef5758455 208 SX1278IoIrqInit(dioIrq);
igbt6 0:4e8ef5758455 209 SX1278RadioRegistersInit();
igbt6 0:4e8ef5758455 210 SX1278SetModem(MODEM_FSK);
igbt6 0:4e8ef5758455 211 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 212 return true;
igbt6 0:4e8ef5758455 213 }
igbt6 0:4e8ef5758455 214
igbt6 0:4e8ef5758455 215 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 216 void SX1278RadioRegistersInit()
igbt6 0:4e8ef5758455 217 {
igbt6 0:4e8ef5758455 218 uint8_t i = 0;
igbt6 0:4e8ef5758455 219 for(i = 0; i < sizeof(SX1278RadioRegsInit) / sizeof(RadioRegisters_t); i++)
igbt6 0:4e8ef5758455 220 {
igbt6 0:4e8ef5758455 221 SX1278SetModem(SX1278RadioRegsInit[i].Modem);
igbt6 0:4e8ef5758455 222 SX1278Write(SX1278RadioRegsInit[i].Addr, SX1278RadioRegsInit[i].Value);
igbt6 0:4e8ef5758455 223 }
igbt6 0:4e8ef5758455 224 }
igbt6 0:4e8ef5758455 225
igbt6 0:4e8ef5758455 226 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 227 RadioState_t SX1278GetStatus(void)
igbt6 0:4e8ef5758455 228 {
igbt6 0:4e8ef5758455 229 return settings.State;
igbt6 0:4e8ef5758455 230 }
igbt6 0:4e8ef5758455 231
igbt6 0:4e8ef5758455 232 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 233 void SX1278SetChannel(uint32_t freq)
igbt6 0:4e8ef5758455 234 {
igbt6 0:4e8ef5758455 235 settings.Channel = freq;
igbt6 0:4e8ef5758455 236 freq = (uint32_t)((double)freq / (double)FREQ_STEP);
igbt6 0:4e8ef5758455 237 SX1278Write(REG_FRFMSB, (uint8_t)((freq >> 16) & 0xFF));
igbt6 0:4e8ef5758455 238 SX1278Write(REG_FRFMID, (uint8_t)((freq >> 8) & 0xFF));
igbt6 0:4e8ef5758455 239 SX1278Write(REG_FRFLSB, (uint8_t)(freq & 0xFF));
igbt6 0:4e8ef5758455 240 }
igbt6 0:4e8ef5758455 241
igbt6 0:4e8ef5758455 242 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 243 bool SX1278IsChannelFree(RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime)
igbt6 0:4e8ef5758455 244 {
igbt6 0:4e8ef5758455 245 // TODO handle carrierSenseTime
igbt6 0:4e8ef5758455 246 int16_t rssi = 0;
igbt6 0:4e8ef5758455 247
igbt6 0:4e8ef5758455 248 SX1278SetModem(modem);
igbt6 0:4e8ef5758455 249
igbt6 0:4e8ef5758455 250 SX1278SetChannel(freq);
igbt6 0:4e8ef5758455 251
igbt6 0:4e8ef5758455 252 SX1278SetOpMode(RF_OPMODE_RECEIVER);
igbt6 0:4e8ef5758455 253
igbt6 0:4e8ef5758455 254 SX1278DelayMs(1);
igbt6 0:4e8ef5758455 255
igbt6 0:4e8ef5758455 256 rssi = SX1278GetRssi(modem);
igbt6 0:4e8ef5758455 257
igbt6 0:4e8ef5758455 258 SX1278SetSleep();
igbt6 0:4e8ef5758455 259 if (rssi > rssiThresh)
igbt6 0:4e8ef5758455 260 {
igbt6 0:4e8ef5758455 261 return false;
igbt6 0:4e8ef5758455 262 }
igbt6 0:4e8ef5758455 263 return true;
igbt6 0:4e8ef5758455 264 }
igbt6 0:4e8ef5758455 265
igbt6 0:4e8ef5758455 266 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 267 uint32_t SX1278Random(void)
igbt6 0:4e8ef5758455 268 {
igbt6 0:4e8ef5758455 269 uint8_t i;
igbt6 0:4e8ef5758455 270 uint32_t rnd = 0;
igbt6 0:4e8ef5758455 271
igbt6 0:4e8ef5758455 272 /*
igbt6 0:4e8ef5758455 273 * Radio setup for random number generation
igbt6 0:4e8ef5758455 274 */
igbt6 0:4e8ef5758455 275 // Set LoRa modem ON
igbt6 0:4e8ef5758455 276 SX1278SetModem(MODEM_LORA);
igbt6 0:4e8ef5758455 277
igbt6 0:4e8ef5758455 278 // Disable LoRa modem interrupts
igbt6 0:4e8ef5758455 279 SX1278Write(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
igbt6 0:4e8ef5758455 280 RFLR_IRQFLAGS_RXDONE |
igbt6 0:4e8ef5758455 281 RFLR_IRQFLAGS_PAYLOADCRCERROR |
igbt6 0:4e8ef5758455 282 RFLR_IRQFLAGS_VALIDHEADER |
igbt6 0:4e8ef5758455 283 RFLR_IRQFLAGS_TXDONE |
igbt6 0:4e8ef5758455 284 RFLR_IRQFLAGS_CADDONE |
igbt6 0:4e8ef5758455 285 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
igbt6 0:4e8ef5758455 286 RFLR_IRQFLAGS_CADDETECTED);
igbt6 0:4e8ef5758455 287
igbt6 0:4e8ef5758455 288 // Set radio in continuous reception
igbt6 0:4e8ef5758455 289 SX1278SetOpMode(RF_OPMODE_RECEIVER);
igbt6 0:4e8ef5758455 290
igbt6 0:4e8ef5758455 291 for(i = 0; i < 32; i++)
igbt6 0:4e8ef5758455 292 {
igbt6 0:4e8ef5758455 293 SX1278DelayMs(1);
igbt6 0:4e8ef5758455 294 // Unfiltered RSSI value SX1278Reading. Only takes the LSB value
igbt6 0:4e8ef5758455 295 rnd |= ((uint32_t)SX1278Read(REG_LR_RSSIWIDEBAND) & 0x01) << i;
igbt6 0:4e8ef5758455 296 }
igbt6 0:4e8ef5758455 297
igbt6 0:4e8ef5758455 298 SX1278SetSleep();
igbt6 0:4e8ef5758455 299
igbt6 0:4e8ef5758455 300 return rnd;
igbt6 0:4e8ef5758455 301 }
igbt6 0:4e8ef5758455 302
igbt6 0:4e8ef5758455 303 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 304 void SX1278SetRxConfig(RadioModems_t modem, uint32_t bandwidth,
igbt6 0:4e8ef5758455 305 uint32_t datarate, uint8_t coderate,
igbt6 0:4e8ef5758455 306 uint32_t bandwidthAfc, uint16_t preambleLen,
igbt6 0:4e8ef5758455 307 uint16_t symbTimeout, bool fixLen,
igbt6 0:4e8ef5758455 308 uint8_t payloadLen,
igbt6 0:4e8ef5758455 309 bool crcOn, bool freqHopOn, uint8_t hopPeriod,
igbt6 0:4e8ef5758455 310 bool iqInverted, bool rxContinuous)
igbt6 0:4e8ef5758455 311 {
igbt6 0:4e8ef5758455 312 SX1278SetModem(modem);
igbt6 0:4e8ef5758455 313
igbt6 0:4e8ef5758455 314 switch (modem)
igbt6 0:4e8ef5758455 315 {
igbt6 0:4e8ef5758455 316 case MODEM_FSK:
igbt6 0:4e8ef5758455 317 {
igbt6 0:4e8ef5758455 318 settings.Fsk.Bandwidth = bandwidth;
igbt6 0:4e8ef5758455 319 settings.Fsk.Datarate = datarate;
igbt6 0:4e8ef5758455 320 settings.Fsk.BandwidthAfc = bandwidthAfc;
igbt6 0:4e8ef5758455 321 settings.Fsk.FixLen = fixLen;
igbt6 0:4e8ef5758455 322 settings.Fsk.PayloadLen = payloadLen;
igbt6 0:4e8ef5758455 323 settings.Fsk.CrcOn = crcOn;
igbt6 0:4e8ef5758455 324 settings.Fsk.IqInverted = iqInverted;
igbt6 0:4e8ef5758455 325 settings.Fsk.RxContinuous = rxContinuous;
igbt6 0:4e8ef5758455 326 settings.Fsk.PreambleLen = preambleLen;
igbt6 0:4e8ef5758455 327 settings.Fsk.RxSingleTimeout = symbTimeout * ((1.0 / (double)datarate) * 8.0) * 1000;
igbt6 0:4e8ef5758455 328
igbt6 0:4e8ef5758455 329 datarate = (uint16_t)((double)XTAL_FREQ / (double)datarate);
igbt6 0:4e8ef5758455 330 SX1278Write(REG_BITRATEMSB, (uint8_t)(datarate >> 8));
igbt6 0:4e8ef5758455 331 SX1278Write(REG_BITRATELSB, (uint8_t)(datarate & 0xFF));
igbt6 0:4e8ef5758455 332
igbt6 0:4e8ef5758455 333 SX1278Write(REG_RXBW, GetFskBandwidthRegValue(bandwidth));
igbt6 0:4e8ef5758455 334 SX1278Write(REG_AFCBW, GetFskBandwidthRegValue(bandwidthAfc));
igbt6 0:4e8ef5758455 335
igbt6 0:4e8ef5758455 336 SX1278Write(REG_PREAMBLEMSB, (uint8_t)((preambleLen >> 8) & 0xFF));
igbt6 0:4e8ef5758455 337 SX1278Write(REG_PREAMBLELSB, (uint8_t)(preambleLen & 0xFF));
igbt6 0:4e8ef5758455 338
igbt6 0:4e8ef5758455 339 if (fixLen == 1)
igbt6 0:4e8ef5758455 340 {
igbt6 0:4e8ef5758455 341 SX1278Write(REG_PAYLOADLENGTH, payloadLen);
igbt6 0:4e8ef5758455 342 }
igbt6 0:4e8ef5758455 343 else
igbt6 0:4e8ef5758455 344 {
igbt6 0:4e8ef5758455 345 SX1278Write(REG_PAYLOADLENGTH, 0xFF); // Set payload length to the maximum
igbt6 0:4e8ef5758455 346 }
igbt6 0:4e8ef5758455 347
igbt6 0:4e8ef5758455 348 SX1278Write(REG_PACKETCONFIG1,
igbt6 0:4e8ef5758455 349 (SX1278Read(REG_PACKETCONFIG1) &
igbt6 0:4e8ef5758455 350 RF_PACKETCONFIG1_CRC_MASK &
igbt6 0:4e8ef5758455 351 RF_PACKETCONFIG1_PACKETFORMAT_MASK) |
igbt6 0:4e8ef5758455 352 ((fixLen == 1) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) |
igbt6 0:4e8ef5758455 353 (crcOn << 4));
igbt6 0:4e8ef5758455 354 SX1278Write(REG_PACKETCONFIG2, (SX1278Read(REG_PACKETCONFIG2) | RF_PACKETCONFIG2_DATAMODE_PACKET));
igbt6 0:4e8ef5758455 355 }
igbt6 0:4e8ef5758455 356 break;
igbt6 0:4e8ef5758455 357 case MODEM_LORA:
igbt6 0:4e8ef5758455 358 {
igbt6 0:4e8ef5758455 359 if (bandwidth > 11) // specified in Hz, needs mapping
igbt6 0:4e8ef5758455 360 {
igbt6 0:4e8ef5758455 361 bandwidth = GetLoRaBandwidthRegValue(bandwidth);
igbt6 0:4e8ef5758455 362 }
igbt6 0:4e8ef5758455 363 if (bandwidth > LORA_BANDWIDTH_500kHz)
igbt6 0:4e8ef5758455 364 {
igbt6 0:4e8ef5758455 365 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
igbt6 0:4e8ef5758455 366 while(1);
igbt6 0:4e8ef5758455 367 }
igbt6 0:4e8ef5758455 368 settings.LoRa.Bandwidth = bandwidth;
igbt6 0:4e8ef5758455 369 settings.LoRa.Datarate = datarate;
igbt6 0:4e8ef5758455 370 settings.LoRa.Coderate = coderate;
igbt6 0:4e8ef5758455 371 settings.LoRa.PreambleLen = preambleLen;
igbt6 0:4e8ef5758455 372 settings.LoRa.FixLen = fixLen;
igbt6 0:4e8ef5758455 373 settings.LoRa.PayloadLen = payloadLen;
igbt6 0:4e8ef5758455 374 settings.LoRa.CrcOn = crcOn;
igbt6 0:4e8ef5758455 375 settings.LoRa.FreqHopOn = freqHopOn;
igbt6 0:4e8ef5758455 376 settings.LoRa.HopPeriod = hopPeriod;
igbt6 0:4e8ef5758455 377 settings.LoRa.IqInverted = iqInverted;
igbt6 0:4e8ef5758455 378 settings.LoRa.RxContinuous = rxContinuous;
igbt6 0:4e8ef5758455 379
igbt6 0:4e8ef5758455 380 if (datarate > LORA_SF12)
igbt6 0:4e8ef5758455 381 {
igbt6 0:4e8ef5758455 382 datarate = LORA_SF12;
igbt6 0:4e8ef5758455 383 }
igbt6 0:4e8ef5758455 384 else if (datarate < LORA_SF6)
igbt6 0:4e8ef5758455 385 {
igbt6 0:4e8ef5758455 386 datarate = LORA_SF6;
igbt6 0:4e8ef5758455 387 }
igbt6 0:4e8ef5758455 388
igbt6 0:4e8ef5758455 389 if (((bandwidth == LORA_BANDWIDTH_125kHz) && ((datarate == LORA_SF11) || (datarate == LORA_SF12))) ||
igbt6 0:4e8ef5758455 390 ((bandwidth == LORA_BANDWIDTH_250kHz) && (datarate == LORA_SF12)))
igbt6 0:4e8ef5758455 391 {
igbt6 0:4e8ef5758455 392 settings.LoRa.LowDatarateOptimize = 0x01;
igbt6 0:4e8ef5758455 393 }
igbt6 0:4e8ef5758455 394 else
igbt6 0:4e8ef5758455 395 {
igbt6 0:4e8ef5758455 396 settings.LoRa.LowDatarateOptimize = 0x00;
igbt6 0:4e8ef5758455 397 }
igbt6 0:4e8ef5758455 398
igbt6 0:4e8ef5758455 399 SX1278Write(REG_LR_MODEMCONFIG1,
igbt6 0:4e8ef5758455 400 (SX1278Read(REG_LR_MODEMCONFIG1) &
igbt6 0:4e8ef5758455 401 RFLR_MODEMCONFIG1_BW_MASK &
igbt6 0:4e8ef5758455 402 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
igbt6 0:4e8ef5758455 403 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) |
igbt6 0:4e8ef5758455 404 (bandwidth << 4) | (coderate << 1) |
igbt6 0:4e8ef5758455 405 fixLen);
igbt6 0:4e8ef5758455 406
igbt6 0:4e8ef5758455 407 SX1278Write(REG_LR_MODEMCONFIG2,
igbt6 0:4e8ef5758455 408 (SX1278Read(REG_LR_MODEMCONFIG2) &
igbt6 0:4e8ef5758455 409 RFLR_MODEMCONFIG2_SF_MASK &
igbt6 0:4e8ef5758455 410 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK &
igbt6 0:4e8ef5758455 411 RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK) |
igbt6 0:4e8ef5758455 412 (datarate << 4) | (crcOn << 2) |
igbt6 0:4e8ef5758455 413 ((symbTimeout >> 8) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK));
igbt6 0:4e8ef5758455 414
igbt6 0:4e8ef5758455 415 SX1278Write(REG_LR_MODEMCONFIG3,
igbt6 0:4e8ef5758455 416 (SX1278Read(REG_LR_MODEMCONFIG3) &
igbt6 0:4e8ef5758455 417 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) |
igbt6 0:4e8ef5758455 418 (settings.LoRa.LowDatarateOptimize << 3));
igbt6 0:4e8ef5758455 419
igbt6 0:4e8ef5758455 420 SX1278Write(REG_LR_SYMBTIMEOUTLSB, (uint8_t)(symbTimeout & 0xFF));
igbt6 0:4e8ef5758455 421
igbt6 0:4e8ef5758455 422 SX1278Write(REG_LR_PREAMBLEMSB, (uint8_t)((preambleLen >> 8) & 0xFF));
igbt6 0:4e8ef5758455 423 SX1278Write(REG_LR_PREAMBLELSB, (uint8_t)(preambleLen & 0xFF));
igbt6 0:4e8ef5758455 424
igbt6 0:4e8ef5758455 425 if (fixLen == 1)
igbt6 0:4e8ef5758455 426 {
igbt6 0:4e8ef5758455 427 SX1278Write(REG_LR_PAYLOADLENGTH, payloadLen);
igbt6 0:4e8ef5758455 428 }
igbt6 0:4e8ef5758455 429
igbt6 0:4e8ef5758455 430 if (settings.LoRa.FreqHopOn == true)
igbt6 0:4e8ef5758455 431 {
igbt6 0:4e8ef5758455 432 SX1278Write(REG_LR_PLLHOP, (SX1278Read(REG_LR_PLLHOP) & RFLR_PLLHOP_FASTHOP_MASK) | RFLR_PLLHOP_FASTHOP_ON);
igbt6 0:4e8ef5758455 433 SX1278Write(REG_LR_HOPPERIOD, settings.LoRa.HopPeriod);
igbt6 0:4e8ef5758455 434 }
igbt6 0:4e8ef5758455 435
igbt6 0:4e8ef5758455 436 if ((bandwidth == LORA_BANDWIDTH_500kHz) && (settings.Channel > RF_MID_BAND_THRESH))
igbt6 0:4e8ef5758455 437 {
igbt6 0:4e8ef5758455 438 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
igbt6 0:4e8ef5758455 439 SX1278Write(REG_LR_HIGHBWOPTIMIZE1, 0x02);
igbt6 0:4e8ef5758455 440 SX1278Write(REG_LR_HIGHBWOPTIMIZE2, 0x64);
igbt6 0:4e8ef5758455 441 }
igbt6 0:4e8ef5758455 442 else if (bandwidth == LORA_BANDWIDTH_500kHz)
igbt6 0:4e8ef5758455 443 {
igbt6 0:4e8ef5758455 444 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
igbt6 0:4e8ef5758455 445 SX1278Write(REG_LR_HIGHBWOPTIMIZE1, 0x02);
igbt6 0:4e8ef5758455 446 SX1278Write(REG_LR_HIGHBWOPTIMIZE2, 0x7F);
igbt6 0:4e8ef5758455 447 }
igbt6 0:4e8ef5758455 448 else
igbt6 0:4e8ef5758455 449 {
igbt6 0:4e8ef5758455 450 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
igbt6 0:4e8ef5758455 451 SX1278Write(REG_LR_HIGHBWOPTIMIZE1, 0x03);
igbt6 0:4e8ef5758455 452 }
igbt6 0:4e8ef5758455 453
igbt6 0:4e8ef5758455 454 if (datarate == LORA_SF6)
igbt6 0:4e8ef5758455 455 {
igbt6 0:4e8ef5758455 456 SX1278Write(REG_LR_DETECTOPTIMIZE,
igbt6 0:4e8ef5758455 457 (SX1278Read(REG_LR_DETECTOPTIMIZE) &
igbt6 0:4e8ef5758455 458 RFLR_DETECTIONOPTIMIZE_MASK) |
igbt6 0:4e8ef5758455 459 RFLR_DETECTIONOPTIMIZE_SF6);
igbt6 0:4e8ef5758455 460 SX1278Write(REG_LR_DETECTIONTHRESHOLD,
igbt6 0:4e8ef5758455 461 RFLR_DETECTIONTHRESH_SF6);
igbt6 0:4e8ef5758455 462 }
igbt6 0:4e8ef5758455 463 else
igbt6 0:4e8ef5758455 464 {
igbt6 0:4e8ef5758455 465 SX1278Write(REG_LR_DETECTOPTIMIZE,
igbt6 0:4e8ef5758455 466 (SX1278Read(REG_LR_DETECTOPTIMIZE) &
igbt6 0:4e8ef5758455 467 RFLR_DETECTIONOPTIMIZE_MASK) |
igbt6 0:4e8ef5758455 468 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12);
igbt6 0:4e8ef5758455 469 SX1278Write(REG_LR_DETECTIONTHRESHOLD,
igbt6 0:4e8ef5758455 470 RFLR_DETECTIONTHRESH_SF7_TO_SF12);
igbt6 0:4e8ef5758455 471 }
igbt6 0:4e8ef5758455 472 }
igbt6 0:4e8ef5758455 473 break;
igbt6 0:4e8ef5758455 474 }
igbt6 0:4e8ef5758455 475 }
igbt6 0:4e8ef5758455 476
igbt6 0:4e8ef5758455 477 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 478 void SX1278SetTxConfig(RadioModems_t modem, int8_t power, uint32_t fdev,
igbt6 0:4e8ef5758455 479 uint32_t bandwidth, uint32_t datarate,
igbt6 0:4e8ef5758455 480 uint8_t coderate, uint16_t preambleLen,
igbt6 0:4e8ef5758455 481 bool fixLen, bool crcOn, bool freqHopOn,
igbt6 0:4e8ef5758455 482 uint8_t hopPeriod, bool iqInverted, uint32_t timeout)
igbt6 0:4e8ef5758455 483 {
igbt6 0:4e8ef5758455 484 SX1278SetModem(modem);
igbt6 0:4e8ef5758455 485 SX1278SetRfTxPower(power);
igbt6 0:4e8ef5758455 486
igbt6 0:4e8ef5758455 487 switch (modem)
igbt6 0:4e8ef5758455 488 {
igbt6 0:4e8ef5758455 489 case MODEM_FSK:
igbt6 0:4e8ef5758455 490 {
igbt6 0:4e8ef5758455 491 settings.Fsk.Power = power;
igbt6 0:4e8ef5758455 492 settings.Fsk.Fdev = fdev;
igbt6 0:4e8ef5758455 493 settings.Fsk.Bandwidth = bandwidth;
igbt6 0:4e8ef5758455 494 settings.Fsk.Datarate = datarate;
igbt6 0:4e8ef5758455 495 settings.Fsk.PreambleLen = preambleLen;
igbt6 0:4e8ef5758455 496 settings.Fsk.FixLen = fixLen;
igbt6 0:4e8ef5758455 497 settings.Fsk.CrcOn = crcOn;
igbt6 0:4e8ef5758455 498 settings.Fsk.IqInverted = iqInverted;
igbt6 0:4e8ef5758455 499 settings.Fsk.TxTimeout = timeout;
igbt6 0:4e8ef5758455 500
igbt6 0:4e8ef5758455 501 fdev = (uint16_t)((double)fdev / (double)FREQ_STEP);
igbt6 0:4e8ef5758455 502 SX1278Write(REG_FDEVMSB, (uint8_t)(fdev >> 8));
igbt6 0:4e8ef5758455 503 SX1278Write(REG_FDEVLSB, (uint8_t)(fdev & 0xFF));
igbt6 0:4e8ef5758455 504
igbt6 0:4e8ef5758455 505 datarate = (uint16_t)((double)XTAL_FREQ / (double)datarate);
igbt6 0:4e8ef5758455 506 SX1278Write(REG_BITRATEMSB, (uint8_t)(datarate >> 8));
igbt6 0:4e8ef5758455 507 SX1278Write(REG_BITRATELSB, (uint8_t)(datarate & 0xFF));
igbt6 0:4e8ef5758455 508
igbt6 0:4e8ef5758455 509 SX1278Write(REG_PREAMBLEMSB, (preambleLen >> 8) & 0x00FF);
igbt6 0:4e8ef5758455 510 SX1278Write(REG_PREAMBLELSB, preambleLen & 0xFF);
igbt6 0:4e8ef5758455 511
igbt6 0:4e8ef5758455 512 SX1278Write(REG_PACKETCONFIG1,
igbt6 0:4e8ef5758455 513 (SX1278Read(REG_PACKETCONFIG1) &
igbt6 0:4e8ef5758455 514 RF_PACKETCONFIG1_CRC_MASK &
igbt6 0:4e8ef5758455 515 RF_PACKETCONFIG1_PACKETFORMAT_MASK) |
igbt6 0:4e8ef5758455 516 ((fixLen == 1) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) |
igbt6 0:4e8ef5758455 517 (crcOn << 4));
igbt6 0:4e8ef5758455 518 SX1278Write(REG_PACKETCONFIG2, (SX1278Read(REG_PACKETCONFIG2) | RF_PACKETCONFIG2_DATAMODE_PACKET));
igbt6 0:4e8ef5758455 519 }
igbt6 0:4e8ef5758455 520 break;
igbt6 0:4e8ef5758455 521 case MODEM_LORA:
igbt6 0:4e8ef5758455 522 {
igbt6 0:4e8ef5758455 523 settings.LoRa.Power = power;
igbt6 0:4e8ef5758455 524 if (bandwidth > LORA_BANDWIDTH_500kHz)
igbt6 0:4e8ef5758455 525 {
igbt6 0:4e8ef5758455 526 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
igbt6 0:4e8ef5758455 527 while(1);
igbt6 0:4e8ef5758455 528 }
igbt6 0:4e8ef5758455 529
igbt6 0:4e8ef5758455 530 settings.LoRa.Bandwidth = bandwidth;
igbt6 0:4e8ef5758455 531 settings.LoRa.Datarate = datarate;
igbt6 0:4e8ef5758455 532 settings.LoRa.Coderate = coderate;
igbt6 0:4e8ef5758455 533 settings.LoRa.PreambleLen = preambleLen;
igbt6 0:4e8ef5758455 534 settings.LoRa.FixLen = fixLen;
igbt6 0:4e8ef5758455 535 settings.LoRa.FreqHopOn = freqHopOn;
igbt6 0:4e8ef5758455 536 settings.LoRa.HopPeriod = hopPeriod;
igbt6 0:4e8ef5758455 537 settings.LoRa.CrcOn = crcOn;
igbt6 0:4e8ef5758455 538 settings.LoRa.IqInverted = iqInverted;
igbt6 0:4e8ef5758455 539 settings.LoRa.TxTimeout = timeout;
igbt6 0:4e8ef5758455 540
igbt6 0:4e8ef5758455 541 if (datarate > LORA_SF12)
igbt6 0:4e8ef5758455 542 {
igbt6 0:4e8ef5758455 543 datarate = LORA_SF12;
igbt6 0:4e8ef5758455 544 }
igbt6 0:4e8ef5758455 545 else if (datarate < LORA_SF6)
igbt6 0:4e8ef5758455 546 {
igbt6 0:4e8ef5758455 547 datarate = LORA_SF6;
igbt6 0:4e8ef5758455 548 }
igbt6 0:4e8ef5758455 549 if (((bandwidth == LORA_BANDWIDTH_125kHz) && ((datarate == LORA_SF11) || (datarate == LORA_SF12))) ||
igbt6 0:4e8ef5758455 550 ((bandwidth == LORA_BANDWIDTH_250kHz) && (datarate == LORA_SF12)))
igbt6 0:4e8ef5758455 551 {
igbt6 0:4e8ef5758455 552 settings.LoRa.LowDatarateOptimize = 0x01;
igbt6 0:4e8ef5758455 553 }
igbt6 0:4e8ef5758455 554 else
igbt6 0:4e8ef5758455 555 {
igbt6 0:4e8ef5758455 556 settings.LoRa.LowDatarateOptimize = 0x00;
igbt6 0:4e8ef5758455 557 }
igbt6 0:4e8ef5758455 558
igbt6 0:4e8ef5758455 559 if (settings.LoRa.FreqHopOn == true)
igbt6 0:4e8ef5758455 560 {
igbt6 0:4e8ef5758455 561 SX1278Write(REG_LR_PLLHOP, (SX1278Read(REG_LR_PLLHOP) & RFLR_PLLHOP_FASTHOP_MASK) | RFLR_PLLHOP_FASTHOP_ON);
igbt6 0:4e8ef5758455 562 SX1278Write(REG_LR_HOPPERIOD, settings.LoRa.HopPeriod);
igbt6 0:4e8ef5758455 563 }
igbt6 0:4e8ef5758455 564
igbt6 0:4e8ef5758455 565 SX1278Write(REG_LR_MODEMCONFIG1,
igbt6 0:4e8ef5758455 566 (SX1278Read(REG_LR_MODEMCONFIG1) &
igbt6 0:4e8ef5758455 567 RFLR_MODEMCONFIG1_BW_MASK &
igbt6 0:4e8ef5758455 568 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
igbt6 0:4e8ef5758455 569 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) |
igbt6 0:4e8ef5758455 570 (bandwidth << 4) | (coderate << 1) |
igbt6 0:4e8ef5758455 571 fixLen);
igbt6 0:4e8ef5758455 572
igbt6 0:4e8ef5758455 573 SX1278Write(REG_LR_MODEMCONFIG2,
igbt6 0:4e8ef5758455 574 (SX1278Read(REG_LR_MODEMCONFIG2) &
igbt6 0:4e8ef5758455 575 RFLR_MODEMCONFIG2_SF_MASK &
igbt6 0:4e8ef5758455 576 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK) |
igbt6 0:4e8ef5758455 577 (datarate << 4) | (crcOn << 2));
igbt6 0:4e8ef5758455 578
igbt6 0:4e8ef5758455 579 SX1278Write(REG_LR_MODEMCONFIG3,
igbt6 0:4e8ef5758455 580 (SX1278Read(REG_LR_MODEMCONFIG3) &
igbt6 0:4e8ef5758455 581 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) |
igbt6 0:4e8ef5758455 582 (settings.LoRa.LowDatarateOptimize << 3));
igbt6 0:4e8ef5758455 583
igbt6 0:4e8ef5758455 584 SX1278Write(REG_LR_PREAMBLEMSB, (preambleLen >> 8) & 0x00FF);
igbt6 0:4e8ef5758455 585 SX1278Write(REG_LR_PREAMBLELSB, preambleLen & 0xFF);
igbt6 0:4e8ef5758455 586
igbt6 0:4e8ef5758455 587 if (datarate == LORA_SF6)
igbt6 0:4e8ef5758455 588 {
igbt6 0:4e8ef5758455 589 SX1278Write(REG_LR_DETECTOPTIMIZE,
igbt6 0:4e8ef5758455 590 (SX1278Read(REG_LR_DETECTOPTIMIZE) &
igbt6 0:4e8ef5758455 591 RFLR_DETECTIONOPTIMIZE_MASK) |
igbt6 0:4e8ef5758455 592 RFLR_DETECTIONOPTIMIZE_SF6);
igbt6 0:4e8ef5758455 593 SX1278Write(REG_LR_DETECTIONTHRESHOLD,
igbt6 0:4e8ef5758455 594 RFLR_DETECTIONTHRESH_SF6);
igbt6 0:4e8ef5758455 595 }
igbt6 0:4e8ef5758455 596 else
igbt6 0:4e8ef5758455 597 {
igbt6 0:4e8ef5758455 598 SX1278Write(REG_LR_DETECTOPTIMIZE,
igbt6 0:4e8ef5758455 599 (SX1278Read(REG_LR_DETECTOPTIMIZE) &
igbt6 0:4e8ef5758455 600 RFLR_DETECTIONOPTIMIZE_MASK) |
igbt6 0:4e8ef5758455 601 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12);
igbt6 0:4e8ef5758455 602 SX1278Write(REG_LR_DETECTIONTHRESHOLD,
igbt6 0:4e8ef5758455 603 RFLR_DETECTIONTHRESH_SF7_TO_SF12);
igbt6 0:4e8ef5758455 604 }
igbt6 0:4e8ef5758455 605 }
igbt6 0:4e8ef5758455 606 break;
igbt6 0:4e8ef5758455 607 }
igbt6 0:4e8ef5758455 608 }
igbt6 0:4e8ef5758455 609
igbt6 0:4e8ef5758455 610 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 611 uint32_t SX1278TimeOnAir(RadioModems_t modem, uint8_t pktLen)
igbt6 0:4e8ef5758455 612 {
igbt6 0:4e8ef5758455 613 uint32_t airTime = 0;
igbt6 0:4e8ef5758455 614
igbt6 0:4e8ef5758455 615 switch (modem)
igbt6 0:4e8ef5758455 616 {
igbt6 0:4e8ef5758455 617 case MODEM_FSK:
igbt6 0:4e8ef5758455 618 {
igbt6 0:4e8ef5758455 619 airTime = rint((8 * (settings.Fsk.PreambleLen +
igbt6 0:4e8ef5758455 620 ((SX1278Read(REG_SYNCCONFIG) & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) +
igbt6 0:4e8ef5758455 621 ((settings.Fsk.FixLen == 0x01) ? 0.0 : 1.0) +
igbt6 0:4e8ef5758455 622 (((SX1278Read(REG_PACKETCONFIG1) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) != 0x00) ? 1.0 : 0) +
igbt6 0:4e8ef5758455 623 pktLen +
igbt6 0:4e8ef5758455 624 ((settings.Fsk.CrcOn == 0x01) ? 2.0 : 0)) /
igbt6 0:4e8ef5758455 625 settings.Fsk.Datarate) * 1000);
igbt6 0:4e8ef5758455 626 }
igbt6 0:4e8ef5758455 627 break;
igbt6 0:4e8ef5758455 628 case MODEM_LORA:
igbt6 0:4e8ef5758455 629 {
igbt6 0:4e8ef5758455 630 double bw = 0.0;
igbt6 0:4e8ef5758455 631 // NOTE: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
igbt6 0:4e8ef5758455 632 switch (settings.LoRa.Bandwidth)
igbt6 0:4e8ef5758455 633 {
igbt6 0:4e8ef5758455 634 case LORA_BANDWIDTH_7kHz: // 7.8 kHz
igbt6 0:4e8ef5758455 635 bw = 78e2;
igbt6 0:4e8ef5758455 636 break;
igbt6 0:4e8ef5758455 637 case LORA_BANDWIDTH_10kHz: // 10.4 kHz
igbt6 0:4e8ef5758455 638 bw = 104e2;
igbt6 0:4e8ef5758455 639 break;
igbt6 0:4e8ef5758455 640 case LORA_BANDWIDTH_15kHz: // 15.6 kHz
igbt6 0:4e8ef5758455 641 bw = 156e2;
igbt6 0:4e8ef5758455 642 break;
igbt6 0:4e8ef5758455 643 case LORA_BANDWIDTH_20kHz: // 20.8 kHz
igbt6 0:4e8ef5758455 644 bw = 208e2;
igbt6 0:4e8ef5758455 645 break;
igbt6 0:4e8ef5758455 646 case LORA_BANDWIDTH_31kHz: // 31.25 kHz
igbt6 0:4e8ef5758455 647 bw = 312e2;
igbt6 0:4e8ef5758455 648 break;
igbt6 0:4e8ef5758455 649 case LORA_BANDWIDTH_41kHz: // 41.7 kHz
igbt6 0:4e8ef5758455 650 bw = 414e2;
igbt6 0:4e8ef5758455 651 break;
igbt6 0:4e8ef5758455 652 case LORA_BANDWIDTH_62kHz: // 62.5 kHz
igbt6 0:4e8ef5758455 653 bw = 625e2;
igbt6 0:4e8ef5758455 654 break;
igbt6 0:4e8ef5758455 655 case LORA_BANDWIDTH_125kHz: // 125 kHz
igbt6 0:4e8ef5758455 656 bw = 125e3;
igbt6 0:4e8ef5758455 657 break;
igbt6 0:4e8ef5758455 658 case LORA_BANDWIDTH_250kHz: // 250 kHz
igbt6 0:4e8ef5758455 659 bw = 250e3;
igbt6 0:4e8ef5758455 660 break;
igbt6 0:4e8ef5758455 661 case LORA_BANDWIDTH_500kHz: // 500 kHz
igbt6 0:4e8ef5758455 662 bw = 500e3;
igbt6 0:4e8ef5758455 663 break;
igbt6 0:4e8ef5758455 664 }
igbt6 0:4e8ef5758455 665
igbt6 0:4e8ef5758455 666 // Symbol rate : time for one symbol (secs)
igbt6 0:4e8ef5758455 667 double rs = bw / (1 << settings.LoRa.Datarate);
igbt6 0:4e8ef5758455 668 double ts = 1 / rs;
igbt6 0:4e8ef5758455 669 // time of preamble
igbt6 0:4e8ef5758455 670 double tPreamble = (settings.LoRa.PreambleLen + 4.25) * ts;
igbt6 0:4e8ef5758455 671 // Symbol length of payload and time
igbt6 0:4e8ef5758455 672 double tmp = ceil((8 * pktLen - 4 * settings.LoRa.Datarate +
igbt6 0:4e8ef5758455 673 28 + 16 * settings.LoRa.CrcOn -
igbt6 0:4e8ef5758455 674 (settings.LoRa.FixLen ? 20 : 0)) /
igbt6 0:4e8ef5758455 675 (double)(4 * (settings.LoRa.Datarate -
igbt6 0:4e8ef5758455 676 ((settings.LoRa.LowDatarateOptimize > 0) ? 2 : 0)))) *
igbt6 0:4e8ef5758455 677 (settings.LoRa.Coderate + 4);
igbt6 0:4e8ef5758455 678 double nPayload = 8 + ((tmp > 0) ? tmp : 0);
igbt6 0:4e8ef5758455 679 double tPayload = nPayload * ts;
igbt6 0:4e8ef5758455 680 // Time on air
igbt6 0:4e8ef5758455 681 double tOnAir = tPreamble + tPayload;
igbt6 0:4e8ef5758455 682 // return ms secs
igbt6 0:4e8ef5758455 683 airTime = floor(tOnAir * 1000 + 0.999);
igbt6 0:4e8ef5758455 684 }
igbt6 0:4e8ef5758455 685 break;
igbt6 0:4e8ef5758455 686 }
igbt6 0:4e8ef5758455 687 return airTime;
igbt6 0:4e8ef5758455 688 }
igbt6 0:4e8ef5758455 689
igbt6 0:4e8ef5758455 690 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 691 void SX1278Send(uint8_t *buffer, uint8_t size)
igbt6 0:4e8ef5758455 692 {
igbt6 0:4e8ef5758455 693 uint32_t txTimeout = 0;
igbt6 0:4e8ef5758455 694
igbt6 0:4e8ef5758455 695 switch (settings.Modem)
igbt6 0:4e8ef5758455 696 {
igbt6 0:4e8ef5758455 697 case MODEM_FSK:
igbt6 0:4e8ef5758455 698 {
igbt6 0:4e8ef5758455 699 settings.FskPacketHandler.NbBytes = 0;
igbt6 0:4e8ef5758455 700 settings.FskPacketHandler.Size = size;
igbt6 0:4e8ef5758455 701
igbt6 0:4e8ef5758455 702 if (settings.Fsk.FixLen == false)
igbt6 0:4e8ef5758455 703 {
igbt6 0:4e8ef5758455 704 SX1278WriteFifo((uint8_t*)&size, 1);
igbt6 0:4e8ef5758455 705 }
igbt6 0:4e8ef5758455 706 else
igbt6 0:4e8ef5758455 707 {
igbt6 0:4e8ef5758455 708 SX1278Write(REG_PAYLOADLENGTH, size);
igbt6 0:4e8ef5758455 709 }
igbt6 0:4e8ef5758455 710
igbt6 0:4e8ef5758455 711 if ((size > 0) && (size <= 64))
igbt6 0:4e8ef5758455 712 {
igbt6 0:4e8ef5758455 713 settings.FskPacketHandler.ChunkSize = size;
igbt6 0:4e8ef5758455 714 }
igbt6 0:4e8ef5758455 715 else
igbt6 0:4e8ef5758455 716 {
igbt6 0:4e8ef5758455 717 memcpy(RxTxBuffer, buffer, size);
igbt6 0:4e8ef5758455 718 settings.FskPacketHandler.ChunkSize = 32;
igbt6 0:4e8ef5758455 719 }
igbt6 0:4e8ef5758455 720
igbt6 0:4e8ef5758455 721 // Write payload buffer
igbt6 0:4e8ef5758455 722 SX1278WriteFifo(buffer, settings.FskPacketHandler.ChunkSize);
igbt6 0:4e8ef5758455 723 settings.FskPacketHandler.NbBytes += settings.FskPacketHandler.ChunkSize;
igbt6 0:4e8ef5758455 724 txTimeout = settings.Fsk.TxTimeout;
igbt6 0:4e8ef5758455 725 }
igbt6 0:4e8ef5758455 726 break;
igbt6 0:4e8ef5758455 727 case MODEM_LORA:
igbt6 0:4e8ef5758455 728 {
igbt6 0:4e8ef5758455 729 if (settings.LoRa.IqInverted == true)
igbt6 0:4e8ef5758455 730 {
igbt6 0:4e8ef5758455 731 SX1278Write(REG_LR_INVERTIQ, ((SX1278Read(REG_LR_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON));
igbt6 0:4e8ef5758455 732 SX1278Write(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON);
igbt6 0:4e8ef5758455 733 }
igbt6 0:4e8ef5758455 734 else
igbt6 0:4e8ef5758455 735 {
igbt6 0:4e8ef5758455 736 SX1278Write(REG_LR_INVERTIQ, ((SX1278Read(REG_LR_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF));
igbt6 0:4e8ef5758455 737 SX1278Write(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF);
igbt6 0:4e8ef5758455 738 }
igbt6 0:4e8ef5758455 739
igbt6 0:4e8ef5758455 740 settings.LoRaPacketHandler.Size = size;
igbt6 0:4e8ef5758455 741
igbt6 0:4e8ef5758455 742 // Initializes the payload size
igbt6 0:4e8ef5758455 743 SX1278Write(REG_LR_PAYLOADLENGTH, size);
igbt6 0:4e8ef5758455 744
igbt6 0:4e8ef5758455 745 // Full buffer used for Tx
igbt6 0:4e8ef5758455 746 SX1278Write(REG_LR_FIFOTXBASEADDR, 0);
igbt6 0:4e8ef5758455 747 SX1278Write(REG_LR_FIFOADDRPTR, 0);
igbt6 0:4e8ef5758455 748
igbt6 0:4e8ef5758455 749 // FIFO operations can not take place in SX1278SetSleep mode
igbt6 0:4e8ef5758455 750 if ((SX1278Read(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP)
igbt6 0:4e8ef5758455 751 {
igbt6 0:4e8ef5758455 752 SX1278SetStandby();
igbt6 0:4e8ef5758455 753 SX1278DelayMs(1);
igbt6 0:4e8ef5758455 754 }
igbt6 0:4e8ef5758455 755 // SX1278Write payload buffer
igbt6 0:4e8ef5758455 756 SX1278WriteFifo(buffer, size);
igbt6 0:4e8ef5758455 757 txTimeout = settings.LoRa.TxTimeout;
igbt6 0:4e8ef5758455 758 }
igbt6 0:4e8ef5758455 759 break;
igbt6 0:4e8ef5758455 760 }
igbt6 0:4e8ef5758455 761
igbt6 0:4e8ef5758455 762 SX1278SetTx(txTimeout);
igbt6 0:4e8ef5758455 763 }
igbt6 0:4e8ef5758455 764
igbt6 0:4e8ef5758455 765 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 766 void SX1278SetSleep(void)
igbt6 0:4e8ef5758455 767 {
igbt6 0:4e8ef5758455 768 SX1278SetTimeout(TXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 769 SX1278SetTimeout(RXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 770
igbt6 0:4e8ef5758455 771 SX1278SetOpMode(RF_OPMODE_SLEEP);
igbt6 0:4e8ef5758455 772 //TODO Disable TCXO radio is in SLEEP mode if available
igbt6 0:4e8ef5758455 773 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 774 }
igbt6 0:4e8ef5758455 775
igbt6 0:4e8ef5758455 776 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 777 void SX1278SetStandby(void)
igbt6 0:4e8ef5758455 778 {
igbt6 0:4e8ef5758455 779 SX1278SetTimeout(TXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 780 SX1278SetTimeout(RXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 781 SX1278SetTimeout(RXTimeoutSyncWordTimer, NULL, 0);
igbt6 0:4e8ef5758455 782
igbt6 0:4e8ef5758455 783 SX1278SetOpMode(RF_OPMODE_STANDBY);
igbt6 0:4e8ef5758455 784 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 785 }
igbt6 0:4e8ef5758455 786
igbt6 0:4e8ef5758455 787 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 788 void SX1278SetRx(uint32_t timeout)
igbt6 0:4e8ef5758455 789 {
igbt6 0:4e8ef5758455 790 bool rxContinuous = false;
igbt6 0:4e8ef5758455 791
igbt6 0:4e8ef5758455 792 switch (settings.Modem)
igbt6 0:4e8ef5758455 793 {
igbt6 0:4e8ef5758455 794 case MODEM_FSK:
igbt6 0:4e8ef5758455 795 {
igbt6 0:4e8ef5758455 796 rxContinuous = settings.Fsk.RxContinuous;
igbt6 0:4e8ef5758455 797
igbt6 0:4e8ef5758455 798 // DIO0=PayloadSX1278Ready
igbt6 0:4e8ef5758455 799 // DIO1=FifoLevel
igbt6 0:4e8ef5758455 800 // DIO2=SyncAddr
igbt6 0:4e8ef5758455 801 // DIO3=FifoEmpty
igbt6 0:4e8ef5758455 802 // DIO4=Preamble
igbt6 0:4e8ef5758455 803 // DIO5=ModeSX1278Ready
igbt6 0:4e8ef5758455 804 SX1278Write(REG_DIOMAPPING1, (SX1278Read(REG_DIOMAPPING1) & RF_DIOMAPPING1_DIO0_MASK &
igbt6 0:4e8ef5758455 805 RF_DIOMAPPING1_DIO1_MASK &
igbt6 0:4e8ef5758455 806 RF_DIOMAPPING1_DIO2_MASK) |
igbt6 0:4e8ef5758455 807 RF_DIOMAPPING1_DIO0_00 |
igbt6 0:4e8ef5758455 808 RF_DIOMAPPING1_DIO1_00 |
igbt6 0:4e8ef5758455 809 RF_DIOMAPPING1_DIO2_11);
igbt6 0:4e8ef5758455 810
igbt6 0:4e8ef5758455 811 SX1278Write(REG_DIOMAPPING2, (SX1278Read(REG_DIOMAPPING2) & RF_DIOMAPPING2_DIO4_MASK &
igbt6 0:4e8ef5758455 812 RF_DIOMAPPING2_MAP_MASK) |
igbt6 0:4e8ef5758455 813 RF_DIOMAPPING2_DIO4_11 |
igbt6 0:4e8ef5758455 814 RF_DIOMAPPING2_MAP_PREAMBLEDETECT);
igbt6 0:4e8ef5758455 815
igbt6 0:4e8ef5758455 816 settings.FskPacketHandler.FifoThresh = SX1278Read(REG_FIFOTHRESH) & 0x3F;
igbt6 0:4e8ef5758455 817
igbt6 0:4e8ef5758455 818 SX1278Write(REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT);
igbt6 0:4e8ef5758455 819
igbt6 0:4e8ef5758455 820 settings.FskPacketHandler.PreambleDetected = false;
igbt6 0:4e8ef5758455 821 settings.FskPacketHandler.SyncWordDetected = false;
igbt6 0:4e8ef5758455 822 settings.FskPacketHandler.NbBytes = 0;
igbt6 0:4e8ef5758455 823 settings.FskPacketHandler.Size = 0;
igbt6 0:4e8ef5758455 824 }
igbt6 0:4e8ef5758455 825 break;
igbt6 0:4e8ef5758455 826 case MODEM_LORA:
igbt6 0:4e8ef5758455 827 {
igbt6 0:4e8ef5758455 828 if (settings.LoRa.IqInverted == true)
igbt6 0:4e8ef5758455 829 {
igbt6 0:4e8ef5758455 830 SX1278Write(REG_LR_INVERTIQ, ((SX1278Read(REG_LR_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF));
igbt6 0:4e8ef5758455 831 SX1278Write(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON);
igbt6 0:4e8ef5758455 832 }
igbt6 0:4e8ef5758455 833 else
igbt6 0:4e8ef5758455 834 {
igbt6 0:4e8ef5758455 835 SX1278Write(REG_LR_INVERTIQ, ((SX1278Read(REG_LR_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF));
igbt6 0:4e8ef5758455 836 SX1278Write(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF);
igbt6 0:4e8ef5758455 837 }
igbt6 0:4e8ef5758455 838
igbt6 0:4e8ef5758455 839 // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal
igbt6 0:4e8ef5758455 840 if (settings.LoRa.Bandwidth < LORA_BANDWIDTH_500kHz)
igbt6 0:4e8ef5758455 841 {
igbt6 0:4e8ef5758455 842 SX1278Write(REG_LR_DETECTOPTIMIZE, SX1278Read(REG_LR_DETECTOPTIMIZE) & 0x7F);
igbt6 0:4e8ef5758455 843 SX1278Write(REG_LR_IFFREQ2, 0x00);
igbt6 0:4e8ef5758455 844 switch (settings.LoRa.Bandwidth)
igbt6 0:4e8ef5758455 845 {
igbt6 0:4e8ef5758455 846 case LORA_BANDWIDTH_7kHz: // 7.8 kHz
igbt6 0:4e8ef5758455 847 SX1278Write(REG_LR_IFFREQ1, 0x48 );
igbt6 0:4e8ef5758455 848 SX1278SetChannel(settings.Channel + 7810);
igbt6 0:4e8ef5758455 849 break;
igbt6 0:4e8ef5758455 850 case LORA_BANDWIDTH_10kHz: // 10.4 kHz
igbt6 0:4e8ef5758455 851 SX1278Write(REG_LR_IFFREQ1, 0x44 );
igbt6 0:4e8ef5758455 852 SX1278SetChannel(settings.Channel + 10420);
igbt6 0:4e8ef5758455 853 break;
igbt6 0:4e8ef5758455 854 case LORA_BANDWIDTH_15kHz: // 15.6 kHz
igbt6 0:4e8ef5758455 855 SX1278Write(REG_LR_IFFREQ1, 0x44 );
igbt6 0:4e8ef5758455 856 SX1278SetChannel(settings.Channel + 15620);
igbt6 0:4e8ef5758455 857 break;
igbt6 0:4e8ef5758455 858 case LORA_BANDWIDTH_20kHz: // 20.8 kHz
igbt6 0:4e8ef5758455 859 SX1278Write(REG_LR_IFFREQ1, 0x44 );
igbt6 0:4e8ef5758455 860 SX1278SetChannel(settings.Channel + 20830);
igbt6 0:4e8ef5758455 861 break;
igbt6 0:4e8ef5758455 862 case LORA_BANDWIDTH_31kHz: // 31.25 kHz
igbt6 0:4e8ef5758455 863 SX1278Write(REG_LR_IFFREQ1, 0x44 );
igbt6 0:4e8ef5758455 864 SX1278SetChannel(settings.Channel + 31250);
igbt6 0:4e8ef5758455 865 break;
igbt6 0:4e8ef5758455 866 case LORA_BANDWIDTH_41kHz: // 41.4 kHz
igbt6 0:4e8ef5758455 867 SX1278Write(REG_LR_IFFREQ1, 0x44 );
igbt6 0:4e8ef5758455 868 SX1278SetChannel(settings.Channel + 41670);
igbt6 0:4e8ef5758455 869 break;
igbt6 0:4e8ef5758455 870 case LORA_BANDWIDTH_62kHz: // 62.5 kHz
igbt6 0:4e8ef5758455 871 SX1278Write(REG_LR_IFFREQ1, 0x40 );
igbt6 0:4e8ef5758455 872 break;
igbt6 0:4e8ef5758455 873 case LORA_BANDWIDTH_125kHz: // 125 kHz
igbt6 0:4e8ef5758455 874 SX1278Write(REG_LR_IFFREQ1, 0x40 );
igbt6 0:4e8ef5758455 875 break;
igbt6 0:4e8ef5758455 876 case LORA_BANDWIDTH_250kHz: // 250 kHz
igbt6 0:4e8ef5758455 877 SX1278Write(REG_LR_IFFREQ1, 0x40 );
igbt6 0:4e8ef5758455 878 break;
igbt6 0:4e8ef5758455 879 }
igbt6 0:4e8ef5758455 880 }
igbt6 0:4e8ef5758455 881 else
igbt6 0:4e8ef5758455 882 {
igbt6 0:4e8ef5758455 883 SX1278Write(REG_LR_DETECTOPTIMIZE, SX1278Read(REG_LR_DETECTOPTIMIZE) | 0x80);
igbt6 0:4e8ef5758455 884 }
igbt6 0:4e8ef5758455 885
igbt6 0:4e8ef5758455 886 rxContinuous = settings.LoRa.RxContinuous;
igbt6 0:4e8ef5758455 887
igbt6 0:4e8ef5758455 888 if (settings.LoRa.FreqHopOn == true)
igbt6 0:4e8ef5758455 889 {
igbt6 0:4e8ef5758455 890 SX1278Write(REG_LR_IRQFLAGSMASK,//RFLR_IRQFLAGS_RXTIMEOUT |
igbt6 0:4e8ef5758455 891 //RFLR_IRQFLAGS_RXDONE |
igbt6 0:4e8ef5758455 892 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
igbt6 0:4e8ef5758455 893 RFLR_IRQFLAGS_VALIDHEADER |
igbt6 0:4e8ef5758455 894 RFLR_IRQFLAGS_TXDONE |
igbt6 0:4e8ef5758455 895 RFLR_IRQFLAGS_CADDONE |
igbt6 0:4e8ef5758455 896 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
igbt6 0:4e8ef5758455 897 RFLR_IRQFLAGS_CADDETECTED);
igbt6 0:4e8ef5758455 898
igbt6 0:4e8ef5758455 899 // DIO0=RxDone, DIO2=FhssChangeChannel
igbt6 0:4e8ef5758455 900 SX1278Write(REG_DIOMAPPING1, (SX1278Read(REG_DIOMAPPING1) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00);
igbt6 0:4e8ef5758455 901 }
igbt6 0:4e8ef5758455 902 else
igbt6 0:4e8ef5758455 903 {
igbt6 0:4e8ef5758455 904 SX1278Write(REG_LR_IRQFLAGSMASK,//RFLR_IRQFLAGS_RXTIMEOUT |
igbt6 0:4e8ef5758455 905 //RFLR_IRQFLAGS_RXDONE |
igbt6 0:4e8ef5758455 906 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
igbt6 0:4e8ef5758455 907 RFLR_IRQFLAGS_VALIDHEADER |
igbt6 0:4e8ef5758455 908 RFLR_IRQFLAGS_TXDONE |
igbt6 0:4e8ef5758455 909 RFLR_IRQFLAGS_CADDONE |
igbt6 0:4e8ef5758455 910 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
igbt6 0:4e8ef5758455 911 RFLR_IRQFLAGS_CADDETECTED);
igbt6 0:4e8ef5758455 912
igbt6 0:4e8ef5758455 913 // DIO0=RxDone
igbt6 0:4e8ef5758455 914 SX1278Write(REG_DIOMAPPING1, (SX1278Read(REG_DIOMAPPING1) & RFLR_DIOMAPPING1_DIO0_MASK) | RFLR_DIOMAPPING1_DIO0_00);
igbt6 0:4e8ef5758455 915 }
igbt6 0:4e8ef5758455 916 SX1278Write(REG_LR_FIFORXBASEADDR, 0);
igbt6 0:4e8ef5758455 917 SX1278Write(REG_LR_FIFOADDRPTR, 0);
igbt6 0:4e8ef5758455 918 }
igbt6 0:4e8ef5758455 919 break;
igbt6 0:4e8ef5758455 920 }
igbt6 0:4e8ef5758455 921
igbt6 0:4e8ef5758455 922 memset(RxTxBuffer, 0, (size_t)RX_BUFFER_SIZE);
igbt6 0:4e8ef5758455 923
igbt6 0:4e8ef5758455 924 settings.State = RF_RX_RUNNING;
igbt6 0:4e8ef5758455 925 if (timeout != 0)
igbt6 0:4e8ef5758455 926 {
igbt6 0:4e8ef5758455 927 SX1278SetTimeout(RXTimeoutTimer, &OnTimeoutIrq, timeout);
igbt6 0:4e8ef5758455 928 }
igbt6 0:4e8ef5758455 929
igbt6 0:4e8ef5758455 930 if (settings.Modem == MODEM_FSK)
igbt6 0:4e8ef5758455 931 {
igbt6 0:4e8ef5758455 932 SX1278SetOpMode(RF_OPMODE_RECEIVER);
igbt6 0:4e8ef5758455 933
igbt6 0:4e8ef5758455 934 if (rxContinuous == false)
igbt6 0:4e8ef5758455 935 {
igbt6 0:4e8ef5758455 936 SX1278SetTimeout(RXTimeoutSyncWordTimer, &OnTimeoutIrq, settings.Fsk.RxSingleTimeout);
igbt6 0:4e8ef5758455 937 }
igbt6 0:4e8ef5758455 938 }
igbt6 0:4e8ef5758455 939 else // MODEM_LORA
igbt6 0:4e8ef5758455 940 {
igbt6 0:4e8ef5758455 941 if (rxContinuous == true)
igbt6 0:4e8ef5758455 942 {
igbt6 0:4e8ef5758455 943 SX1278SetOpMode(RFLR_OPMODE_RECEIVER);
igbt6 0:4e8ef5758455 944 }
igbt6 0:4e8ef5758455 945 else
igbt6 0:4e8ef5758455 946 {
igbt6 0:4e8ef5758455 947 SX1278SetOpMode(RFLR_OPMODE_RECEIVER_SINGLE);
igbt6 0:4e8ef5758455 948 }
igbt6 0:4e8ef5758455 949 }
igbt6 0:4e8ef5758455 950 }
igbt6 0:4e8ef5758455 951
igbt6 0:4e8ef5758455 952 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 953 void SX1278SetTx(uint32_t timeout)
igbt6 0:4e8ef5758455 954 {
igbt6 0:4e8ef5758455 955
igbt6 0:4e8ef5758455 956 switch (settings.Modem)
igbt6 0:4e8ef5758455 957 {
igbt6 0:4e8ef5758455 958 case MODEM_FSK:
igbt6 0:4e8ef5758455 959 {
igbt6 0:4e8ef5758455 960 // DIO0=PacketSent
igbt6 0:4e8ef5758455 961 // DIO1=FifoEmpty
igbt6 0:4e8ef5758455 962 // DIO2=FifoFull
igbt6 0:4e8ef5758455 963 // DIO3=FifoEmpty
igbt6 0:4e8ef5758455 964 // DIO4=LowBat
igbt6 0:4e8ef5758455 965 // DIO5=ModeSX1278Ready
igbt6 0:4e8ef5758455 966 SX1278Write(REG_DIOMAPPING1, (SX1278Read(REG_DIOMAPPING1) & RF_DIOMAPPING1_DIO0_MASK &
igbt6 0:4e8ef5758455 967 RF_DIOMAPPING1_DIO1_MASK &
igbt6 0:4e8ef5758455 968 RF_DIOMAPPING1_DIO2_MASK) |
igbt6 0:4e8ef5758455 969 RF_DIOMAPPING1_DIO1_01);
igbt6 0:4e8ef5758455 970
igbt6 0:4e8ef5758455 971 SX1278Write(REG_DIOMAPPING2, (SX1278Read(REG_DIOMAPPING2) & RF_DIOMAPPING2_DIO4_MASK &
igbt6 0:4e8ef5758455 972 RF_DIOMAPPING2_MAP_MASK));
igbt6 0:4e8ef5758455 973 settings.FskPacketHandler.FifoThresh = SX1278Read(REG_FIFOTHRESH) & 0x3F;
igbt6 0:4e8ef5758455 974 }
igbt6 0:4e8ef5758455 975 break;
igbt6 0:4e8ef5758455 976 case MODEM_LORA:
igbt6 0:4e8ef5758455 977 {
igbt6 0:4e8ef5758455 978 if (settings.LoRa.FreqHopOn == true)
igbt6 0:4e8ef5758455 979 {
igbt6 0:4e8ef5758455 980 SX1278Write(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
igbt6 0:4e8ef5758455 981 RFLR_IRQFLAGS_RXDONE |
igbt6 0:4e8ef5758455 982 RFLR_IRQFLAGS_PAYLOADCRCERROR |
igbt6 0:4e8ef5758455 983 RFLR_IRQFLAGS_VALIDHEADER |
igbt6 0:4e8ef5758455 984 //RFLR_IRQFLAGS_TXDONE |
igbt6 0:4e8ef5758455 985 RFLR_IRQFLAGS_CADDONE |
igbt6 0:4e8ef5758455 986 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
igbt6 0:4e8ef5758455 987 RFLR_IRQFLAGS_CADDETECTED);
igbt6 0:4e8ef5758455 988
igbt6 0:4e8ef5758455 989 // DIO0=TxDone, DIO2=FhssChangeChannel
igbt6 0:4e8ef5758455 990 SX1278Write(REG_DIOMAPPING1, (SX1278Read(REG_DIOMAPPING1) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_00);
igbt6 0:4e8ef5758455 991 }
igbt6 0:4e8ef5758455 992 else
igbt6 0:4e8ef5758455 993 {
igbt6 0:4e8ef5758455 994 SX1278Write(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
igbt6 0:4e8ef5758455 995 RFLR_IRQFLAGS_RXDONE |
igbt6 0:4e8ef5758455 996 RFLR_IRQFLAGS_PAYLOADCRCERROR |
igbt6 0:4e8ef5758455 997 RFLR_IRQFLAGS_VALIDHEADER |
igbt6 0:4e8ef5758455 998 //RFLR_IRQFLAGS_TXDONE |
igbt6 0:4e8ef5758455 999 RFLR_IRQFLAGS_CADDONE |
igbt6 0:4e8ef5758455 1000 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
igbt6 0:4e8ef5758455 1001 RFLR_IRQFLAGS_CADDETECTED);
igbt6 0:4e8ef5758455 1002
igbt6 0:4e8ef5758455 1003 // DIO0=TxDone
igbt6 0:4e8ef5758455 1004 SX1278Write(REG_DIOMAPPING1, (SX1278Read(REG_DIOMAPPING1) & RFLR_DIOMAPPING1_DIO0_MASK) | RFLR_DIOMAPPING1_DIO0_01);
igbt6 0:4e8ef5758455 1005 }
igbt6 0:4e8ef5758455 1006 }
igbt6 0:4e8ef5758455 1007 break;
igbt6 0:4e8ef5758455 1008 }
igbt6 0:4e8ef5758455 1009
igbt6 0:4e8ef5758455 1010 settings.State = RF_TX_RUNNING;
igbt6 0:4e8ef5758455 1011 SX1278SetTimeout(TXTimeoutTimer, &OnTimeoutIrq, timeout);
igbt6 0:4e8ef5758455 1012 SX1278SetOpMode(RF_OPMODE_TRANSMITTER);
igbt6 0:4e8ef5758455 1013 }
igbt6 0:4e8ef5758455 1014
igbt6 0:4e8ef5758455 1015 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1016 void SX1278StartCad(void)
igbt6 0:4e8ef5758455 1017 {
igbt6 0:4e8ef5758455 1018 switch (settings.Modem)
igbt6 0:4e8ef5758455 1019 {
igbt6 0:4e8ef5758455 1020 case MODEM_FSK:
igbt6 0:4e8ef5758455 1021 {
igbt6 0:4e8ef5758455 1022
igbt6 0:4e8ef5758455 1023 }
igbt6 0:4e8ef5758455 1024 break;
igbt6 0:4e8ef5758455 1025 case MODEM_LORA:
igbt6 0:4e8ef5758455 1026 {
igbt6 0:4e8ef5758455 1027 SX1278Write(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
igbt6 0:4e8ef5758455 1028 RFLR_IRQFLAGS_RXDONE |
igbt6 0:4e8ef5758455 1029 RFLR_IRQFLAGS_PAYLOADCRCERROR |
igbt6 0:4e8ef5758455 1030 RFLR_IRQFLAGS_VALIDHEADER |
igbt6 0:4e8ef5758455 1031 RFLR_IRQFLAGS_TXDONE |
igbt6 0:4e8ef5758455 1032 //RFLR_IRQFLAGS_CADDONE |
igbt6 0:4e8ef5758455 1033 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
igbt6 0:4e8ef5758455 1034 //RFLR_IRQFLAGS_CADDETECTED
igbt6 0:4e8ef5758455 1035 );
igbt6 0:4e8ef5758455 1036
igbt6 0:4e8ef5758455 1037 if (dioIrq[3])
igbt6 0:4e8ef5758455 1038 {
igbt6 0:4e8ef5758455 1039 // DIO3=CADDone
igbt6 0:4e8ef5758455 1040 SX1278Write(REG_DIOMAPPING1, (SX1278Read(REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO3_MASK ) | RFLR_DIOMAPPING1_DIO3_00 );
igbt6 0:4e8ef5758455 1041 }
igbt6 0:4e8ef5758455 1042 else
igbt6 0:4e8ef5758455 1043 {
igbt6 0:4e8ef5758455 1044 // DIO0=CADDone
igbt6 0:4e8ef5758455 1045 SX1278Write(REG_DIOMAPPING1, (SX1278Read(REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_10 );
igbt6 0:4e8ef5758455 1046 }
igbt6 0:4e8ef5758455 1047
igbt6 0:4e8ef5758455 1048 settings.State = RF_CAD;
igbt6 0:4e8ef5758455 1049 SX1278SetOpMode(RFLR_OPMODE_CAD);
igbt6 0:4e8ef5758455 1050 }
igbt6 0:4e8ef5758455 1051 break;
igbt6 0:4e8ef5758455 1052 default:
igbt6 0:4e8ef5758455 1053 break;
igbt6 0:4e8ef5758455 1054 }
igbt6 0:4e8ef5758455 1055 }
igbt6 0:4e8ef5758455 1056
igbt6 0:4e8ef5758455 1057 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1058 void SX1278SetTxContinuousWave(uint32_t freq, int8_t power, uint16_t time)
igbt6 0:4e8ef5758455 1059 {
igbt6 0:4e8ef5758455 1060 uint32_t timeout = (uint32_t)(time);
igbt6 0:4e8ef5758455 1061
igbt6 0:4e8ef5758455 1062 SX1278SetChannel(freq);
igbt6 0:4e8ef5758455 1063
igbt6 0:4e8ef5758455 1064 SX1278SetTxConfig(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, timeout);
igbt6 0:4e8ef5758455 1065
igbt6 0:4e8ef5758455 1066 SX1278Write(REG_PACKETCONFIG2, (SX1278Read(REG_PACKETCONFIG2) & RF_PACKETCONFIG2_DATAMODE_MASK));
igbt6 0:4e8ef5758455 1067 // Disable radio interrupts
igbt6 0:4e8ef5758455 1068 SX1278Write(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11);
igbt6 0:4e8ef5758455 1069 SX1278Write(REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10);
igbt6 0:4e8ef5758455 1070
igbt6 0:4e8ef5758455 1071 settings.State = RF_TX_RUNNING;
igbt6 0:4e8ef5758455 1072 SX1278SetTimeout(TXTimeoutTimer, &OnTimeoutIrq, timeout);
igbt6 0:4e8ef5758455 1073 SX1278SetOpMode(RF_OPMODE_TRANSMITTER);
igbt6 0:4e8ef5758455 1074 }
igbt6 0:4e8ef5758455 1075
igbt6 0:4e8ef5758455 1076 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1077 int16_t SX1278GetRssi(RadioModems_t modem)
igbt6 0:4e8ef5758455 1078 {
igbt6 0:4e8ef5758455 1079 int16_t rssi = 0;
igbt6 0:4e8ef5758455 1080
igbt6 0:4e8ef5758455 1081 switch (modem)
igbt6 0:4e8ef5758455 1082 {
igbt6 0:4e8ef5758455 1083 case MODEM_FSK:
igbt6 0:4e8ef5758455 1084 rssi = -(SX1278Read(REG_RSSIVALUE) >> 1);
igbt6 0:4e8ef5758455 1085 break;
igbt6 0:4e8ef5758455 1086 case MODEM_LORA:
igbt6 0:4e8ef5758455 1087 if (settings.Channel > RF_MID_BAND_THRESH)
igbt6 0:4e8ef5758455 1088 {
igbt6 0:4e8ef5758455 1089 rssi = RSSI_OFFSET_HF + SX1278Read(REG_LR_RSSIVALUE);
igbt6 0:4e8ef5758455 1090 }
igbt6 0:4e8ef5758455 1091 else
igbt6 0:4e8ef5758455 1092 {
igbt6 0:4e8ef5758455 1093 rssi = RSSI_OFFSET_LF + SX1278Read(REG_LR_RSSIVALUE);
igbt6 0:4e8ef5758455 1094 }
igbt6 0:4e8ef5758455 1095 break;
igbt6 0:4e8ef5758455 1096 default:
igbt6 0:4e8ef5758455 1097 rssi = -1;
igbt6 0:4e8ef5758455 1098 break;
igbt6 0:4e8ef5758455 1099 }
igbt6 0:4e8ef5758455 1100 return rssi;
igbt6 0:4e8ef5758455 1101 }
igbt6 0:4e8ef5758455 1102
igbt6 0:4e8ef5758455 1103 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1104 int32_t SX1278GetFrequencyError(RadioModems_t modem )
igbt6 0:4e8ef5758455 1105 {
igbt6 0:4e8ef5758455 1106 int32_t val = 0;
igbt6 0:4e8ef5758455 1107
igbt6 0:4e8ef5758455 1108 if (modem != MODEM_LORA)
igbt6 0:4e8ef5758455 1109 return 0;
igbt6 0:4e8ef5758455 1110
igbt6 0:4e8ef5758455 1111 val = (SX1278Read(REG_LR_FEIMSB) & 0b1111) << 16; // high word, 4 valid bits only
igbt6 0:4e8ef5758455 1112 val |= ((SX1278Read(REG_LR_FEIMID) << 8) | SX1278Read(REG_LR_FEILSB)); // high byte, low byte
igbt6 0:4e8ef5758455 1113 if (val & 0x80000) //convert sign bit
igbt6 0:4e8ef5758455 1114 val |= 0xfff00000;
igbt6 0:4e8ef5758455 1115
igbt6 0:4e8ef5758455 1116 int32_t bandwidth = 0;
igbt6 0:4e8ef5758455 1117 for (int i = 0; i < (int)(sizeof(SX1278LoRaBandwidths) / sizeof(BandwidthMap_t)) -1; i++ ) {
igbt6 0:4e8ef5758455 1118 if (SX1278LoRaBandwidths[i].RegValue == settings.LoRa.Bandwidth) {
igbt6 0:4e8ef5758455 1119 bandwidth = SX1278LoRaBandwidths[i].bandwidth;
igbt6 0:4e8ef5758455 1120 break;
igbt6 0:4e8ef5758455 1121 }
igbt6 0:4e8ef5758455 1122 }
igbt6 0:4e8ef5758455 1123 if (!bandwidth)
igbt6 0:4e8ef5758455 1124 return 0;
igbt6 0:4e8ef5758455 1125
igbt6 0:4e8ef5758455 1126 float bandWidthkHz = (float)bandwidth/1000;
igbt6 0:4e8ef5758455 1127
igbt6 0:4e8ef5758455 1128 int32_t hz = (((float)val * (float)(1<<24)) / ((float)XTAL_FREQ)) * (bandWidthkHz / 500.0);
igbt6 0:4e8ef5758455 1129
igbt6 0:4e8ef5758455 1130 return hz;
igbt6 0:4e8ef5758455 1131 }
igbt6 0:4e8ef5758455 1132
igbt6 0:4e8ef5758455 1133 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1134 void SX1278SetOpMode(uint8_t opMode)
igbt6 0:4e8ef5758455 1135 {
igbt6 0:4e8ef5758455 1136 // if(opMode == RF_OPMODE_SLEEP ) // TODO NOT USED on RA-01
igbt6 0:4e8ef5758455 1137 // {
igbt6 0:4e8ef5758455 1138 // SX1278SetAntSwLowPower( true );
igbt6 0:4e8ef5758455 1139 // }
igbt6 0:4e8ef5758455 1140 // else
igbt6 0:4e8ef5758455 1141 // {
igbt6 0:4e8ef5758455 1142 // // Enable TCXO if operating mode different from SLEEP.
igbt6 0:4e8ef5758455 1143 // SX1278SetBoardTcxo( true );
igbt6 0:4e8ef5758455 1144 // SX1278SetAntSwLowPower( false );
igbt6 0:4e8ef5758455 1145 // SX1278SetAntSw( opMode );
igbt6 0:4e8ef5758455 1146 // }
igbt6 0:4e8ef5758455 1147 SX1278Write(REG_OPMODE, (SX1278Read(REG_OPMODE) & RF_OPMODE_MASK) | opMode);
igbt6 0:4e8ef5758455 1148 }
igbt6 0:4e8ef5758455 1149
igbt6 0:4e8ef5758455 1150 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1151 void SX1278SetModem(RadioModems_t modem)
igbt6 0:4e8ef5758455 1152 {
igbt6 0:4e8ef5758455 1153 if ((SX1278Read(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0)
igbt6 0:4e8ef5758455 1154 {
igbt6 0:4e8ef5758455 1155 settings.Modem = MODEM_LORA;
igbt6 0:4e8ef5758455 1156 }
igbt6 0:4e8ef5758455 1157 else
igbt6 0:4e8ef5758455 1158 {
igbt6 0:4e8ef5758455 1159 settings.Modem = MODEM_FSK;
igbt6 0:4e8ef5758455 1160 }
igbt6 0:4e8ef5758455 1161
igbt6 0:4e8ef5758455 1162 if (settings.Modem == modem)
igbt6 0:4e8ef5758455 1163 {
igbt6 0:4e8ef5758455 1164 return;
igbt6 0:4e8ef5758455 1165 }
igbt6 0:4e8ef5758455 1166
igbt6 0:4e8ef5758455 1167 settings.Modem = modem;
igbt6 0:4e8ef5758455 1168 switch (settings.Modem)
igbt6 0:4e8ef5758455 1169 {
igbt6 0:4e8ef5758455 1170 default:
igbt6 0:4e8ef5758455 1171 case MODEM_FSK:
igbt6 0:4e8ef5758455 1172 SX1278SetSleep();
igbt6 0:4e8ef5758455 1173 SX1278Write(REG_OPMODE, (SX1278Read(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) | RFLR_OPMODE_LONGRANGEMODE_OFF);
igbt6 0:4e8ef5758455 1174
igbt6 0:4e8ef5758455 1175 SX1278Write(REG_DIOMAPPING1, 0x00);
igbt6 0:4e8ef5758455 1176 SX1278Write(REG_DIOMAPPING2, 0x30); // DIO5=ModeSX1278Ready
igbt6 0:4e8ef5758455 1177 break;
igbt6 0:4e8ef5758455 1178 case MODEM_LORA:
igbt6 0:4e8ef5758455 1179 SX1278SetSleep();
igbt6 0:4e8ef5758455 1180 SX1278Write(REG_OPMODE, (SX1278Read(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) | RFLR_OPMODE_LONGRANGEMODE_ON);
igbt6 0:4e8ef5758455 1181
igbt6 0:4e8ef5758455 1182 SX1278Write(REG_DIOMAPPING1, 0x00);
igbt6 0:4e8ef5758455 1183 SX1278Write(REG_DIOMAPPING2, 0x00);
igbt6 0:4e8ef5758455 1184 break;
igbt6 0:4e8ef5758455 1185 }
igbt6 0:4e8ef5758455 1186 }
igbt6 0:4e8ef5758455 1187
igbt6 0:4e8ef5758455 1188 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1189 void SX1278SetMaxPayloadLength(RadioModems_t modem, uint8_t max)
igbt6 0:4e8ef5758455 1190 {
igbt6 0:4e8ef5758455 1191 SX1278SetModem(modem);
igbt6 0:4e8ef5758455 1192
igbt6 0:4e8ef5758455 1193 switch (modem)
igbt6 0:4e8ef5758455 1194 {
igbt6 0:4e8ef5758455 1195 case MODEM_FSK:
igbt6 0:4e8ef5758455 1196 if (settings.Fsk.FixLen == false)
igbt6 0:4e8ef5758455 1197 {
igbt6 0:4e8ef5758455 1198 SX1278Write(REG_PAYLOADLENGTH, max);
igbt6 0:4e8ef5758455 1199 }
igbt6 0:4e8ef5758455 1200 break;
igbt6 0:4e8ef5758455 1201 case MODEM_LORA:
igbt6 0:4e8ef5758455 1202 SX1278Write(REG_LR_PAYLOADMAXLENGTH, max);
igbt6 0:4e8ef5758455 1203 break;
igbt6 0:4e8ef5758455 1204 }
igbt6 0:4e8ef5758455 1205 }
igbt6 0:4e8ef5758455 1206
igbt6 0:4e8ef5758455 1207 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1208 void SX1278SetPublicNetwork(bool enable)
igbt6 0:4e8ef5758455 1209 {
igbt6 0:4e8ef5758455 1210 SX1278SetModem(MODEM_LORA);
igbt6 0:4e8ef5758455 1211 settings.LoRa.PublicNetwork = enable;
igbt6 0:4e8ef5758455 1212 if (enable == true)
igbt6 0:4e8ef5758455 1213 {
igbt6 0:4e8ef5758455 1214 // Change LoRa modem SyncWord
igbt6 0:4e8ef5758455 1215 SX1278Write(REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD);
igbt6 0:4e8ef5758455 1216 }
igbt6 0:4e8ef5758455 1217 else
igbt6 0:4e8ef5758455 1218 {
igbt6 0:4e8ef5758455 1219 // Change LoRa modem SyncWord
igbt6 0:4e8ef5758455 1220 SX1278Write(REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD);
igbt6 0:4e8ef5758455 1221 }
igbt6 0:4e8ef5758455 1222 }
igbt6 0:4e8ef5758455 1223
igbt6 0:4e8ef5758455 1224 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1225 void OnTimeoutIrq()
igbt6 0:4e8ef5758455 1226 {
igbt6 0:4e8ef5758455 1227 switch (settings.State)
igbt6 0:4e8ef5758455 1228 {
igbt6 0:4e8ef5758455 1229 case RF_RX_RUNNING:
igbt6 0:4e8ef5758455 1230 if (settings.Modem == MODEM_FSK)
igbt6 0:4e8ef5758455 1231 {
igbt6 0:4e8ef5758455 1232 settings.FskPacketHandler.PreambleDetected = false;
igbt6 0:4e8ef5758455 1233 settings.FskPacketHandler.SyncWordDetected = false;
igbt6 0:4e8ef5758455 1234 settings.FskPacketHandler.NbBytes = 0;
igbt6 0:4e8ef5758455 1235 settings.FskPacketHandler.Size = 0;
igbt6 0:4e8ef5758455 1236
igbt6 0:4e8ef5758455 1237 // Clear Irqs
igbt6 0:4e8ef5758455 1238 SX1278Write(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
igbt6 0:4e8ef5758455 1239 RF_IRQFLAGS1_PREAMBLEDETECT |
igbt6 0:4e8ef5758455 1240 RF_IRQFLAGS1_SYNCADDRESSMATCH);
igbt6 0:4e8ef5758455 1241 SX1278Write(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);
igbt6 0:4e8ef5758455 1242
igbt6 0:4e8ef5758455 1243 if (settings.Fsk.RxContinuous == true)
igbt6 0:4e8ef5758455 1244 {
igbt6 0:4e8ef5758455 1245 // Continuous mode restart Rx chain
igbt6 0:4e8ef5758455 1246 SX1278Write(REG_RXCONFIG, SX1278Read(REG_RXCONFIG) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
igbt6 0:4e8ef5758455 1247 SX1278SetTimeout(RXTimeoutSyncWordTimer, &OnTimeoutIrq, settings.Fsk.RxSingleTimeout);
igbt6 0:4e8ef5758455 1248 }
igbt6 0:4e8ef5758455 1249 else
igbt6 0:4e8ef5758455 1250 {
igbt6 0:4e8ef5758455 1251 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 1252 SX1278SetTimeout(RXTimeoutSyncWordTimer, NULL, 0);
igbt6 0:4e8ef5758455 1253 }
igbt6 0:4e8ef5758455 1254 }
igbt6 0:4e8ef5758455 1255 if ((RadioEvents != NULL) && (RadioEvents->RxTimeout != NULL))
igbt6 0:4e8ef5758455 1256 {
igbt6 0:4e8ef5758455 1257 RadioEvents->RxTimeout();
igbt6 0:4e8ef5758455 1258 }
igbt6 0:4e8ef5758455 1259 break;
igbt6 0:4e8ef5758455 1260 case RF_TX_RUNNING:
igbt6 0:4e8ef5758455 1261 // Tx timeout shouldn't happen.
igbt6 0:4e8ef5758455 1262 // But it has been observed that when it happens it is a result of a corrupted SPI transfer
igbt6 0:4e8ef5758455 1263 // it depends on the platform design.
igbt6 0:4e8ef5758455 1264 //
igbt6 0:4e8ef5758455 1265 // The workaround is to put the radio in a known state. Thus, we re-initialize it.
igbt6 0:4e8ef5758455 1266
igbt6 0:4e8ef5758455 1267 // BEGIN WORKAROUND
igbt6 0:4e8ef5758455 1268
igbt6 0:4e8ef5758455 1269 // Reset the radio
igbt6 0:4e8ef5758455 1270 SX1278Reset();
igbt6 0:4e8ef5758455 1271
igbt6 0:4e8ef5758455 1272 // Calibrate Rx chain
igbt6 0:4e8ef5758455 1273 RxChainCalibration();
igbt6 0:4e8ef5758455 1274
igbt6 0:4e8ef5758455 1275 // Initialize radio default values
igbt6 0:4e8ef5758455 1276 SX1278SetOpMode(RF_OPMODE_SLEEP);
igbt6 0:4e8ef5758455 1277 SX1278RadioRegistersInit();
igbt6 0:4e8ef5758455 1278
igbt6 0:4e8ef5758455 1279 SX1278SetModem(MODEM_FSK);
igbt6 0:4e8ef5758455 1280
igbt6 0:4e8ef5758455 1281 // Restore previous network type setting.
igbt6 0:4e8ef5758455 1282 SX1278SetPublicNetwork(settings.LoRa.PublicNetwork);
igbt6 0:4e8ef5758455 1283 // END WORKAROUND
igbt6 0:4e8ef5758455 1284
igbt6 0:4e8ef5758455 1285 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 1286 if ((RadioEvents != NULL) && (RadioEvents->TxTimeout != NULL))
igbt6 0:4e8ef5758455 1287 {
igbt6 0:4e8ef5758455 1288 RadioEvents->TxTimeout();
igbt6 0:4e8ef5758455 1289 }
igbt6 0:4e8ef5758455 1290 break;
igbt6 0:4e8ef5758455 1291 default:
igbt6 0:4e8ef5758455 1292 break;
igbt6 0:4e8ef5758455 1293 }
igbt6 0:4e8ef5758455 1294 }
igbt6 0:4e8ef5758455 1295
igbt6 0:4e8ef5758455 1296 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1297 void SX1278SetRfTxPower(int8_t power)
igbt6 0:4e8ef5758455 1298 {
igbt6 0:4e8ef5758455 1299 uint8_t paConfig = 0;
igbt6 0:4e8ef5758455 1300 uint8_t paDac = 0;
igbt6 0:4e8ef5758455 1301
igbt6 0:4e8ef5758455 1302 paConfig = SX1278Read(REG_PACONFIG);
igbt6 0:4e8ef5758455 1303 paDac = SX1278Read(REG_PADAC);
igbt6 0:4e8ef5758455 1304
igbt6 0:4e8ef5758455 1305 paConfig = (paConfig & RF_PACONFIG_PASELECT_MASK) | SX1278GetPaSelect(settings.Channel);
igbt6 0:4e8ef5758455 1306 paConfig = (paConfig & RF_PACONFIG_MAX_POWER_MASK) | 0x70;
igbt6 0:4e8ef5758455 1307
igbt6 0:4e8ef5758455 1308 if((paConfig & RF_PACONFIG_PASELECT_PABOOST) == RF_PACONFIG_PASELECT_PABOOST)
igbt6 0:4e8ef5758455 1309 {
igbt6 0:4e8ef5758455 1310 if(power > 17)
igbt6 0:4e8ef5758455 1311 {
igbt6 0:4e8ef5758455 1312 paDac = (paDac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_ON;
igbt6 0:4e8ef5758455 1313 }
igbt6 0:4e8ef5758455 1314 else
igbt6 0:4e8ef5758455 1315 {
igbt6 0:4e8ef5758455 1316 paDac = (paDac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_OFF;
igbt6 0:4e8ef5758455 1317 }
igbt6 0:4e8ef5758455 1318 if((paDac & RF_PADAC_20DBM_ON) == RF_PADAC_20DBM_ON)
igbt6 0:4e8ef5758455 1319 {
igbt6 0:4e8ef5758455 1320 if(power < 5)
igbt6 0:4e8ef5758455 1321 {
igbt6 0:4e8ef5758455 1322 power = 5;
igbt6 0:4e8ef5758455 1323 }
igbt6 0:4e8ef5758455 1324 if(power > 20)
igbt6 0:4e8ef5758455 1325 {
igbt6 0:4e8ef5758455 1326 power = 20;
igbt6 0:4e8ef5758455 1327 }
igbt6 0:4e8ef5758455 1328 paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) | (uint8_t)((uint16_t)(power - 5) & 0x0F);
igbt6 0:4e8ef5758455 1329 }
igbt6 0:4e8ef5758455 1330 else
igbt6 0:4e8ef5758455 1331 {
igbt6 0:4e8ef5758455 1332 if(power < 2)
igbt6 0:4e8ef5758455 1333 {
igbt6 0:4e8ef5758455 1334 power = 2;
igbt6 0:4e8ef5758455 1335 }
igbt6 0:4e8ef5758455 1336 if(power > 17)
igbt6 0:4e8ef5758455 1337 {
igbt6 0:4e8ef5758455 1338 power = 17;
igbt6 0:4e8ef5758455 1339 }
igbt6 0:4e8ef5758455 1340 paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) | (uint8_t)((uint16_t)(power - 2) & 0x0F);
igbt6 0:4e8ef5758455 1341 }
igbt6 0:4e8ef5758455 1342 }
igbt6 0:4e8ef5758455 1343 else
igbt6 0:4e8ef5758455 1344 {
igbt6 0:4e8ef5758455 1345 if(power < -1)
igbt6 0:4e8ef5758455 1346 {
igbt6 0:4e8ef5758455 1347 power = -1;
igbt6 0:4e8ef5758455 1348 }
igbt6 0:4e8ef5758455 1349 if(power > 14)
igbt6 0:4e8ef5758455 1350 {
igbt6 0:4e8ef5758455 1351 power = 14;
igbt6 0:4e8ef5758455 1352 }
igbt6 0:4e8ef5758455 1353 paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) | (uint8_t)((uint16_t)(power + 1) & 0x0F);
igbt6 0:4e8ef5758455 1354 }
igbt6 0:4e8ef5758455 1355 SX1278Write(REG_PACONFIG, paConfig);
igbt6 0:4e8ef5758455 1356 SX1278Write(REG_PADAC, paDac);
igbt6 0:4e8ef5758455 1357 }
igbt6 0:4e8ef5758455 1358
igbt6 0:4e8ef5758455 1359 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1360 uint8_t SX1278GetPaSelect(uint32_t channel)
igbt6 0:4e8ef5758455 1361 {
igbt6 0:4e8ef5758455 1362 if(channel > RF_MID_BAND_THRESH)
igbt6 0:4e8ef5758455 1363 {
igbt6 0:4e8ef5758455 1364 return RF_PACONFIG_PASELECT_PABOOST;
igbt6 0:4e8ef5758455 1365 }
igbt6 0:4e8ef5758455 1366 else
igbt6 0:4e8ef5758455 1367 {
igbt6 0:4e8ef5758455 1368 return RF_PACONFIG_PASELECT_RFO;
igbt6 0:4e8ef5758455 1369 }
igbt6 0:4e8ef5758455 1370 }
igbt6 0:4e8ef5758455 1371
igbt6 0:4e8ef5758455 1372 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1373 bool SX1278CheckRfFrequency(uint32_t frequency)
igbt6 0:4e8ef5758455 1374 {
igbt6 0:4e8ef5758455 1375 // Implement check. Currently all frequencies are supported
igbt6 0:4e8ef5758455 1376 return true;
igbt6 0:4e8ef5758455 1377 }
igbt6 0:4e8ef5758455 1378
igbt6 0:4e8ef5758455 1379 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1380 void SX1278Write(uint8_t addr, uint8_t data)
igbt6 0:4e8ef5758455 1381 {
igbt6 0:4e8ef5758455 1382 SX1278WriteBuffer(addr, &data, 1);
igbt6 0:4e8ef5758455 1383 }
igbt6 0:4e8ef5758455 1384
igbt6 0:4e8ef5758455 1385 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1386 uint8_t SX1278Read(uint8_t addr)
igbt6 0:4e8ef5758455 1387 {
igbt6 0:4e8ef5758455 1388 uint8_t data;
igbt6 0:4e8ef5758455 1389 SX1278ReadBuffer(addr, &data, 1);
igbt6 0:4e8ef5758455 1390 return data;
igbt6 0:4e8ef5758455 1391 }
igbt6 0:4e8ef5758455 1392
igbt6 0:4e8ef5758455 1393 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1394 void SX1278WriteFifo(uint8_t *buffer, uint8_t size)
igbt6 0:4e8ef5758455 1395 {
igbt6 0:4e8ef5758455 1396 SX1278WriteBuffer(0, buffer, size);
igbt6 0:4e8ef5758455 1397 }
igbt6 0:4e8ef5758455 1398
igbt6 0:4e8ef5758455 1399 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1400 void SX1278ReadFifo(uint8_t *buffer, uint8_t size)
igbt6 0:4e8ef5758455 1401 {
igbt6 0:4e8ef5758455 1402 SX1278ReadBuffer(0, buffer, size);
igbt6 0:4e8ef5758455 1403 }
igbt6 0:4e8ef5758455 1404
igbt6 0:4e8ef5758455 1405
igbt6 0:4e8ef5758455 1406 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1407
igbt6 0:4e8ef5758455 1408
igbt6 0:4e8ef5758455 1409
igbt6 0:4e8ef5758455 1410 /**
igbt6 0:4e8ef5758455 1411 * ============================================================================
igbt6 0:4e8ef5758455 1412 * @brief Private functions definitions
igbt6 0:4e8ef5758455 1413 * ============================================================================
igbt6 0:4e8ef5758455 1414 */
igbt6 0:4e8ef5758455 1415 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1416 void RxChainCalibration(void)
igbt6 0:4e8ef5758455 1417 {
igbt6 0:4e8ef5758455 1418 uint8_t regPaConfigInitVal;
igbt6 0:4e8ef5758455 1419 uint32_t initialFreq;
igbt6 0:4e8ef5758455 1420
igbt6 0:4e8ef5758455 1421 // Save context
igbt6 0:4e8ef5758455 1422 regPaConfigInitVal = SX1278Read(REG_PACONFIG);
igbt6 0:4e8ef5758455 1423 initialFreq = (double)(((uint32_t)SX1278Read(REG_FRFMSB) << 16) |
igbt6 0:4e8ef5758455 1424 ((uint32_t)SX1278Read(REG_FRFMID) << 8) |
igbt6 0:4e8ef5758455 1425 ((uint32_t)SX1278Read(REG_FRFLSB))) * (double)FREQ_STEP;
igbt6 0:4e8ef5758455 1426
igbt6 0:4e8ef5758455 1427 // Cut the PA just in case, RFO output, power = -1 dBm
igbt6 0:4e8ef5758455 1428 SX1278Write(REG_PACONFIG, 0x00);
igbt6 0:4e8ef5758455 1429
igbt6 0:4e8ef5758455 1430 // Launch Rx chain calibration for LF band
igbt6 0:4e8ef5758455 1431 SX1278Write (REG_IMAGECAL, (SX1278Read(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_MASK) | RF_IMAGECAL_IMAGECAL_START);
igbt6 0:4e8ef5758455 1432 while((SX1278Read(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING)
igbt6 0:4e8ef5758455 1433 {
igbt6 0:4e8ef5758455 1434 }
igbt6 0:4e8ef5758455 1435
igbt6 0:4e8ef5758455 1436 // Sets a Frequency in HF band
igbt6 0:4e8ef5758455 1437 SX1278SetChannel(868000000);
igbt6 0:4e8ef5758455 1438
igbt6 0:4e8ef5758455 1439 // Launch Rx chain calibration for HF band
igbt6 0:4e8ef5758455 1440 SX1278Write(REG_IMAGECAL, (SX1278Read(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_MASK) | RF_IMAGECAL_IMAGECAL_START);
igbt6 0:4e8ef5758455 1441 while((SX1278Read(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING)
igbt6 0:4e8ef5758455 1442 {
igbt6 0:4e8ef5758455 1443 }
igbt6 0:4e8ef5758455 1444
igbt6 0:4e8ef5758455 1445 // Restore context
igbt6 0:4e8ef5758455 1446 SX1278Write(REG_PACONFIG, regPaConfigInitVal);
igbt6 0:4e8ef5758455 1447 SX1278SetChannel(initialFreq);
igbt6 0:4e8ef5758455 1448 }
igbt6 0:4e8ef5758455 1449
igbt6 0:4e8ef5758455 1450 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1451 uint8_t GetFskBandwidthRegValue(uint32_t bandwidth)
igbt6 0:4e8ef5758455 1452 {
igbt6 0:4e8ef5758455 1453 uint8_t i;
igbt6 0:4e8ef5758455 1454
igbt6 0:4e8ef5758455 1455 for (i = 0; i < (sizeof(SX1278FskBandwidths) / sizeof(BandwidthMap_t)) - 1; i++)
igbt6 0:4e8ef5758455 1456 {
igbt6 0:4e8ef5758455 1457 if ((bandwidth >= SX1278FskBandwidths[i].bandwidth) && (bandwidth < SX1278FskBandwidths[i + 1].bandwidth))
igbt6 0:4e8ef5758455 1458 {
igbt6 0:4e8ef5758455 1459 return SX1278FskBandwidths[i].RegValue;
igbt6 0:4e8ef5758455 1460 }
igbt6 0:4e8ef5758455 1461 }
igbt6 0:4e8ef5758455 1462 // ERROR: Value not found
igbt6 0:4e8ef5758455 1463 while(1);
igbt6 0:4e8ef5758455 1464 }
igbt6 0:4e8ef5758455 1465
igbt6 0:4e8ef5758455 1466 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1467 uint8_t GetLoRaBandwidthRegValue(uint32_t bandwidth)
igbt6 0:4e8ef5758455 1468 {
igbt6 0:4e8ef5758455 1469 uint8_t i;
igbt6 0:4e8ef5758455 1470
igbt6 0:4e8ef5758455 1471 for (i = 0; i < (sizeof(SX1278LoRaBandwidths) / sizeof(BandwidthMap_t)) - 1; i++)
igbt6 0:4e8ef5758455 1472 {
igbt6 0:4e8ef5758455 1473 if ((bandwidth >= SX1278LoRaBandwidths[i].bandwidth) && (bandwidth < SX1278LoRaBandwidths[i + 1].bandwidth))
igbt6 0:4e8ef5758455 1474 {
igbt6 0:4e8ef5758455 1475 return SX1278LoRaBandwidths[i].RegValue;
igbt6 0:4e8ef5758455 1476 }
igbt6 0:4e8ef5758455 1477 }
igbt6 0:4e8ef5758455 1478 // ERROR: Value not found
igbt6 0:4e8ef5758455 1479 while(1);
igbt6 0:4e8ef5758455 1480 }
igbt6 0:4e8ef5758455 1481
igbt6 0:4e8ef5758455 1482 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1483 void OnDio0Irq()
igbt6 0:4e8ef5758455 1484 {
igbt6 0:4e8ef5758455 1485 volatile uint8_t irqFlags = 0;
igbt6 0:4e8ef5758455 1486
igbt6 0:4e8ef5758455 1487 switch (settings.State)
igbt6 0:4e8ef5758455 1488 {
igbt6 0:4e8ef5758455 1489 case RF_RX_RUNNING:
igbt6 0:4e8ef5758455 1490 //TimerStop(&RxTimeoutTimer);
igbt6 0:4e8ef5758455 1491 // RxDone interrupt
igbt6 0:4e8ef5758455 1492 switch (settings.Modem)
igbt6 0:4e8ef5758455 1493 {
igbt6 0:4e8ef5758455 1494 case MODEM_FSK:
igbt6 0:4e8ef5758455 1495 if (settings.Fsk.CrcOn == true)
igbt6 0:4e8ef5758455 1496 {
igbt6 0:4e8ef5758455 1497 irqFlags = SX1278Read(REG_IRQFLAGS2);
igbt6 0:4e8ef5758455 1498 if ((irqFlags & RF_IRQFLAGS2_CRCOK) != RF_IRQFLAGS2_CRCOK)
igbt6 0:4e8ef5758455 1499 {
igbt6 0:4e8ef5758455 1500 // Clear Irqs
igbt6 0:4e8ef5758455 1501 SX1278Write(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
igbt6 0:4e8ef5758455 1502 RF_IRQFLAGS1_PREAMBLEDETECT |
igbt6 0:4e8ef5758455 1503 RF_IRQFLAGS1_SYNCADDRESSMATCH);
igbt6 0:4e8ef5758455 1504 SX1278Write(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);
igbt6 0:4e8ef5758455 1505
igbt6 0:4e8ef5758455 1506 SX1278SetTimeout(RXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 1507
igbt6 0:4e8ef5758455 1508 if (settings.Fsk.RxContinuous == false)
igbt6 0:4e8ef5758455 1509 {
igbt6 0:4e8ef5758455 1510 SX1278SetTimeout(RXTimeoutSyncWordTimer, NULL, 0);
igbt6 0:4e8ef5758455 1511 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 1512 }
igbt6 0:4e8ef5758455 1513 else
igbt6 0:4e8ef5758455 1514 {
igbt6 0:4e8ef5758455 1515 // Continuous mode restart Rx chain
igbt6 0:4e8ef5758455 1516 SX1278Write(REG_RXCONFIG, SX1278Read(REG_RXCONFIG) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
igbt6 0:4e8ef5758455 1517 SX1278SetTimeout(RXTimeoutSyncWordTimer, &OnTimeoutIrq, settings.Fsk.RxSingleTimeout);
igbt6 0:4e8ef5758455 1518 }
igbt6 0:4e8ef5758455 1519
igbt6 0:4e8ef5758455 1520 if ((RadioEvents != NULL) && (RadioEvents->RxError != NULL))
igbt6 0:4e8ef5758455 1521 {
igbt6 0:4e8ef5758455 1522 RadioEvents->RxError();
igbt6 0:4e8ef5758455 1523 }
igbt6 0:4e8ef5758455 1524 settings.FskPacketHandler.PreambleDetected = false;
igbt6 0:4e8ef5758455 1525 settings.FskPacketHandler.SyncWordDetected = false;
igbt6 0:4e8ef5758455 1526 settings.FskPacketHandler.NbBytes = 0;
igbt6 0:4e8ef5758455 1527 settings.FskPacketHandler.Size = 0;
igbt6 0:4e8ef5758455 1528 break;
igbt6 0:4e8ef5758455 1529 }
igbt6 0:4e8ef5758455 1530 }
igbt6 0:4e8ef5758455 1531
igbt6 0:4e8ef5758455 1532 // SX1278Read received packet size
igbt6 0:4e8ef5758455 1533 if ((settings.FskPacketHandler.Size == 0) && (settings.FskPacketHandler.NbBytes == 0))
igbt6 0:4e8ef5758455 1534 {
igbt6 0:4e8ef5758455 1535 if (settings.Fsk.FixLen == false)
igbt6 0:4e8ef5758455 1536 {
igbt6 0:4e8ef5758455 1537 SX1278ReadFifo((uint8_t*)&settings.FskPacketHandler.Size, 1);
igbt6 0:4e8ef5758455 1538 }
igbt6 0:4e8ef5758455 1539 else
igbt6 0:4e8ef5758455 1540 {
igbt6 0:4e8ef5758455 1541 settings.FskPacketHandler.Size = SX1278Read(REG_PAYLOADLENGTH);
igbt6 0:4e8ef5758455 1542 }
igbt6 0:4e8ef5758455 1543 SX1278ReadFifo(RxTxBuffer + settings.FskPacketHandler.NbBytes, settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes);
igbt6 0:4e8ef5758455 1544 settings.FskPacketHandler.NbBytes += (settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes);
igbt6 0:4e8ef5758455 1545 }
igbt6 0:4e8ef5758455 1546 else
igbt6 0:4e8ef5758455 1547 {
igbt6 0:4e8ef5758455 1548 SX1278ReadFifo(RxTxBuffer + settings.FskPacketHandler.NbBytes, settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes);
igbt6 0:4e8ef5758455 1549 settings.FskPacketHandler.NbBytes += (settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes);
igbt6 0:4e8ef5758455 1550 }
igbt6 0:4e8ef5758455 1551
igbt6 0:4e8ef5758455 1552 SX1278SetTimeout(RXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 1553
igbt6 0:4e8ef5758455 1554 if (settings.Fsk.RxContinuous == false)
igbt6 0:4e8ef5758455 1555 {
igbt6 0:4e8ef5758455 1556 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 1557 SX1278SetTimeout(RXTimeoutSyncWordTimer, NULL, 0);
igbt6 0:4e8ef5758455 1558 }
igbt6 0:4e8ef5758455 1559 else
igbt6 0:4e8ef5758455 1560 {
igbt6 0:4e8ef5758455 1561 // Continuous mode restart Rx chain
igbt6 0:4e8ef5758455 1562 SX1278Write(REG_RXCONFIG, SX1278Read(REG_RXCONFIG) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
igbt6 0:4e8ef5758455 1563 SX1278SetTimeout(RXTimeoutSyncWordTimer, &OnTimeoutIrq, settings.Fsk.RxSingleTimeout);
igbt6 0:4e8ef5758455 1564 }
igbt6 0:4e8ef5758455 1565
igbt6 0:4e8ef5758455 1566 if ((RadioEvents != NULL) && (RadioEvents->RxDone != NULL))
igbt6 0:4e8ef5758455 1567 {
igbt6 0:4e8ef5758455 1568 RadioEvents->RxDone(RxTxBuffer, settings.FskPacketHandler.Size, settings.FskPacketHandler.RssiValue, 0);
igbt6 0:4e8ef5758455 1569 }
igbt6 0:4e8ef5758455 1570 settings.FskPacketHandler.PreambleDetected = false;
igbt6 0:4e8ef5758455 1571 settings.FskPacketHandler.SyncWordDetected = false;
igbt6 0:4e8ef5758455 1572 settings.FskPacketHandler.NbBytes = 0;
igbt6 0:4e8ef5758455 1573 settings.FskPacketHandler.Size = 0;
igbt6 0:4e8ef5758455 1574 break;
igbt6 0:4e8ef5758455 1575 case MODEM_LORA:
igbt6 0:4e8ef5758455 1576 {
igbt6 0:4e8ef5758455 1577 // Clear Irq
igbt6 0:4e8ef5758455 1578 SX1278Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE);
igbt6 0:4e8ef5758455 1579
igbt6 0:4e8ef5758455 1580 irqFlags = SX1278Read(REG_LR_IRQFLAGS);
igbt6 0:4e8ef5758455 1581 if ((irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK) == RFLR_IRQFLAGS_PAYLOADCRCERROR)
igbt6 0:4e8ef5758455 1582 {
igbt6 0:4e8ef5758455 1583 // Clear Irq
igbt6 0:4e8ef5758455 1584 SX1278Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR);
igbt6 0:4e8ef5758455 1585
igbt6 0:4e8ef5758455 1586 if (settings.LoRa.RxContinuous == false)
igbt6 0:4e8ef5758455 1587 {
igbt6 0:4e8ef5758455 1588 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 1589 }
igbt6 0:4e8ef5758455 1590 SX1278SetTimeout(RXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 1591
igbt6 0:4e8ef5758455 1592 if ((RadioEvents != NULL) && (RadioEvents->RxError != NULL))
igbt6 0:4e8ef5758455 1593 {
igbt6 0:4e8ef5758455 1594 RadioEvents->RxError();
igbt6 0:4e8ef5758455 1595 }
igbt6 0:4e8ef5758455 1596 break;
igbt6 0:4e8ef5758455 1597 }
igbt6 0:4e8ef5758455 1598 // Returns SNR value [dB] rounded to the nearest integer value
igbt6 0:4e8ef5758455 1599 settings.LoRaPacketHandler.SnrValue = (((int8_t)SX1278Read(REG_LR_PKTSNRVALUE)) + 2) >> 2;
igbt6 0:4e8ef5758455 1600 int16_t rssi = SX1278Read(REG_LR_PKTRSSIVALUE);
igbt6 0:4e8ef5758455 1601 if (settings.LoRaPacketHandler.SnrValue < 0)
igbt6 0:4e8ef5758455 1602 {
igbt6 0:4e8ef5758455 1603 if (settings.Channel > RF_MID_BAND_THRESH)
igbt6 0:4e8ef5758455 1604 {
igbt6 0:4e8ef5758455 1605 settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 ) +
igbt6 0:4e8ef5758455 1606 settings.LoRaPacketHandler.SnrValue;
igbt6 0:4e8ef5758455 1607 }
igbt6 0:4e8ef5758455 1608 else
igbt6 0:4e8ef5758455 1609 {
igbt6 0:4e8ef5758455 1610 settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 ) +
igbt6 0:4e8ef5758455 1611 settings.LoRaPacketHandler.SnrValue;
igbt6 0:4e8ef5758455 1612 }
igbt6 0:4e8ef5758455 1613 }
igbt6 0:4e8ef5758455 1614 else
igbt6 0:4e8ef5758455 1615 {
igbt6 0:4e8ef5758455 1616 if(settings.Channel > RF_MID_BAND_THRESH)
igbt6 0:4e8ef5758455 1617 {
igbt6 0:4e8ef5758455 1618 settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 );
igbt6 0:4e8ef5758455 1619 }
igbt6 0:4e8ef5758455 1620 else
igbt6 0:4e8ef5758455 1621 {
igbt6 0:4e8ef5758455 1622 settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 );
igbt6 0:4e8ef5758455 1623 }
igbt6 0:4e8ef5758455 1624 }
igbt6 0:4e8ef5758455 1625
igbt6 0:4e8ef5758455 1626 settings.LoRaPacketHandler.Size = SX1278Read( REG_LR_RXNBBYTES);
igbt6 0:4e8ef5758455 1627 SX1278Write( REG_LR_FIFOADDRPTR, SX1278Read( REG_LR_FIFORXCURRENTADDR));
igbt6 0:4e8ef5758455 1628 SX1278ReadFifo( RxTxBuffer, settings.LoRaPacketHandler.Size);
igbt6 0:4e8ef5758455 1629
igbt6 0:4e8ef5758455 1630 if(settings.LoRa.RxContinuous == false)
igbt6 0:4e8ef5758455 1631 {
igbt6 0:4e8ef5758455 1632 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 1633 }
igbt6 0:4e8ef5758455 1634
igbt6 0:4e8ef5758455 1635 SX1278SetTimeout(RXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 1636
igbt6 0:4e8ef5758455 1637 if ((RadioEvents != NULL) && (RadioEvents->RxDone != NULL))
igbt6 0:4e8ef5758455 1638 {
igbt6 0:4e8ef5758455 1639 RadioEvents->RxDone(RxTxBuffer, settings.LoRaPacketHandler.Size, settings.LoRaPacketHandler.RssiValue, settings.LoRaPacketHandler.SnrValue);
igbt6 0:4e8ef5758455 1640 }
igbt6 0:4e8ef5758455 1641 }
igbt6 0:4e8ef5758455 1642 break;
igbt6 0:4e8ef5758455 1643 default:
igbt6 0:4e8ef5758455 1644 break;
igbt6 0:4e8ef5758455 1645 }
igbt6 0:4e8ef5758455 1646 break;
igbt6 0:4e8ef5758455 1647 case RF_TX_RUNNING:
igbt6 0:4e8ef5758455 1648 SX1278SetTimeout(TXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 1649 // TxDone interrupt
igbt6 0:4e8ef5758455 1650 switch (settings.Modem)
igbt6 0:4e8ef5758455 1651 {
igbt6 0:4e8ef5758455 1652 case MODEM_LORA:
igbt6 0:4e8ef5758455 1653 // Clear Irq
igbt6 0:4e8ef5758455 1654 SX1278Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE);
igbt6 0:4e8ef5758455 1655 // Intentional fall through
igbt6 0:4e8ef5758455 1656 case MODEM_FSK:
igbt6 0:4e8ef5758455 1657 default:
igbt6 0:4e8ef5758455 1658 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 1659 if ((RadioEvents != NULL) && (RadioEvents->TxDone != NULL))
igbt6 0:4e8ef5758455 1660 {
igbt6 0:4e8ef5758455 1661 RadioEvents->TxDone();
igbt6 0:4e8ef5758455 1662 }
igbt6 0:4e8ef5758455 1663 break;
igbt6 0:4e8ef5758455 1664 }
igbt6 0:4e8ef5758455 1665 break;
igbt6 0:4e8ef5758455 1666 default:
igbt6 0:4e8ef5758455 1667 break;
igbt6 0:4e8ef5758455 1668 }
igbt6 0:4e8ef5758455 1669 }
igbt6 0:4e8ef5758455 1670
igbt6 0:4e8ef5758455 1671 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1672 void OnDio1Irq()
igbt6 0:4e8ef5758455 1673 {
igbt6 0:4e8ef5758455 1674 switch (settings.State)
igbt6 0:4e8ef5758455 1675 {
igbt6 0:4e8ef5758455 1676 case RF_RX_RUNNING:
igbt6 0:4e8ef5758455 1677 switch (settings.Modem)
igbt6 0:4e8ef5758455 1678 {
igbt6 0:4e8ef5758455 1679 case MODEM_FSK:
igbt6 0:4e8ef5758455 1680 // Stop Timer
igbt6 0:4e8ef5758455 1681 SX1278SetTimeout(RXTimeoutSyncWordTimer, NULL, 0);
igbt6 0:4e8ef5758455 1682
igbt6 0:4e8ef5758455 1683 // FifoLevel interrupt
igbt6 0:4e8ef5758455 1684 // SX1278Read received packet size
igbt6 0:4e8ef5758455 1685 if ((settings.FskPacketHandler.Size == 0) && (settings.FskPacketHandler.NbBytes == 0))
igbt6 0:4e8ef5758455 1686 {
igbt6 0:4e8ef5758455 1687 if (settings.Fsk.FixLen == false)
igbt6 0:4e8ef5758455 1688 {
igbt6 0:4e8ef5758455 1689 SX1278ReadFifo((uint8_t*)&settings.FskPacketHandler.Size, 1);
igbt6 0:4e8ef5758455 1690 }
igbt6 0:4e8ef5758455 1691 else
igbt6 0:4e8ef5758455 1692 {
igbt6 0:4e8ef5758455 1693 settings.FskPacketHandler.Size = SX1278Read(REG_PAYLOADLENGTH);
igbt6 0:4e8ef5758455 1694 }
igbt6 0:4e8ef5758455 1695 }
igbt6 0:4e8ef5758455 1696 // ERRATA 3.1 - PayloadReady Set for 31.25ns if FIFO is Empty
igbt6 0:4e8ef5758455 1697 //
igbt6 0:4e8ef5758455 1698 // When FifoLevel interrupt is used to offload the
igbt6 0:4e8ef5758455 1699 // FIFO, the microcontroller should monitor both
igbt6 0:4e8ef5758455 1700 // PayloadReady and FifoLevel interrupts, and
igbt6 0:4e8ef5758455 1701 // read only (FifoThreshold-1) bytes off the FIFO
igbt6 0:4e8ef5758455 1702 // when FifoLevel fires
igbt6 0:4e8ef5758455 1703 if ((settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes) > settings.FskPacketHandler.FifoThresh)
igbt6 0:4e8ef5758455 1704 {
igbt6 0:4e8ef5758455 1705 SX1278ReadFifo((RxTxBuffer + settings.FskPacketHandler.NbBytes), settings.FskPacketHandler.FifoThresh);
igbt6 0:4e8ef5758455 1706 settings.FskPacketHandler.NbBytes += settings.FskPacketHandler.FifoThresh;
igbt6 0:4e8ef5758455 1707 }
igbt6 0:4e8ef5758455 1708 else
igbt6 0:4e8ef5758455 1709 {
igbt6 0:4e8ef5758455 1710 SX1278ReadFifo((RxTxBuffer + settings.FskPacketHandler.NbBytes), settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes);
igbt6 0:4e8ef5758455 1711 settings.FskPacketHandler.NbBytes += (settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes);
igbt6 0:4e8ef5758455 1712 }
igbt6 0:4e8ef5758455 1713 break;
igbt6 0:4e8ef5758455 1714 case MODEM_LORA:
igbt6 0:4e8ef5758455 1715 // Sync time out
igbt6 0:4e8ef5758455 1716 SX1278SetTimeout(RXTimeoutTimer, NULL, 0);
igbt6 0:4e8ef5758455 1717 // Clear Irq
igbt6 0:4e8ef5758455 1718 SX1278Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT);
igbt6 0:4e8ef5758455 1719
igbt6 0:4e8ef5758455 1720 settings.State = RF_IDLE;
igbt6 0:4e8ef5758455 1721 if ((RadioEvents != NULL) && (RadioEvents->RxTimeout != NULL))
igbt6 0:4e8ef5758455 1722 {
igbt6 0:4e8ef5758455 1723 RadioEvents->RxTimeout();
igbt6 0:4e8ef5758455 1724 }
igbt6 0:4e8ef5758455 1725 break;
igbt6 0:4e8ef5758455 1726 default:
igbt6 0:4e8ef5758455 1727 break;
igbt6 0:4e8ef5758455 1728 }
igbt6 0:4e8ef5758455 1729 break;
igbt6 0:4e8ef5758455 1730 case RF_TX_RUNNING:
igbt6 0:4e8ef5758455 1731 switch (settings.Modem)
igbt6 0:4e8ef5758455 1732 {
igbt6 0:4e8ef5758455 1733 case MODEM_FSK:
igbt6 0:4e8ef5758455 1734 // FifoEmpty interrupt
igbt6 0:4e8ef5758455 1735 if ((settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes) > settings.FskPacketHandler.ChunkSize)
igbt6 0:4e8ef5758455 1736 {
igbt6 0:4e8ef5758455 1737 SX1278WriteFifo((RxTxBuffer + settings.FskPacketHandler.NbBytes), settings.FskPacketHandler.ChunkSize);
igbt6 0:4e8ef5758455 1738 settings.FskPacketHandler.NbBytes += settings.FskPacketHandler.ChunkSize;
igbt6 0:4e8ef5758455 1739 }
igbt6 0:4e8ef5758455 1740 else
igbt6 0:4e8ef5758455 1741 {
igbt6 0:4e8ef5758455 1742 // SX1278Write the last chunk of data
igbt6 0:4e8ef5758455 1743 SX1278WriteFifo(RxTxBuffer + settings.FskPacketHandler.NbBytes, settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes);
igbt6 0:4e8ef5758455 1744 settings.FskPacketHandler.NbBytes += settings.FskPacketHandler.Size - settings.FskPacketHandler.NbBytes;
igbt6 0:4e8ef5758455 1745 }
igbt6 0:4e8ef5758455 1746 break;
igbt6 0:4e8ef5758455 1747 case MODEM_LORA:
igbt6 0:4e8ef5758455 1748 break;
igbt6 0:4e8ef5758455 1749 default:
igbt6 0:4e8ef5758455 1750 break;
igbt6 0:4e8ef5758455 1751 }
igbt6 0:4e8ef5758455 1752 break;
igbt6 0:4e8ef5758455 1753 default:
igbt6 0:4e8ef5758455 1754 break;
igbt6 0:4e8ef5758455 1755 }
igbt6 0:4e8ef5758455 1756 }
igbt6 0:4e8ef5758455 1757
igbt6 0:4e8ef5758455 1758 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1759 void OnDio2Irq()
igbt6 0:4e8ef5758455 1760 {
igbt6 0:4e8ef5758455 1761 switch (settings.State)
igbt6 0:4e8ef5758455 1762 {
igbt6 0:4e8ef5758455 1763 case RF_RX_RUNNING:
igbt6 0:4e8ef5758455 1764 switch (settings.Modem)
igbt6 0:4e8ef5758455 1765 {
igbt6 0:4e8ef5758455 1766 case MODEM_FSK:
igbt6 0:4e8ef5758455 1767 // Checks if DIO4 is connected. If it is not PreambleDtected is set to true.
igbt6 0:4e8ef5758455 1768 if (dioIrq[4] == NULL)
igbt6 0:4e8ef5758455 1769 {
igbt6 0:4e8ef5758455 1770 settings.FskPacketHandler.PreambleDetected = true;
igbt6 0:4e8ef5758455 1771 }
igbt6 0:4e8ef5758455 1772
igbt6 0:4e8ef5758455 1773 if ((settings.FskPacketHandler.PreambleDetected == true) && (settings.FskPacketHandler.SyncWordDetected == false))
igbt6 0:4e8ef5758455 1774 {
igbt6 0:4e8ef5758455 1775 SX1278SetTimeout(RXTimeoutSyncWordTimer, NULL, 0);
igbt6 0:4e8ef5758455 1776
igbt6 0:4e8ef5758455 1777 settings.FskPacketHandler.SyncWordDetected = true;
igbt6 0:4e8ef5758455 1778
igbt6 0:4e8ef5758455 1779 settings.FskPacketHandler.RssiValue = -(SX1278Read(REG_RSSIVALUE) >> 1);
igbt6 0:4e8ef5758455 1780
igbt6 0:4e8ef5758455 1781 settings.FskPacketHandler.AfcValue = (int32_t)(double)(((uint16_t)SX1278Read(REG_AFCMSB) << 8) |
igbt6 0:4e8ef5758455 1782 (uint16_t)SX1278Read(REG_AFCLSB)) *
igbt6 0:4e8ef5758455 1783 (double)FREQ_STEP;
igbt6 0:4e8ef5758455 1784 settings.FskPacketHandler.RxGain = (SX1278Read(REG_LNA) >> 5) & 0x07;
igbt6 0:4e8ef5758455 1785 }
igbt6 0:4e8ef5758455 1786 break;
igbt6 0:4e8ef5758455 1787 case MODEM_LORA:
igbt6 0:4e8ef5758455 1788 if (settings.LoRa.FreqHopOn == true)
igbt6 0:4e8ef5758455 1789 {
igbt6 0:4e8ef5758455 1790 // Clear Irq
igbt6 0:4e8ef5758455 1791 SX1278Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL);
igbt6 0:4e8ef5758455 1792
igbt6 0:4e8ef5758455 1793 if ((RadioEvents != NULL) && (RadioEvents->FhssChangeChannel != NULL))
igbt6 0:4e8ef5758455 1794 {
igbt6 0:4e8ef5758455 1795 RadioEvents->FhssChangeChannel((SX1278Read(REG_LR_HOPCHANNEL) & RFLR_HOPCHANNEL_CHANNEL_MASK));
igbt6 0:4e8ef5758455 1796 }
igbt6 0:4e8ef5758455 1797 }
igbt6 0:4e8ef5758455 1798 break;
igbt6 0:4e8ef5758455 1799 default:
igbt6 0:4e8ef5758455 1800 break;
igbt6 0:4e8ef5758455 1801 }
igbt6 0:4e8ef5758455 1802 break;
igbt6 0:4e8ef5758455 1803 case RF_TX_RUNNING:
igbt6 0:4e8ef5758455 1804 switch (settings.Modem)
igbt6 0:4e8ef5758455 1805 {
igbt6 0:4e8ef5758455 1806 case MODEM_FSK:
igbt6 0:4e8ef5758455 1807 break;
igbt6 0:4e8ef5758455 1808 case MODEM_LORA:
igbt6 0:4e8ef5758455 1809 if (settings.LoRa.FreqHopOn == true)
igbt6 0:4e8ef5758455 1810 {
igbt6 0:4e8ef5758455 1811 // Clear Irq
igbt6 0:4e8ef5758455 1812 SX1278Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL);
igbt6 0:4e8ef5758455 1813
igbt6 0:4e8ef5758455 1814 if ((RadioEvents != NULL) && (RadioEvents->FhssChangeChannel != NULL))
igbt6 0:4e8ef5758455 1815 {
igbt6 0:4e8ef5758455 1816 RadioEvents->FhssChangeChannel((SX1278Read(REG_LR_HOPCHANNEL) & RFLR_HOPCHANNEL_CHANNEL_MASK));
igbt6 0:4e8ef5758455 1817 }
igbt6 0:4e8ef5758455 1818 }
igbt6 0:4e8ef5758455 1819 break;
igbt6 0:4e8ef5758455 1820 default:
igbt6 0:4e8ef5758455 1821 break;
igbt6 0:4e8ef5758455 1822 }
igbt6 0:4e8ef5758455 1823 break;
igbt6 0:4e8ef5758455 1824 default:
igbt6 0:4e8ef5758455 1825 break;
igbt6 0:4e8ef5758455 1826 }
igbt6 0:4e8ef5758455 1827 }
igbt6 0:4e8ef5758455 1828
igbt6 0:4e8ef5758455 1829 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1830 void OnDio3Irq()
igbt6 0:4e8ef5758455 1831 {
igbt6 0:4e8ef5758455 1832 switch (settings.Modem)
igbt6 0:4e8ef5758455 1833 {
igbt6 0:4e8ef5758455 1834 case MODEM_FSK:
igbt6 0:4e8ef5758455 1835 break;
igbt6 0:4e8ef5758455 1836 case MODEM_LORA:
igbt6 0:4e8ef5758455 1837 if ((SX1278Read(REG_LR_IRQFLAGS) & RFLR_IRQFLAGS_CADDETECTED) == RFLR_IRQFLAGS_CADDETECTED)
igbt6 0:4e8ef5758455 1838 {
igbt6 0:4e8ef5758455 1839 // Clear Irq
igbt6 0:4e8ef5758455 1840 SX1278Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE);
igbt6 0:4e8ef5758455 1841 if ((RadioEvents != NULL) && (RadioEvents->CadDone != NULL))
igbt6 0:4e8ef5758455 1842 {
igbt6 0:4e8ef5758455 1843 RadioEvents->CadDone(true);
igbt6 0:4e8ef5758455 1844 }
igbt6 0:4e8ef5758455 1845 }
igbt6 0:4e8ef5758455 1846 else
igbt6 0:4e8ef5758455 1847 {
igbt6 0:4e8ef5758455 1848 // Clear Irq
igbt6 0:4e8ef5758455 1849 SX1278Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE);
igbt6 0:4e8ef5758455 1850 if ((RadioEvents != NULL) && (RadioEvents->CadDone != NULL))
igbt6 0:4e8ef5758455 1851 {
igbt6 0:4e8ef5758455 1852 RadioEvents->CadDone(false);
igbt6 0:4e8ef5758455 1853 }
igbt6 0:4e8ef5758455 1854 }
igbt6 0:4e8ef5758455 1855 break;
igbt6 0:4e8ef5758455 1856 default:
igbt6 0:4e8ef5758455 1857 break;
igbt6 0:4e8ef5758455 1858 }
igbt6 0:4e8ef5758455 1859 }
igbt6 0:4e8ef5758455 1860
igbt6 0:4e8ef5758455 1861 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1862 void OnDio4Irq()
igbt6 0:4e8ef5758455 1863 {
igbt6 0:4e8ef5758455 1864 switch (settings.Modem)
igbt6 0:4e8ef5758455 1865 {
igbt6 0:4e8ef5758455 1866 case MODEM_FSK:
igbt6 0:4e8ef5758455 1867 {
igbt6 0:4e8ef5758455 1868 if (settings.FskPacketHandler.PreambleDetected == false)
igbt6 0:4e8ef5758455 1869 {
igbt6 0:4e8ef5758455 1870 settings.FskPacketHandler.PreambleDetected = true;
igbt6 0:4e8ef5758455 1871 }
igbt6 0:4e8ef5758455 1872 }
igbt6 0:4e8ef5758455 1873 break;
igbt6 0:4e8ef5758455 1874 case MODEM_LORA:
igbt6 0:4e8ef5758455 1875 break;
igbt6 0:4e8ef5758455 1876 default:
igbt6 0:4e8ef5758455 1877 break;
igbt6 0:4e8ef5758455 1878 }
igbt6 0:4e8ef5758455 1879 }
igbt6 0:4e8ef5758455 1880
igbt6 0:4e8ef5758455 1881 //-----------------------------------------------------------------------------
igbt6 0:4e8ef5758455 1882 void OnDio5Irq()
igbt6 0:4e8ef5758455 1883 {
igbt6 0:4e8ef5758455 1884 switch (settings.Modem)
igbt6 0:4e8ef5758455 1885 {
igbt6 0:4e8ef5758455 1886 case MODEM_FSK:
igbt6 0:4e8ef5758455 1887 break;
igbt6 0:4e8ef5758455 1888 case MODEM_LORA:
igbt6 0:4e8ef5758455 1889 break;
igbt6 0:4e8ef5758455 1890 default:
igbt6 0:4e8ef5758455 1891 break;
igbt6 0:4e8ef5758455 1892 }
igbt6 0:4e8ef5758455 1893 }
igbt6 0:4e8ef5758455 1894
igbt6 0:4e8ef5758455 1895 //-----------------------------------------------------------------------------