1

Committer:
advxolltm
Date:
Mon Jun 06 16:37:12 2022 +0000
Revision:
22:fc88e265f425
Parent:
20:75635d50262e
123

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:9c052ff8dd6a 1 #include "radio.h"
Wayne Roberts 0:9c052ff8dd6a 2 #ifdef SX127x_H
Wayne Roberts 0:9c052ff8dd6a 3
Wayne Roberts 17:5f34cbe2ac53 4 #ifdef DEVICE_LPTICKER
Wayne Roberts 0:9c052ff8dd6a 5 LowPowerTimer Radio::lpt;
Wayne Roberts 17:5f34cbe2ac53 6 LowPowerTimeout TxTimeoutEvent;
Wayne Roberts 17:5f34cbe2ac53 7 #else
Wayne Roberts 17:5f34cbe2ac53 8 Timer Radio::lpt;
Wayne Roberts 17:5f34cbe2ac53 9 Timeout TxTimeoutEvent;
Wayne Roberts 17:5f34cbe2ac53 10 #endif
Wayne Roberts 0:9c052ff8dd6a 11
Wayne Roberts 20:75635d50262e 12 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 20:75635d50262e 13 volatile us_timestamp_t Radio::irqAt;
Wayne Roberts 20:75635d50262e 14 #else
Wayne Roberts 20:75635d50262e 15 using namespace std::chrono;
Wayne Roberts 20:75635d50262e 16 LowPowerClock::time_point Radio::irqAt;
Wayne Roberts 20:75635d50262e 17 #endif
Wayne Roberts 20:75635d50262e 18
Wayne Roberts 0:9c052ff8dd6a 19 void Radio::Sleep()
Wayne Roberts 0:9c052ff8dd6a 20 {
Wayne Roberts 0:9c052ff8dd6a 21 radio.set_opmode(RF_OPMODE_SLEEP);
Wayne Roberts 0:9c052ff8dd6a 22 }
Wayne Roberts 0:9c052ff8dd6a 23
Wayne Roberts 0:9c052ff8dd6a 24 void Radio::Standby()
Wayne Roberts 0:9c052ff8dd6a 25 {
Wayne Roberts 0:9c052ff8dd6a 26 radio.set_opmode(RF_OPMODE_STANDBY);
Wayne Roberts 0:9c052ff8dd6a 27 }
Wayne Roberts 0:9c052ff8dd6a 28
Wayne Roberts 0:9c052ff8dd6a 29 bool Radio::CheckRfFrequency(unsigned hz)
Wayne Roberts 0:9c052ff8dd6a 30 {
Wayne Roberts 0:9c052ff8dd6a 31 return true;
Wayne Roberts 0:9c052ff8dd6a 32 }
Wayne Roberts 0:9c052ff8dd6a 33
Wayne Roberts 0:9c052ff8dd6a 34 void Radio::SetChannel(unsigned hz)
Wayne Roberts 0:9c052ff8dd6a 35 {
Wayne Roberts 0:9c052ff8dd6a 36 radio.set_frf_MHz(hz / 1000000.0);
Wayne Roberts 0:9c052ff8dd6a 37 }
Wayne Roberts 0:9c052ff8dd6a 38
Wayne Roberts 0:9c052ff8dd6a 39 float Radio::getFrfMHz()
Wayne Roberts 0:9c052ff8dd6a 40 {
Wayne Roberts 0:9c052ff8dd6a 41 return radio.get_frf_MHz();
Wayne Roberts 0:9c052ff8dd6a 42 }
Wayne Roberts 0:9c052ff8dd6a 43
Wayne Roberts 0:9c052ff8dd6a 44 void SX1272OnTimeoutIrq( void )
Wayne Roberts 0:9c052ff8dd6a 45 {
Wayne Roberts 0:9c052ff8dd6a 46 Radio::radio.set_opmode(RF_OPMODE_STANDBY);
Wayne Roberts 0:9c052ff8dd6a 47 }
Wayne Roberts 0:9c052ff8dd6a 48
Wayne Roberts 0:9c052ff8dd6a 49 void Radio::SetTxContinuousWave(unsigned hz, int8_t dbm, unsigned timeout_us)
Wayne Roberts 0:9c052ff8dd6a 50 {
Wayne Roberts 19:94b5382d3fc6 51 fsk.enable(true);
Wayne Roberts 19:94b5382d3fc6 52 fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
Wayne Roberts 19:94b5382d3fc6 53 fsk.RegPktConfig2.bits.DataModePacket = 0; // continuous mode
Wayne Roberts 19:94b5382d3fc6 54 radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);
Wayne Roberts 19:94b5382d3fc6 55 fsk.set_tx_fdev_hz(0); // unmodulated carrier, aka dead carrier
Wayne Roberts 19:94b5382d3fc6 56 SetChannel(hz);
Wayne Roberts 0:9c052ff8dd6a 57 set_tx_dbm(dbm);
Wayne Roberts 19:94b5382d3fc6 58
Wayne Roberts 20:75635d50262e 59 if (timeout_us != 0) {
Wayne Roberts 20:75635d50262e 60 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 19:94b5382d3fc6 61 TxTimeoutEvent.attach_us(SX1272OnTimeoutIrq, timeout_us);
Wayne Roberts 20:75635d50262e 62 #else
Wayne Roberts 20:75635d50262e 63 TxTimeoutEvent.attach(SX1272OnTimeoutIrq, microseconds(timeout_us));
Wayne Roberts 20:75635d50262e 64 #endif
Wayne Roberts 20:75635d50262e 65 }
Wayne Roberts 19:94b5382d3fc6 66
Wayne Roberts 0:9c052ff8dd6a 67 radio.set_opmode(RF_OPMODE_TRANSMITTER);
Wayne Roberts 0:9c052ff8dd6a 68 }
Wayne Roberts 0:9c052ff8dd6a 69
Wayne Roberts 0:9c052ff8dd6a 70 #define LORA_MAC_PRIVATE_SYNCWORD 0x12
Wayne Roberts 0:9c052ff8dd6a 71 #define LORA_MAC_PUBLIC_SYNCWORD 0x34
Wayne Roberts 0:9c052ff8dd6a 72 void Radio::SetPublicNetwork(bool en)
Wayne Roberts 0:9c052ff8dd6a 73 {
Wayne Roberts 0:9c052ff8dd6a 74 radio.write_reg(REG_LR_SYNC_BYTE, en ? LORA_MAC_PUBLIC_SYNCWORD : LORA_MAC_PRIVATE_SYNCWORD);
Wayne Roberts 0:9c052ff8dd6a 75 }
Wayne Roberts 0:9c052ff8dd6a 76
Wayne Roberts 0:9c052ff8dd6a 77 uint32_t Radio::Random(void)
Wayne Roberts 0:9c052ff8dd6a 78 {
Wayne Roberts 0:9c052ff8dd6a 79 uint32_t ret = 0;
Wayne Roberts 0:9c052ff8dd6a 80 unsigned i;
Wayne Roberts 0:9c052ff8dd6a 81
Wayne Roberts 0:9c052ff8dd6a 82 radio.set_opmode(RF_OPMODE_RECEIVER);
Wayne Roberts 0:9c052ff8dd6a 83 for (i = 0; i < 32; i++) {
Wayne Roberts 0:9c052ff8dd6a 84 uint32_t r;
Wayne Roberts 0:9c052ff8dd6a 85 wait_us(3000);
Wayne Roberts 0:9c052ff8dd6a 86 r = radio.read_reg(REG_LR_WIDEBAND_RSSI);
Wayne Roberts 0:9c052ff8dd6a 87 r <<= ((i & 7) << 2);
Wayne Roberts 0:9c052ff8dd6a 88 ret ^= r;
Wayne Roberts 0:9c052ff8dd6a 89 }
Wayne Roberts 0:9c052ff8dd6a 90
Wayne Roberts 0:9c052ff8dd6a 91 return ret;
Wayne Roberts 0:9c052ff8dd6a 92 }
Wayne Roberts 0:9c052ff8dd6a 93
Wayne Roberts 0:9c052ff8dd6a 94 void Radio::LoRaPacketConfig(unsigned preambleLen, bool fixLen, bool crcOn, bool invIQ)
Wayne Roberts 0:9c052ff8dd6a 95 {
Wayne Roberts 0:9c052ff8dd6a 96 lora.RegPreamble = preambleLen;
Wayne Roberts 0:9c052ff8dd6a 97 radio.write_u16(REG_LR_PREAMBLEMSB, lora.RegPreamble);
Wayne Roberts 0:9c052ff8dd6a 98
Wayne Roberts 0:9c052ff8dd6a 99 if (radio.type == SX1276) {
Wayne Roberts 0:9c052ff8dd6a 100 lora.RegModemConfig.sx1276bits.ImplicitHeaderModeOn = fixLen;
Wayne Roberts 0:9c052ff8dd6a 101 lora.RegModemConfig2.sx1276bits.RxPayloadCrcOn = crcOn;
Wayne Roberts 0:9c052ff8dd6a 102 radio.write_reg(REG_LR_MODEMCONFIG2, lora.RegModemConfig2.octet);
Wayne Roberts 0:9c052ff8dd6a 103 } else if (radio.type == SX1272) {
Wayne Roberts 0:9c052ff8dd6a 104 lora.RegModemConfig.sx1272bits.ImplicitHeaderModeOn = fixLen;
Wayne Roberts 0:9c052ff8dd6a 105 lora.RegModemConfig.sx1272bits.RxPayloadCrcOn = crcOn;
Wayne Roberts 0:9c052ff8dd6a 106 }
Wayne Roberts 0:9c052ff8dd6a 107
Wayne Roberts 0:9c052ff8dd6a 108 radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet);
Wayne Roberts 0:9c052ff8dd6a 109
Wayne Roberts 0:9c052ff8dd6a 110 lora.invert_tx(invIQ);
Wayne Roberts 0:9c052ff8dd6a 111 lora.invert_rx(invIQ);
Wayne Roberts 0:9c052ff8dd6a 112 }
Wayne Roberts 0:9c052ff8dd6a 113
Wayne Roberts 0:9c052ff8dd6a 114 void Radio::GFSKModemConfig(unsigned bps, unsigned bw_hz, unsigned fdev_hz)
Wayne Roberts 0:9c052ff8dd6a 115 {
Wayne Roberts 0:9c052ff8dd6a 116 if (radio.RegOpMode.bits.LongRangeMode)
Wayne Roberts 0:9c052ff8dd6a 117 fsk.enable(false);
Wayne Roberts 0:9c052ff8dd6a 118
Wayne Roberts 0:9c052ff8dd6a 119 fsk.set_bitrate(bps);
Wayne Roberts 0:9c052ff8dd6a 120
Wayne Roberts 0:9c052ff8dd6a 121 fsk.set_rx_dcc_bw_hz(bw_hz, 0);
Wayne Roberts 0:9c052ff8dd6a 122 fsk.set_rx_dcc_bw_hz(bw_hz * 1.5, 1);
Wayne Roberts 0:9c052ff8dd6a 123
Wayne Roberts 0:9c052ff8dd6a 124 fsk.set_tx_fdev_hz(fdev_hz);
Wayne Roberts 0:9c052ff8dd6a 125 }
Wayne Roberts 0:9c052ff8dd6a 126
Wayne Roberts 0:9c052ff8dd6a 127
Wayne Roberts 0:9c052ff8dd6a 128 void Radio::GFSKPacketConfig(unsigned preambleLen, bool fixLen, bool crcOn)
Wayne Roberts 0:9c052ff8dd6a 129 {
Wayne Roberts 0:9c052ff8dd6a 130 if (radio.RegOpMode.bits.LongRangeMode)
Wayne Roberts 0:9c052ff8dd6a 131 fsk.enable(false);
Wayne Roberts 0:9c052ff8dd6a 132
Wayne Roberts 0:9c052ff8dd6a 133 radio.write_u16(REG_FSK_PREAMBLEMSB, preambleLen);
Wayne Roberts 0:9c052ff8dd6a 134
Wayne Roberts 0:9c052ff8dd6a 135 fsk.RegPktConfig1.bits.PacketFormatVariable = fixLen ? 0 : 1;
Wayne Roberts 0:9c052ff8dd6a 136 fsk.RegPktConfig1.bits.CrcOn = crcOn;
Wayne Roberts 0:9c052ff8dd6a 137 radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
Wayne Roberts 0:9c052ff8dd6a 138 }
Wayne Roberts 0:9c052ff8dd6a 139
Wayne Roberts 13:a354f82d12d9 140 void Radio::SetLoRaSymbolTimeout(uint16_t symbs)
Wayne Roberts 0:9c052ff8dd6a 141 {
Wayne Roberts 0:9c052ff8dd6a 142 if (!radio.RegOpMode.bits.LongRangeMode)
Wayne Roberts 0:9c052ff8dd6a 143 lora.enable();
Wayne Roberts 0:9c052ff8dd6a 144
Wayne Roberts 13:a354f82d12d9 145 radio.write_reg(REG_LR_SYMBTIMEOUTLSB, symbs & 0xff);
Wayne Roberts 13:a354f82d12d9 146 symbs >>= 8;
Wayne Roberts 13:a354f82d12d9 147 lora.RegModemConfig2.sx1272bits.SymbTimeoutMsb = symbs;
Wayne Roberts 0:9c052ff8dd6a 148 radio.write_reg(REG_LR_MODEMCONFIG2, lora.RegModemConfig2.octet);
Wayne Roberts 0:9c052ff8dd6a 149 }
Wayne Roberts 0:9c052ff8dd6a 150
Wayne Roberts 0:9c052ff8dd6a 151 void Radio::LoRaModemConfig(unsigned bwKHz, uint8_t sf, uint8_t coderate)
Wayne Roberts 0:9c052ff8dd6a 152 {
Wayne Roberts 0:9c052ff8dd6a 153 float sp;
Wayne Roberts 0:9c052ff8dd6a 154 if (!radio.RegOpMode.bits.LongRangeMode)
Wayne Roberts 0:9c052ff8dd6a 155 lora.enable();
Wayne Roberts 0:9c052ff8dd6a 156
Wayne Roberts 0:9c052ff8dd6a 157 lora.RegModemConfig2.sx1276bits.SpreadingFactor = sf;
Wayne Roberts 0:9c052ff8dd6a 158 radio.write_reg(REG_LR_MODEMCONFIG2, lora.RegModemConfig2.octet);
Wayne Roberts 0:9c052ff8dd6a 159
Wayne Roberts 0:9c052ff8dd6a 160 lora.setBw_KHz(bwKHz);
Wayne Roberts 0:9c052ff8dd6a 161
Wayne Roberts 0:9c052ff8dd6a 162 if (radio.type == SX1276) {
Wayne Roberts 0:9c052ff8dd6a 163 lora.RegModemConfig.sx1276bits.CodingRate = coderate;
Wayne Roberts 0:9c052ff8dd6a 164
Wayne Roberts 0:9c052ff8dd6a 165 sp = lora.get_symbol_period();
Wayne Roberts 0:9c052ff8dd6a 166 if (sp > 16)
Wayne Roberts 0:9c052ff8dd6a 167 lora.RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
Wayne Roberts 0:9c052ff8dd6a 168 else
Wayne Roberts 0:9c052ff8dd6a 169 lora.RegModemConfig3.sx1276bits.LowDataRateOptimize = 0;
Wayne Roberts 0:9c052ff8dd6a 170
Wayne Roberts 0:9c052ff8dd6a 171 radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet);
Wayne Roberts 0:9c052ff8dd6a 172 } else if (radio.type == SX1272) {
Wayne Roberts 0:9c052ff8dd6a 173 lora.RegModemConfig.sx1272bits.CodingRate = coderate;
Wayne Roberts 0:9c052ff8dd6a 174
Wayne Roberts 0:9c052ff8dd6a 175 if (lora.get_symbol_period() > 16)
Wayne Roberts 0:9c052ff8dd6a 176 lora.RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
Wayne Roberts 0:9c052ff8dd6a 177 else
Wayne Roberts 0:9c052ff8dd6a 178 lora.RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
Wayne Roberts 0:9c052ff8dd6a 179 }
Wayne Roberts 0:9c052ff8dd6a 180 radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet);
Wayne Roberts 0:9c052ff8dd6a 181 }
Wayne Roberts 0:9c052ff8dd6a 182
Wayne Roberts 1:e79b0a55135f 183 void Radio::SetRxMaxPayloadLength(uint8_t max)
Wayne Roberts 0:9c052ff8dd6a 184 {
Wayne Roberts 1:e79b0a55135f 185 if (radio.RegOpMode.bits.LongRangeMode)
Wayne Roberts 1:e79b0a55135f 186 radio.write_reg(REG_LR_RX_MAX_PAYLOADLENGTH, max);
Wayne Roberts 1:e79b0a55135f 187 else
Wayne Roberts 1:e79b0a55135f 188 radio.write_reg(REG_FSK_PAYLOADLENGTH, max);
Wayne Roberts 0:9c052ff8dd6a 189 }
Wayne Roberts 0:9c052ff8dd6a 190
Wayne Roberts 6:b7bbf31e06e4 191 void Radio::SetFixedPayloadLength(uint8_t len)
Wayne Roberts 6:b7bbf31e06e4 192 {
Wayne Roberts 6:b7bbf31e06e4 193 lora.RegPayloadLength = len;
Wayne Roberts 6:b7bbf31e06e4 194 radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
Wayne Roberts 6:b7bbf31e06e4 195 }
Wayne Roberts 6:b7bbf31e06e4 196
Wayne Roberts 0:9c052ff8dd6a 197 const RadioEvents_t* RadioEvents;
Wayne Roberts 0:9c052ff8dd6a 198
Wayne Roberts 0:9c052ff8dd6a 199
Wayne Roberts 0:9c052ff8dd6a 200 volatile struct pe {
Wayne Roberts 0:9c052ff8dd6a 201 uint8_t dio0 : 1;
Wayne Roberts 0:9c052ff8dd6a 202 uint8_t dio1 : 1;
Wayne Roberts 0:9c052ff8dd6a 203 uint8_t txing : 1;
Wayne Roberts 0:9c052ff8dd6a 204 } pinEvent;
Wayne Roberts 0:9c052ff8dd6a 205
Wayne Roberts 0:9c052ff8dd6a 206 void
Wayne Roberts 0:9c052ff8dd6a 207 Radio::dio0UserContext()
Wayne Roberts 0:9c052ff8dd6a 208 {
Wayne Roberts 0:9c052ff8dd6a 209 service_action_e act = lora.service();
Wayne Roberts 0:9c052ff8dd6a 210
Wayne Roberts 0:9c052ff8dd6a 211 if (!pinEvent.txing) {
Wayne Roberts 0:9c052ff8dd6a 212 if (act == SERVICE_READ_FIFO && RadioEvents->RxDone) {
Wayne Roberts 0:9c052ff8dd6a 213 int8_t rssi;
Wayne Roberts 0:9c052ff8dd6a 214 float snr = lora.RegPktSnrValue / 4.0;
Wayne Roberts 0:9c052ff8dd6a 215
Wayne Roberts 0:9c052ff8dd6a 216 rssi = lora.get_pkt_rssi();
Wayne Roberts 0:9c052ff8dd6a 217 if (snr < 0)
Wayne Roberts 0:9c052ff8dd6a 218 rssi += snr;
Wayne Roberts 0:9c052ff8dd6a 219 RadioEvents->RxDone(lora.RegRxNbBytes, rssi, snr);
Wayne Roberts 0:9c052ff8dd6a 220 }
Wayne Roberts 0:9c052ff8dd6a 221 } else if (act == SERVICE_TX_DONE) {
Wayne Roberts 0:9c052ff8dd6a 222 if (RadioEvents->TxDone_botHalf)
Wayne Roberts 0:9c052ff8dd6a 223 RadioEvents->TxDone_botHalf();
Wayne Roberts 0:9c052ff8dd6a 224 }
Wayne Roberts 0:9c052ff8dd6a 225 }
Wayne Roberts 0:9c052ff8dd6a 226
Wayne Roberts 0:9c052ff8dd6a 227 void Radio::dio0isr()
Wayne Roberts 0:9c052ff8dd6a 228 {
Wayne Roberts 20:75635d50262e 229 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 0:9c052ff8dd6a 230 irqAt = lpt.read_us();
Wayne Roberts 20:75635d50262e 231 #else
Wayne Roberts 20:75635d50262e 232 irqAt = LowPowerClock::now();
Wayne Roberts 20:75635d50262e 233 #endif
Wayne Roberts 14:94993ae5b164 234
Wayne Roberts 14:94993ae5b164 235 if (RadioEvents->DioPin_top_half)
Wayne Roberts 14:94993ae5b164 236 RadioEvents->DioPin_top_half();
Wayne Roberts 0:9c052ff8dd6a 237
Wayne Roberts 0:9c052ff8dd6a 238 if (pinEvent.txing) {
Wayne Roberts 0:9c052ff8dd6a 239 /* TxDone handling requires low latency */
Wayne Roberts 0:9c052ff8dd6a 240 if (RadioEvents->TxDone_topHalf)
Wayne Roberts 0:9c052ff8dd6a 241 RadioEvents->TxDone_topHalf(); // TODO in callback read irqAt for timestamp of interrupt
Wayne Roberts 0:9c052ff8dd6a 242
Wayne Roberts 0:9c052ff8dd6a 243 }
Wayne Roberts 0:9c052ff8dd6a 244
Wayne Roberts 0:9c052ff8dd6a 245 pinEvent.dio0 = 1;
Wayne Roberts 0:9c052ff8dd6a 246 }
Wayne Roberts 0:9c052ff8dd6a 247
Wayne Roberts 0:9c052ff8dd6a 248 void Radio::dio1UserContext()
Wayne Roberts 0:9c052ff8dd6a 249 {
Wayne Roberts 0:9c052ff8dd6a 250 lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
Wayne Roberts 0:9c052ff8dd6a 251
Wayne Roberts 0:9c052ff8dd6a 252 if (RadioEvents->RxTimeout)
Wayne Roberts 0:9c052ff8dd6a 253 RadioEvents->RxTimeout();
Wayne Roberts 0:9c052ff8dd6a 254
Wayne Roberts 0:9c052ff8dd6a 255 radio.write_reg(REG_LR_IRQFLAGS, 0x80); // ensure RxTimeout is cleared
Wayne Roberts 0:9c052ff8dd6a 256 }
Wayne Roberts 0:9c052ff8dd6a 257
Wayne Roberts 0:9c052ff8dd6a 258 void Radio::dio1isr()
Wayne Roberts 0:9c052ff8dd6a 259 {
Wayne Roberts 0:9c052ff8dd6a 260 pinEvent.dio1 = 1;
Wayne Roberts 14:94993ae5b164 261
Wayne Roberts 14:94993ae5b164 262 if (RadioEvents->DioPin_top_half)
Wayne Roberts 14:94993ae5b164 263 RadioEvents->DioPin_top_half();
Wayne Roberts 0:9c052ff8dd6a 264 }
Wayne Roberts 0:9c052ff8dd6a 265
Wayne Roberts 13:a354f82d12d9 266 void Radio::Init(const RadioEvents_t* e, unsigned spi_hz)
Wayne Roberts 0:9c052ff8dd6a 267 {
Wayne Roberts 13:a354f82d12d9 268 radio.m_spi.frequency(spi_hz);
Wayne Roberts 13:a354f82d12d9 269
Wayne Roberts 8:0518c6e68b79 270 while (radio.dio0.read() || radio.dio1.read()) {
Wayne Roberts 8:0518c6e68b79 271 radio.write_reg(REG_LR_IRQFLAGS, 0xff); // clear stagnant interrupt
Wayne Roberts 8:0518c6e68b79 272 }
Wayne Roberts 0:9c052ff8dd6a 273 dio0.rise(dio0isr);
Wayne Roberts 0:9c052ff8dd6a 274 dio1.rise(dio1isr);
Wayne Roberts 0:9c052ff8dd6a 275
Wayne Roberts 0:9c052ff8dd6a 276 radio.rf_switch = rfsw_callback;
Wayne Roberts 0:9c052ff8dd6a 277 boardInit();
Wayne Roberts 0:9c052ff8dd6a 278
Wayne Roberts 0:9c052ff8dd6a 279 RadioEvents = e;
Wayne Roberts 0:9c052ff8dd6a 280 lpt.start();
Wayne Roberts 0:9c052ff8dd6a 281 }
Wayne Roberts 0:9c052ff8dd6a 282
Wayne Roberts 7:ba81f66e56d1 283 float Radio::GetRssiInst()
Wayne Roberts 7:ba81f66e56d1 284 {
Wayne Roberts 7:ba81f66e56d1 285 return lora.get_current_rssi();
Wayne Roberts 7:ba81f66e56d1 286 }
Wayne Roberts 7:ba81f66e56d1 287
Wayne Roberts 0:9c052ff8dd6a 288 int Radio::Send(uint8_t size, timestamp_t maxListenTime, timestamp_t channelFreeTime, int rssiThresh)
Wayne Roberts 0:9c052ff8dd6a 289 {
Wayne Roberts 0:9c052ff8dd6a 290 if (radio.RegOpMode.bits.Mode == RF_OPMODE_SLEEP) {
Wayne Roberts 0:9c052ff8dd6a 291 radio.set_opmode(RF_OPMODE_STANDBY);
Wayne Roberts 0:9c052ff8dd6a 292 wait_us(1000);
Wayne Roberts 0:9c052ff8dd6a 293 }
Wayne Roberts 0:9c052ff8dd6a 294 radio.write_reg(REG_LR_IRQFLAGS, 0x08); // ensure TxDone is cleared
Wayne Roberts 0:9c052ff8dd6a 295 lora.RegPayloadLength = size;
Wayne Roberts 0:9c052ff8dd6a 296 radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
Wayne Roberts 0:9c052ff8dd6a 297
Wayne Roberts 0:9c052ff8dd6a 298 if (maxListenTime > 0) {
Wayne Roberts 0:9c052ff8dd6a 299 int rssi;
Wayne Roberts 0:9c052ff8dd6a 300 us_timestamp_t startAt, chFreeAt, now;
Wayne Roberts 0:9c052ff8dd6a 301 lora.start_rx(RF_OPMODE_RECEIVER);
Wayne Roberts 20:75635d50262e 302 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 0:9c052ff8dd6a 303 startAt = lpt.read_us();
Wayne Roberts 20:75635d50262e 304 #else
Wayne Roberts 20:75635d50262e 305 startAt = LowPowerClock::now().time_since_epoch().count();
Wayne Roberts 20:75635d50262e 306 #endif
Wayne Roberts 0:9c052ff8dd6a 307 Lstart:
Wayne Roberts 0:9c052ff8dd6a 308 do {
Wayne Roberts 20:75635d50262e 309 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 0:9c052ff8dd6a 310 now = lpt.read_us();
Wayne Roberts 20:75635d50262e 311 #else
Wayne Roberts 20:75635d50262e 312 now = LowPowerClock::now().time_since_epoch().count();
Wayne Roberts 20:75635d50262e 313 #endif
Wayne Roberts 0:9c052ff8dd6a 314 if ((now - startAt) > maxListenTime) {
Wayne Roberts 0:9c052ff8dd6a 315 return -1;
Wayne Roberts 0:9c052ff8dd6a 316 }
Wayne Roberts 0:9c052ff8dd6a 317 rssi = lora.get_current_rssi();
Wayne Roberts 0:9c052ff8dd6a 318 } while (rssi > rssiThresh);
Wayne Roberts 20:75635d50262e 319 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 0:9c052ff8dd6a 320 chFreeAt = lpt.read_us();
Wayne Roberts 20:75635d50262e 321 #else
Wayne Roberts 20:75635d50262e 322 chFreeAt = LowPowerClock::now().time_since_epoch().count();
Wayne Roberts 20:75635d50262e 323 #endif
Wayne Roberts 0:9c052ff8dd6a 324 do {
Wayne Roberts 20:75635d50262e 325 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 0:9c052ff8dd6a 326 now = lpt.read_us();
Wayne Roberts 20:75635d50262e 327 #else
Wayne Roberts 20:75635d50262e 328 now = LowPowerClock::now().time_since_epoch().count();
Wayne Roberts 20:75635d50262e 329 #endif
Wayne Roberts 0:9c052ff8dd6a 330 rssi = lora.get_current_rssi();
Wayne Roberts 0:9c052ff8dd6a 331 if (rssi > rssiThresh) {
Wayne Roberts 0:9c052ff8dd6a 332 goto Lstart;
Wayne Roberts 0:9c052ff8dd6a 333 }
Wayne Roberts 0:9c052ff8dd6a 334 } while ((now - chFreeAt) < channelFreeTime);
Wayne Roberts 0:9c052ff8dd6a 335 }
Wayne Roberts 0:9c052ff8dd6a 336
Wayne Roberts 0:9c052ff8dd6a 337 lora.start_tx(size);
Wayne Roberts 0:9c052ff8dd6a 338 pinEvent.txing = 1;
Wayne Roberts 0:9c052ff8dd6a 339
Wayne Roberts 0:9c052ff8dd6a 340 return 0;
Wayne Roberts 0:9c052ff8dd6a 341 }
Wayne Roberts 0:9c052ff8dd6a 342
Wayne Roberts 0:9c052ff8dd6a 343 void Radio::Rx(unsigned timeout)
Wayne Roberts 0:9c052ff8dd6a 344 {
Wayne Roberts 0:9c052ff8dd6a 345 if (timeout == 0) {
Wayne Roberts 0:9c052ff8dd6a 346 lora.start_rx(RF_OPMODE_RECEIVER);
Wayne Roberts 0:9c052ff8dd6a 347 } else {
Wayne Roberts 0:9c052ff8dd6a 348 lora.start_rx(RF_OPMODE_RECEIVER_SINGLE);
Wayne Roberts 0:9c052ff8dd6a 349 }
Wayne Roberts 0:9c052ff8dd6a 350
Wayne Roberts 0:9c052ff8dd6a 351 pinEvent.txing = 0;
Wayne Roberts 0:9c052ff8dd6a 352 }
Wayne Roberts 0:9c052ff8dd6a 353
Wayne Roberts 0:9c052ff8dd6a 354
Wayne Roberts 0:9c052ff8dd6a 355 void Radio::ocp(uint8_t ma)
Wayne Roberts 0:9c052ff8dd6a 356 {
Wayne Roberts 0:9c052ff8dd6a 357 if (ma < 130)
Wayne Roberts 0:9c052ff8dd6a 358 radio.RegOcp.bits.OcpTrim = (ma - 45) / 5;
Wayne Roberts 0:9c052ff8dd6a 359 else
Wayne Roberts 0:9c052ff8dd6a 360 radio.RegOcp.bits.OcpTrim = (ma + 30) / 10;
Wayne Roberts 0:9c052ff8dd6a 361 radio.write_reg(REG_OCP, radio.RegOcp.octet);
Wayne Roberts 0:9c052ff8dd6a 362
Wayne Roberts 0:9c052ff8dd6a 363 radio.RegOcp.octet = radio.read_reg(REG_OCP);
Wayne Roberts 0:9c052ff8dd6a 364 if (radio.RegOcp.bits.OcpTrim < 16)
Wayne Roberts 0:9c052ff8dd6a 365 ma = 45 + (5 * radio.RegOcp.bits.OcpTrim);
Wayne Roberts 0:9c052ff8dd6a 366 else if (radio.RegOcp.bits.OcpTrim < 28)
Wayne Roberts 0:9c052ff8dd6a 367 ma = (10 * radio.RegOcp.bits.OcpTrim) - 30;
Wayne Roberts 0:9c052ff8dd6a 368 else
Wayne Roberts 0:9c052ff8dd6a 369 ma = 240;
Wayne Roberts 0:9c052ff8dd6a 370 }
Wayne Roberts 0:9c052ff8dd6a 371
Wayne Roberts 0:9c052ff8dd6a 372
Wayne Roberts 0:9c052ff8dd6a 373 #if 0
Wayne Roberts 0:9c052ff8dd6a 374 void Radio::PrintStatus()
Wayne Roberts 0:9c052ff8dd6a 375 {
Wayne Roberts 0:9c052ff8dd6a 376 #ifdef MAC_DEBUG
Wayne Roberts 0:9c052ff8dd6a 377 radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
Wayne Roberts 0:9c052ff8dd6a 378 switch (radio.RegOpMode.bits.Mode) {
Wayne Roberts 0:9c052ff8dd6a 379 case RF_OPMODE_SLEEP: printf("SLEEP "); break;
Wayne Roberts 0:9c052ff8dd6a 380 case RF_OPMODE_STANDBY: printf("STBY "); break;
Wayne Roberts 0:9c052ff8dd6a 381 case RF_OPMODE_SYNTHESIZER_TX: printf("FSTX "); break;
Wayne Roberts 0:9c052ff8dd6a 382 case RF_OPMODE_TRANSMITTER: printf("TX "); break;
Wayne Roberts 0:9c052ff8dd6a 383 case RF_OPMODE_SYNTHESIZER_RX: printf("FSRX "); break;
Wayne Roberts 0:9c052ff8dd6a 384 case RF_OPMODE_RECEIVER: printf("RXC "); break;
Wayne Roberts 0:9c052ff8dd6a 385 case RF_OPMODE_RECEIVER_SINGLE: printf("RXS "); break;
Wayne Roberts 0:9c052ff8dd6a 386 case RF_OPMODE_CAD: printf("CAD "); break;
Wayne Roberts 0:9c052ff8dd6a 387 }
Wayne Roberts 0:9c052ff8dd6a 388
Wayne Roberts 0:9c052ff8dd6a 389 printf("dio:%u:%u opmode:%02x %.2fMHz sf%ubw%u ", radio.dio0.read(), radio.dio1.read(), radio.RegOpMode.octet, radio.get_frf_MHz(), lora.getSf(), lora.getBw());
Wayne Roberts 0:9c052ff8dd6a 390 lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
Wayne Roberts 0:9c052ff8dd6a 391 printf("irqFlags:%02x\r\n", lora.RegIrqFlags.octet);
Wayne Roberts 0:9c052ff8dd6a 392 #endif /* MAC_DEBUG */
Wayne Roberts 0:9c052ff8dd6a 393 }
Wayne Roberts 0:9c052ff8dd6a 394 #endif /* if 0 */
Wayne Roberts 0:9c052ff8dd6a 395
Wayne Roberts 0:9c052ff8dd6a 396 #ifdef DUTY_ENABLE
Wayne Roberts 0:9c052ff8dd6a 397 us_timestamp_t
Wayne Roberts 0:9c052ff8dd6a 398 Radio::TimeOnAir(RadioModems_t m, uint8_t pktLen)
Wayne Roberts 0:9c052ff8dd6a 399 {
Wayne Roberts 0:9c052ff8dd6a 400 uint32_t airTime = 0;
Wayne Roberts 0:9c052ff8dd6a 401
Wayne Roberts 0:9c052ff8dd6a 402 switch (m)
Wayne Roberts 0:9c052ff8dd6a 403 {
Wayne Roberts 0:9c052ff8dd6a 404 case MODEM_FSK:
Wayne Roberts 0:9c052ff8dd6a 405 {
Wayne Roberts 0:9c052ff8dd6a 406 /* TODO
Wayne Roberts 0:9c052ff8dd6a 407 airTime = round( ( 8 * ( SX1272.Settings.Fsk.PreambleLen +
Wayne Roberts 0:9c052ff8dd6a 408 ( ( SX1272Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
Wayne Roberts 0:9c052ff8dd6a 409 ( ( SX1272.Settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
Wayne Roberts 0:9c052ff8dd6a 410 ( ( ( SX1272Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
Wayne Roberts 0:9c052ff8dd6a 411 pktLen +
Wayne Roberts 0:9c052ff8dd6a 412 ( ( SX1272.Settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
Wayne Roberts 0:9c052ff8dd6a 413 SX1272.Settings.Fsk.Datarate ) * 1e3 );
Wayne Roberts 0:9c052ff8dd6a 414 */
Wayne Roberts 0:9c052ff8dd6a 415 }
Wayne Roberts 0:9c052ff8dd6a 416 break;
Wayne Roberts 0:9c052ff8dd6a 417 case MODEM_LORA:
Wayne Roberts 0:9c052ff8dd6a 418 {
Wayne Roberts 0:9c052ff8dd6a 419 double bw = 0.0;
Wayne Roberts 0:9c052ff8dd6a 420 uint8_t fixLen, bandwidth, LowDatarateOptimize, coderate, crcOn ;
Wayne Roberts 0:9c052ff8dd6a 421 if (radio.type == SX1276) {
Wayne Roberts 0:9c052ff8dd6a 422 coderate = lora.RegModemConfig.sx1276bits.CodingRate;
Wayne Roberts 0:9c052ff8dd6a 423 LowDatarateOptimize = lora.RegModemConfig3.sx1276bits.LowDataRateOptimize;
Wayne Roberts 0:9c052ff8dd6a 424 fixLen = lora.RegModemConfig.sx1276bits.ImplicitHeaderModeOn;
Wayne Roberts 0:9c052ff8dd6a 425 bandwidth = lora.RegModemConfig.sx1276bits.Bw - 7;
Wayne Roberts 0:9c052ff8dd6a 426 crcOn = lora.RegModemConfig2.sx1276bits.RxPayloadCrcOn;
Wayne Roberts 0:9c052ff8dd6a 427 } else if (radio.type == SX1272) {
Wayne Roberts 0:9c052ff8dd6a 428 coderate = lora.RegModemConfig.sx1272bits.CodingRate;
Wayne Roberts 0:9c052ff8dd6a 429 LowDatarateOptimize = lora.RegModemConfig.sx1272bits.LowDataRateOptimize;
Wayne Roberts 0:9c052ff8dd6a 430 fixLen = lora.RegModemConfig.sx1272bits.ImplicitHeaderModeOn;
Wayne Roberts 0:9c052ff8dd6a 431 bandwidth = lora.RegModemConfig.sx1272bits.Bw;
Wayne Roberts 0:9c052ff8dd6a 432 crcOn = lora.RegModemConfig.sx1272bits.RxPayloadCrcOn;
Wayne Roberts 0:9c052ff8dd6a 433 } else
Wayne Roberts 0:9c052ff8dd6a 434 return 0;
Wayne Roberts 0:9c052ff8dd6a 435
Wayne Roberts 0:9c052ff8dd6a 436 switch( bandwidth )
Wayne Roberts 0:9c052ff8dd6a 437 {
Wayne Roberts 0:9c052ff8dd6a 438 case 0: // 125 kHz
Wayne Roberts 0:9c052ff8dd6a 439 bw = 125;//ms: 125e3;
Wayne Roberts 0:9c052ff8dd6a 440 break;
Wayne Roberts 0:9c052ff8dd6a 441 case 1: // 250 kHz
Wayne Roberts 0:9c052ff8dd6a 442 bw = 250;//ms:250e3;
Wayne Roberts 0:9c052ff8dd6a 443 break;
Wayne Roberts 0:9c052ff8dd6a 444 case 2: // 500 kHz
Wayne Roberts 0:9c052ff8dd6a 445 bw = 500;//ms:500e3;
Wayne Roberts 0:9c052ff8dd6a 446 break;
Wayne Roberts 0:9c052ff8dd6a 447 }
Wayne Roberts 0:9c052ff8dd6a 448
Wayne Roberts 0:9c052ff8dd6a 449 // Symbol rate : time for one symbol (secs)
Wayne Roberts 0:9c052ff8dd6a 450 double rs = bw / ( 1 << lora.RegModemConfig2.sx1276bits.SpreadingFactor );
Wayne Roberts 0:9c052ff8dd6a 451 double ts = 1 / rs;
Wayne Roberts 0:9c052ff8dd6a 452 // time of preamble
Wayne Roberts 0:9c052ff8dd6a 453 double tPreamble;
Wayne Roberts 0:9c052ff8dd6a 454 tPreamble = (lora.RegPreamble + 4.25 ) * ts;
Wayne Roberts 0:9c052ff8dd6a 455 // Symbol length of payload and time
Wayne Roberts 0:9c052ff8dd6a 456 double tmp = ceil( ( 8 * pktLen - 4 * lora.RegModemConfig2.sx1276bits.SpreadingFactor +
Wayne Roberts 0:9c052ff8dd6a 457 28 + 16 * crcOn -
Wayne Roberts 0:9c052ff8dd6a 458 ( fixLen ? 20 : 0 ) ) /
Wayne Roberts 0:9c052ff8dd6a 459 ( double )( 4 * ( lora.RegModemConfig2.sx1276bits.SpreadingFactor -
Wayne Roberts 0:9c052ff8dd6a 460 ( ( LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
Wayne Roberts 0:9c052ff8dd6a 461 ( coderate + 4 );
Wayne Roberts 0:9c052ff8dd6a 462 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
Wayne Roberts 0:9c052ff8dd6a 463 double tPayload = nPayload * ts;
Wayne Roberts 0:9c052ff8dd6a 464 // Time on air
Wayne Roberts 0:9c052ff8dd6a 465 double tOnAir = tPreamble + tPayload;
Wayne Roberts 0:9c052ff8dd6a 466 // return ms secs
Wayne Roberts 0:9c052ff8dd6a 467 airTime = floor( tOnAir * 1e3 + 0.999 );
Wayne Roberts 0:9c052ff8dd6a 468 }
Wayne Roberts 0:9c052ff8dd6a 469 break;
Wayne Roberts 0:9c052ff8dd6a 470 }
Wayne Roberts 0:9c052ff8dd6a 471 return airTime;
Wayne Roberts 0:9c052ff8dd6a 472
Wayne Roberts 0:9c052ff8dd6a 473 }
Wayne Roberts 0:9c052ff8dd6a 474 #endif /* DUTY_ENABLE */
Wayne Roberts 0:9c052ff8dd6a 475
Wayne Roberts 0:9c052ff8dd6a 476 void Radio::service()
Wayne Roberts 0:9c052ff8dd6a 477 {
Wayne Roberts 0:9c052ff8dd6a 478 if (pinEvent.dio0) {
Wayne Roberts 17:5f34cbe2ac53 479 dio0UserContext();
Wayne Roberts 17:5f34cbe2ac53 480 pinEvent.txing = 0;
Wayne Roberts 0:9c052ff8dd6a 481 pinEvent.dio0 = 0;
Wayne Roberts 10:3303cf2867d4 482 } else if (radio.dio0.read()) {
Wayne Roberts 10:3303cf2867d4 483 /* fail: missed interrupt */
Wayne Roberts 10:3303cf2867d4 484 dio0isr();
Wayne Roberts 0:9c052ff8dd6a 485 }
Wayne Roberts 0:9c052ff8dd6a 486
Wayne Roberts 0:9c052ff8dd6a 487 if (pinEvent.dio1) {
Wayne Roberts 0:9c052ff8dd6a 488 dio1UserContext();
Wayne Roberts 0:9c052ff8dd6a 489 pinEvent.dio1 = 0;
Wayne Roberts 0:9c052ff8dd6a 490 }
Wayne Roberts 0:9c052ff8dd6a 491 }
Wayne Roberts 0:9c052ff8dd6a 492
Wayne Roberts 0:9c052ff8dd6a 493 uint32_t Radio::lora_toa_us( uint8_t pktLen )
Wayne Roberts 0:9c052ff8dd6a 494 {
Wayne Roberts 0:9c052ff8dd6a 495 uint32_t airTime = 0;
Wayne Roberts 0:9c052ff8dd6a 496 uint8_t chipBW = Radio::lora.getBw();
Wayne Roberts 0:9c052ff8dd6a 497 double bwKHz;
Wayne Roberts 0:9c052ff8dd6a 498 uint8_t LowDataRateOptimize;
Wayne Roberts 0:9c052ff8dd6a 499 bool FixLen;
Wayne Roberts 0:9c052ff8dd6a 500 uint8_t crcOn;
Wayne Roberts 0:9c052ff8dd6a 501 uint16_t preambleLen = Radio::radio.read_u16(REG_LR_PREAMBLEMSB);
Wayne Roberts 0:9c052ff8dd6a 502
Wayne Roberts 0:9c052ff8dd6a 503 Radio::lora.RegModemConfig2.octet = Radio::radio.read_reg(REG_LR_MODEMCONFIG2);
Wayne Roberts 0:9c052ff8dd6a 504 Radio::lora.RegModemConfig.octet = Radio::radio.read_reg(REG_LR_MODEMCONFIG);
Wayne Roberts 0:9c052ff8dd6a 505
Wayne Roberts 0:9c052ff8dd6a 506 if (Radio::radio.type == SX1276) {
Wayne Roberts 0:9c052ff8dd6a 507 chipBW -= 7;
Wayne Roberts 0:9c052ff8dd6a 508 Radio::lora.RegModemConfig3.octet = Radio::radio.read_reg(REG_LR_MODEMCONFIG3);
Wayne Roberts 0:9c052ff8dd6a 509 LowDataRateOptimize = Radio::lora.RegModemConfig3.sx1276bits.LowDataRateOptimize;
Wayne Roberts 0:9c052ff8dd6a 510 FixLen = Radio::lora.RegModemConfig.sx1276bits.ImplicitHeaderModeOn;
Wayne Roberts 0:9c052ff8dd6a 511 crcOn = Radio::lora.RegModemConfig2.sx1276bits.RxPayloadCrcOn;
Wayne Roberts 0:9c052ff8dd6a 512 } else if (Radio::radio.type == SX1272) {
Wayne Roberts 0:9c052ff8dd6a 513 LowDataRateOptimize = Radio::lora.RegModemConfig.sx1272bits.LowDataRateOptimize;
Wayne Roberts 0:9c052ff8dd6a 514 FixLen = Radio::lora.RegModemConfig.sx1272bits.ImplicitHeaderModeOn;
Wayne Roberts 0:9c052ff8dd6a 515 crcOn = Radio::lora.RegModemConfig.sx1272bits.RxPayloadCrcOn;
Wayne Roberts 0:9c052ff8dd6a 516 } else
Wayne Roberts 0:9c052ff8dd6a 517 return 0;
Wayne Roberts 0:9c052ff8dd6a 518
Wayne Roberts 0:9c052ff8dd6a 519 switch (chipBW) {
Wayne Roberts 0:9c052ff8dd6a 520 case 0: bwKHz = 125; break;
Wayne Roberts 0:9c052ff8dd6a 521 case 1: bwKHz = 250; break;
Wayne Roberts 0:9c052ff8dd6a 522 case 2: bwKHz = 500; break;
Wayne Roberts 0:9c052ff8dd6a 523 default: return 0;
Wayne Roberts 0:9c052ff8dd6a 524 }
Wayne Roberts 0:9c052ff8dd6a 525
Wayne Roberts 0:9c052ff8dd6a 526 // Symbol rate : time for one symbol (secs)
Wayne Roberts 0:9c052ff8dd6a 527 double rs = bwKHz / ( 1 << Radio::lora.RegModemConfig2.sx1276bits.SpreadingFactor );
Wayne Roberts 0:9c052ff8dd6a 528 double ts = 1 / rs;
Wayne Roberts 0:9c052ff8dd6a 529 // time of preamble
Wayne Roberts 0:9c052ff8dd6a 530 double tPreamble = ( preambleLen + 4.25 ) * ts;
Wayne Roberts 0:9c052ff8dd6a 531 // Symbol length of payload and time
Wayne Roberts 0:9c052ff8dd6a 532 double tmp = ceil( ( 8 * pktLen - 4 * Radio::lora.RegModemConfig2.sx1276bits.SpreadingFactor +
Wayne Roberts 0:9c052ff8dd6a 533 28 + 16 * crcOn -
Wayne Roberts 0:9c052ff8dd6a 534 ( FixLen ? 20 : 0 ) ) /
Wayne Roberts 0:9c052ff8dd6a 535 ( double )( 4 * ( Radio::lora.RegModemConfig2.sx1276bits.SpreadingFactor -
Wayne Roberts 0:9c052ff8dd6a 536 ( ( LowDataRateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
Wayne Roberts 0:9c052ff8dd6a 537 ( Radio::lora.getCodingRate(false) + 4 );
Wayne Roberts 0:9c052ff8dd6a 538 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
Wayne Roberts 0:9c052ff8dd6a 539 double tPayload = nPayload * ts;
Wayne Roberts 0:9c052ff8dd6a 540 // Time on air
Wayne Roberts 0:9c052ff8dd6a 541 double tOnAir = tPreamble + tPayload;
Wayne Roberts 0:9c052ff8dd6a 542 // return microseconds
Wayne Roberts 0:9c052ff8dd6a 543 airTime = floor( tOnAir * 1000 + 0.999 );
Wayne Roberts 0:9c052ff8dd6a 544
Wayne Roberts 0:9c052ff8dd6a 545 return airTime;
Wayne Roberts 0:9c052ff8dd6a 546 }
Wayne Roberts 0:9c052ff8dd6a 547 #endif /* ..SX127x_H */
Wayne Roberts 0:9c052ff8dd6a 548