Hardware Abstraction Layer, permitting any LoRa application to use any LoRa radio chip

Dependents:   alarm_slave alarm_master lora_p2p lorawan1v1 ... more

radio chip selection

Radio chip driver is not included, allowing choice of radio device.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
if you're using SX1280, then import sx1280 driver into your program.
if you're using LR1110, then import LR1110 driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.
If you're using Type1SJ select target DISCO_L072CZ_LRWAN1 and import sx126x driver into your program.

Pin assigned to arduino LoRa radio shield form-factor

Committer:
Wayne Roberts
Date:
Wed Dec 05 15:04:48 2018 -0800
Revision:
7:ba81f66e56d1
Parent:
5:ab124d3842a8
Child:
11:5111788c4298
Child:
14:94993ae5b164
add instataneous rssi, rx indication on sx1280

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 SX126x_H
Wayne Roberts 0:9c052ff8dd6a 3 #include "SPIu.h"
Wayne Roberts 0:9c052ff8dd6a 4
Wayne Roberts 0:9c052ff8dd6a 5 LowPowerTimer Radio::lpt;
Wayne Roberts 0:9c052ff8dd6a 6 volatile us_timestamp_t Radio::irqAt;
Wayne Roberts 5:ab124d3842a8 7 bool Radio::paOff;
Wayne Roberts 0:9c052ff8dd6a 8
Wayne Roberts 0:9c052ff8dd6a 9 #ifdef TARGET_FF_ARDUINO
Wayne Roberts 0:9c052ff8dd6a 10 SPIu spi(D11, D12, D13); // mosi, miso, sclk
Wayne Roberts 0:9c052ff8dd6a 11 //spi, nss, busy, dio1
Wayne Roberts 0:9c052ff8dd6a 12 SX126x Radio::radio(spi, D7, D3, D5);
Wayne Roberts 0:9c052ff8dd6a 13
Wayne Roberts 0:9c052ff8dd6a 14 DigitalOut antswPower(D8);
Wayne Roberts 0:9c052ff8dd6a 15 AnalogIn xtalSel(A3);
Wayne Roberts 0:9c052ff8dd6a 16
Wayne Roberts 2:c321b5919516 17 DigitalIn Radio::chipType(A2);
Wayne Roberts 0:9c052ff8dd6a 18
Wayne Roberts 0:9c052ff8dd6a 19 #define PINNAME_NRST A0
Wayne Roberts 0:9c052ff8dd6a 20
Wayne Roberts 0:9c052ff8dd6a 21 #define LED_ON 1
Wayne Roberts 0:9c052ff8dd6a 22 #define LED_OFF 0
Wayne Roberts 0:9c052ff8dd6a 23 DigitalOut tx_led(A4);
Wayne Roberts 0:9c052ff8dd6a 24 DigitalOut rx_led(A5);
Wayne Roberts 0:9c052ff8dd6a 25
Wayne Roberts 0:9c052ff8dd6a 26 void Radio::chipModeChange()
Wayne Roberts 0:9c052ff8dd6a 27 {
Wayne Roberts 0:9c052ff8dd6a 28 if (radio.chipMode == CHIPMODE_NONE) {
Wayne Roberts 0:9c052ff8dd6a 29 tx_led = LED_OFF;
Wayne Roberts 0:9c052ff8dd6a 30 rx_led = LED_OFF;
Wayne Roberts 0:9c052ff8dd6a 31 } else if (radio.chipMode == CHIPMODE_TX) {
Wayne Roberts 0:9c052ff8dd6a 32 tx_led = LED_ON;
Wayne Roberts 0:9c052ff8dd6a 33 rx_led = LED_OFF;
Wayne Roberts 0:9c052ff8dd6a 34 } else if (radio.chipMode == CHIPMODE_RX) {
Wayne Roberts 0:9c052ff8dd6a 35 tx_led = LED_OFF;
Wayne Roberts 0:9c052ff8dd6a 36 rx_led = LED_ON;
Wayne Roberts 0:9c052ff8dd6a 37 }
Wayne Roberts 0:9c052ff8dd6a 38 }
Wayne Roberts 0:9c052ff8dd6a 39 #endif /* TARGET_FF_ARDUINO */
Wayne Roberts 0:9c052ff8dd6a 40
Wayne Roberts 0:9c052ff8dd6a 41 const RadioEvents_t* RadioEvents;
Wayne Roberts 0:9c052ff8dd6a 42 PacketParams_t Radio::pp;
Wayne Roberts 0:9c052ff8dd6a 43 RadioModems_t Radio::_m_;
Wayne Roberts 0:9c052ff8dd6a 44
Wayne Roberts 3:122af639cf0b 45 #if defined(TARGET_FF_MORPHO) && !defined(TARGET_DISCO_L072CZ_LRWAN1)
Wayne Roberts 0:9c052ff8dd6a 46 DigitalOut pc3(PC_3); // debug RX indication, for nucleo boards
Wayne Roberts 3:122af639cf0b 47 #define RX_INDICATION pc3
Wayne Roberts 0:9c052ff8dd6a 48 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 0:9c052ff8dd6a 49
Wayne Roberts 0:9c052ff8dd6a 50 void Radio::Rx(unsigned timeout)
Wayne Roberts 0:9c052ff8dd6a 51 {
Wayne Roberts 0:9c052ff8dd6a 52 antswPower = 1;
Wayne Roberts 0:9c052ff8dd6a 53
Wayne Roberts 0:9c052ff8dd6a 54 {
Wayne Roberts 0:9c052ff8dd6a 55 uint8_t buf[8];
Wayne Roberts 0:9c052ff8dd6a 56 IrqFlags_t irqEnable;
Wayne Roberts 0:9c052ff8dd6a 57 irqEnable.word = 0;
Wayne Roberts 0:9c052ff8dd6a 58 irqEnable.bits.RxDone = 1;
Wayne Roberts 0:9c052ff8dd6a 59 irqEnable.bits.Timeout = 1;
Wayne Roberts 0:9c052ff8dd6a 60
Wayne Roberts 0:9c052ff8dd6a 61 buf[0] = irqEnable.word >> 8; // enable bits
Wayne Roberts 0:9c052ff8dd6a 62 buf[1] = irqEnable.word; // enable bits
Wayne Roberts 0:9c052ff8dd6a 63 buf[2] = irqEnable.word >> 8; // dio1
Wayne Roberts 0:9c052ff8dd6a 64 buf[3] = irqEnable.word; // dio1
Wayne Roberts 0:9c052ff8dd6a 65 buf[4] = 0; // dio2
Wayne Roberts 0:9c052ff8dd6a 66 buf[5] = 0; // dio2
Wayne Roberts 0:9c052ff8dd6a 67 buf[6] = 0; // dio3
Wayne Roberts 0:9c052ff8dd6a 68 buf[7] = 0; // dio3
Wayne Roberts 0:9c052ff8dd6a 69 radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
Wayne Roberts 0:9c052ff8dd6a 70 }
Wayne Roberts 0:9c052ff8dd6a 71
Wayne Roberts 3:122af639cf0b 72 #ifdef RX_INDICATION
Wayne Roberts 3:122af639cf0b 73 RX_INDICATION = 1;
Wayne Roberts 3:122af639cf0b 74 #endif
Wayne Roberts 0:9c052ff8dd6a 75 if (timeout == 0)
Wayne Roberts 0:9c052ff8dd6a 76 radio.start_rx(RX_TIMEOUT_CONTINUOUS);
Wayne Roberts 0:9c052ff8dd6a 77 else
Wayne Roberts 0:9c052ff8dd6a 78 radio.start_rx(timeout * RC_TICKS_PER_US);
Wayne Roberts 0:9c052ff8dd6a 79 }
Wayne Roberts 0:9c052ff8dd6a 80
Wayne Roberts 0:9c052ff8dd6a 81 void Radio::Standby()
Wayne Roberts 0:9c052ff8dd6a 82 {
Wayne Roberts 0:9c052ff8dd6a 83 radio.setStandby(STBY_RC); // STBY_XOSC
Wayne Roberts 0:9c052ff8dd6a 84
Wayne Roberts 0:9c052ff8dd6a 85 antswPower = 0;
Wayne Roberts 0:9c052ff8dd6a 86 }
Wayne Roberts 0:9c052ff8dd6a 87
Wayne Roberts 0:9c052ff8dd6a 88 void Radio::Sleep()
Wayne Roberts 0:9c052ff8dd6a 89 {
Wayne Roberts 0:9c052ff8dd6a 90 radio.setSleep(true, false);
Wayne Roberts 0:9c052ff8dd6a 91
Wayne Roberts 0:9c052ff8dd6a 92 antswPower = 0;
Wayne Roberts 0:9c052ff8dd6a 93 }
Wayne Roberts 0:9c052ff8dd6a 94
Wayne Roberts 0:9c052ff8dd6a 95 void Radio::set_tx_dbm(int8_t dbm)
Wayne Roberts 0:9c052ff8dd6a 96 {
Wayne Roberts 5:ab124d3842a8 97 unsigned v = radio.readReg(REG_ADDR_ANACTRL16, 1);
Wayne Roberts 5:ab124d3842a8 98
Wayne Roberts 5:ab124d3842a8 99 if (dbm == PA_OFF_DBM) {
Wayne Roberts 5:ab124d3842a8 100 /* bench test: prevent overloading receiving station (very low tx power) */
Wayne Roberts 5:ab124d3842a8 101 if ((v & 0x10) == 0) {
Wayne Roberts 5:ab124d3842a8 102 v |= 0x10;
Wayne Roberts 5:ab124d3842a8 103 radio.writeReg(REG_ADDR_ANACTRL16, v, 1);
Wayne Roberts 5:ab124d3842a8 104 }
Wayne Roberts 5:ab124d3842a8 105 paOff = true;
Wayne Roberts 5:ab124d3842a8 106 } else {
Wayne Roberts 5:ab124d3842a8 107 radio.set_tx_dbm(chipType == CHIP_TYPE_SX1262, dbm);
Wayne Roberts 5:ab124d3842a8 108 if (v & 0x10) {
Wayne Roberts 5:ab124d3842a8 109 v &= ~0x10;
Wayne Roberts 5:ab124d3842a8 110 radio.writeReg(REG_ADDR_ANACTRL16, v, 1);
Wayne Roberts 5:ab124d3842a8 111 }
Wayne Roberts 5:ab124d3842a8 112 paOff = false;
Wayne Roberts 5:ab124d3842a8 113 }
Wayne Roberts 0:9c052ff8dd6a 114 }
Wayne Roberts 0:9c052ff8dd6a 115
Wayne Roberts 0:9c052ff8dd6a 116 void Radio::SetTxContinuousWave(unsigned hz, int8_t dbm, unsigned timeout_us)
Wayne Roberts 0:9c052ff8dd6a 117 {
Wayne Roberts 0:9c052ff8dd6a 118 SetChannel(hz);
Wayne Roberts 0:9c052ff8dd6a 119 radio.set_tx_dbm(chipType == CHIP_TYPE_SX1262, dbm);
Wayne Roberts 4:57080d572494 120 radio.xfer(OPCODE_SET_TX_CARRIER, 0, 0, NULL);
Wayne Roberts 0:9c052ff8dd6a 121 }
Wayne Roberts 0:9c052ff8dd6a 122
Wayne Roberts 0:9c052ff8dd6a 123 uint32_t Radio::Random(void)
Wayne Roberts 0:9c052ff8dd6a 124 {
Wayne Roberts 0:9c052ff8dd6a 125 uint32_t ret;
Wayne Roberts 0:9c052ff8dd6a 126
Wayne Roberts 0:9c052ff8dd6a 127 radio.start_rx(RX_TIMEOUT_CONTINUOUS);
Wayne Roberts 0:9c052ff8dd6a 128
Wayne Roberts 0:9c052ff8dd6a 129 ret = radio.readReg(REG_ADDR_RANDOM, 4);
Wayne Roberts 0:9c052ff8dd6a 130
Wayne Roberts 0:9c052ff8dd6a 131 Standby();
Wayne Roberts 0:9c052ff8dd6a 132
Wayne Roberts 0:9c052ff8dd6a 133 return ret;
Wayne Roberts 0:9c052ff8dd6a 134 }
Wayne Roberts 0:9c052ff8dd6a 135
Wayne Roberts 0:9c052ff8dd6a 136 bool Radio::CheckRfFrequency(unsigned hz)
Wayne Roberts 0:9c052ff8dd6a 137 {
Wayne Roberts 0:9c052ff8dd6a 138 return true;
Wayne Roberts 0:9c052ff8dd6a 139 }
Wayne Roberts 0:9c052ff8dd6a 140
Wayne Roberts 0:9c052ff8dd6a 141 void Radio::SetChannel(unsigned hz)
Wayne Roberts 0:9c052ff8dd6a 142 {
Wayne Roberts 0:9c052ff8dd6a 143 radio.setMHz(hz / 1000000.0);
Wayne Roberts 0:9c052ff8dd6a 144 }
Wayne Roberts 0:9c052ff8dd6a 145
Wayne Roberts 0:9c052ff8dd6a 146 float Radio::getFrfMHz()
Wayne Roberts 0:9c052ff8dd6a 147 {
Wayne Roberts 0:9c052ff8dd6a 148 return radio.getMHz();
Wayne Roberts 0:9c052ff8dd6a 149 }
Wayne Roberts 0:9c052ff8dd6a 150
Wayne Roberts 0:9c052ff8dd6a 151 void Radio::LoRaPacketConfig(unsigned preambleLen, bool fixLen, bool crcOn, bool invIQ)
Wayne Roberts 0:9c052ff8dd6a 152 {
Wayne Roberts 0:9c052ff8dd6a 153 if (radio.getPacketType() != PACKET_TYPE_LORA)
Wayne Roberts 0:9c052ff8dd6a 154 radio.setPacketType(PACKET_TYPE_LORA);
Wayne Roberts 0:9c052ff8dd6a 155
Wayne Roberts 0:9c052ff8dd6a 156 pp.lora.PreambleLengthHi = preambleLen >> 8;
Wayne Roberts 0:9c052ff8dd6a 157 pp.lora.PreambleLengthLo = preambleLen;
Wayne Roberts 0:9c052ff8dd6a 158 pp.lora.HeaderType = fixLen;
Wayne Roberts 0:9c052ff8dd6a 159 pp.lora.CRCType = crcOn;
Wayne Roberts 0:9c052ff8dd6a 160 pp.lora.InvertIQ = invIQ;
Wayne Roberts 0:9c052ff8dd6a 161
Wayne Roberts 0:9c052ff8dd6a 162 radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, pp.buf);
Wayne Roberts 0:9c052ff8dd6a 163 }
Wayne Roberts 0:9c052ff8dd6a 164
Wayne Roberts 0:9c052ff8dd6a 165 void Radio::GFSKModemConfig(unsigned bps, unsigned bw_hz, unsigned fdev_hz)
Wayne Roberts 0:9c052ff8dd6a 166 {
Wayne Roberts 0:9c052ff8dd6a 167 ModulationParams_t mp;
Wayne Roberts 0:9c052ff8dd6a 168 uint32_t u32;
Wayne Roberts 0:9c052ff8dd6a 169
Wayne Roberts 0:9c052ff8dd6a 170 if (radio.getPacketType() != PACKET_TYPE_GFSK)
Wayne Roberts 0:9c052ff8dd6a 171 radio.setPacketType(PACKET_TYPE_GFSK);
Wayne Roberts 0:9c052ff8dd6a 172
Wayne Roberts 0:9c052ff8dd6a 173 u32 = 32 * (XTAL_FREQ_HZ / bps);
Wayne Roberts 0:9c052ff8dd6a 174 mp.gfsk.bitrateHi = u32 >> 16; // param1
Wayne Roberts 0:9c052ff8dd6a 175 mp.gfsk.bitrateMid = u32 >> 8; // param2
Wayne Roberts 0:9c052ff8dd6a 176 mp.gfsk.bitrateLo = u32; // param3
Wayne Roberts 0:9c052ff8dd6a 177 mp.gfsk.PulseShape = GFSK_SHAPE_BT1_0; // param4
Wayne Roberts 0:9c052ff8dd6a 178 // param5:
Wayne Roberts 0:9c052ff8dd6a 179 if (bw_hz < 5800)
Wayne Roberts 0:9c052ff8dd6a 180 mp.gfsk.bandwidth = GFSK_RX_BW_4800;
Wayne Roberts 0:9c052ff8dd6a 181 else if (bw_hz < 7300)
Wayne Roberts 0:9c052ff8dd6a 182 mp.gfsk.bandwidth = GFSK_RX_BW_5800;
Wayne Roberts 0:9c052ff8dd6a 183 else if (bw_hz < 9700)
Wayne Roberts 0:9c052ff8dd6a 184 mp.gfsk.bandwidth = GFSK_RX_BW_7300;
Wayne Roberts 0:9c052ff8dd6a 185 else if (bw_hz < 11700)
Wayne Roberts 0:9c052ff8dd6a 186 mp.gfsk.bandwidth = GFSK_RX_BW_9700;
Wayne Roberts 0:9c052ff8dd6a 187 else if (bw_hz < 14600)
Wayne Roberts 0:9c052ff8dd6a 188 mp.gfsk.bandwidth = GFSK_RX_BW_11700;
Wayne Roberts 0:9c052ff8dd6a 189 else if (bw_hz < 19500)
Wayne Roberts 0:9c052ff8dd6a 190 mp.gfsk.bandwidth = GFSK_RX_BW_14600;
Wayne Roberts 0:9c052ff8dd6a 191 else if (bw_hz < 23400)
Wayne Roberts 0:9c052ff8dd6a 192 mp.gfsk.bandwidth = GFSK_RX_BW_19500;
Wayne Roberts 0:9c052ff8dd6a 193 else if (bw_hz < 29300)
Wayne Roberts 0:9c052ff8dd6a 194 mp.gfsk.bandwidth = GFSK_RX_BW_23400;
Wayne Roberts 0:9c052ff8dd6a 195 else if (bw_hz < 39000)
Wayne Roberts 0:9c052ff8dd6a 196 mp.gfsk.bandwidth = GFSK_RX_BW_29300;
Wayne Roberts 0:9c052ff8dd6a 197 else if (bw_hz < 46900)
Wayne Roberts 0:9c052ff8dd6a 198 mp.gfsk.bandwidth = GFSK_RX_BW_39000;
Wayne Roberts 0:9c052ff8dd6a 199 else if (bw_hz < 58600)
Wayne Roberts 0:9c052ff8dd6a 200 mp.gfsk.bandwidth = GFSK_RX_BW_46900;
Wayne Roberts 0:9c052ff8dd6a 201 else if (bw_hz < 78200)
Wayne Roberts 0:9c052ff8dd6a 202 mp.gfsk.bandwidth = GFSK_RX_BW_58600;
Wayne Roberts 0:9c052ff8dd6a 203 else if (bw_hz < 93800)
Wayne Roberts 0:9c052ff8dd6a 204 mp.gfsk.bandwidth = GFSK_RX_BW_78200;
Wayne Roberts 0:9c052ff8dd6a 205 else if (bw_hz < 117300)
Wayne Roberts 0:9c052ff8dd6a 206 mp.gfsk.bandwidth = GFSK_RX_BW_93800;
Wayne Roberts 0:9c052ff8dd6a 207 else if (bw_hz < 156200)
Wayne Roberts 0:9c052ff8dd6a 208 mp.gfsk.bandwidth = GFSK_RX_BW_117300;
Wayne Roberts 0:9c052ff8dd6a 209 else if (bw_hz < 187200)
Wayne Roberts 0:9c052ff8dd6a 210 mp.gfsk.bandwidth = GFSK_RX_BW_156200;
Wayne Roberts 0:9c052ff8dd6a 211 else if (bw_hz < 234300)
Wayne Roberts 0:9c052ff8dd6a 212 mp.gfsk.bandwidth = GFSK_RX_BW_187200;
Wayne Roberts 0:9c052ff8dd6a 213 else if (bw_hz < 312000)
Wayne Roberts 0:9c052ff8dd6a 214 mp.gfsk.bandwidth = GFSK_RX_BW_234300;
Wayne Roberts 0:9c052ff8dd6a 215 else if (bw_hz < 373600)
Wayne Roberts 0:9c052ff8dd6a 216 mp.gfsk.bandwidth = GFSK_RX_BW_312000;
Wayne Roberts 0:9c052ff8dd6a 217 else if (bw_hz < 467000)
Wayne Roberts 0:9c052ff8dd6a 218 mp.gfsk.bandwidth = GFSK_RX_BW_373600;
Wayne Roberts 0:9c052ff8dd6a 219 else
Wayne Roberts 0:9c052ff8dd6a 220 mp.gfsk.bandwidth = GFSK_RX_BW_467000;
Wayne Roberts 0:9c052ff8dd6a 221
Wayne Roberts 0:9c052ff8dd6a 222 if (fdev_hz > 0) {
Wayne Roberts 0:9c052ff8dd6a 223 u32 = fdev_hz / FREQ_STEP;
Wayne Roberts 0:9c052ff8dd6a 224 mp.gfsk.fdevHi = u32 >> 16; // param6
Wayne Roberts 0:9c052ff8dd6a 225 mp.gfsk.fdevMid = u32 >> 8; // param7
Wayne Roberts 0:9c052ff8dd6a 226 mp.gfsk.fdevLo = u32; // param8
Wayne Roberts 0:9c052ff8dd6a 227 }
Wayne Roberts 0:9c052ff8dd6a 228
Wayne Roberts 0:9c052ff8dd6a 229 radio.xfer(OPCODE_SET_MODULATION_PARAMS, 8, 0, mp.buf);
Wayne Roberts 0:9c052ff8dd6a 230 }
Wayne Roberts 0:9c052ff8dd6a 231
Wayne Roberts 0:9c052ff8dd6a 232 void Radio::GFSKPacketConfig(unsigned preambleLen, bool fixLen, bool crcOn)
Wayne Roberts 0:9c052ff8dd6a 233 {
Wayne Roberts 0:9c052ff8dd6a 234 if (radio.getPacketType() != PACKET_TYPE_GFSK)
Wayne Roberts 0:9c052ff8dd6a 235 radio.setPacketType(PACKET_TYPE_GFSK);
Wayne Roberts 0:9c052ff8dd6a 236
Wayne Roberts 0:9c052ff8dd6a 237 pp.gfsk.PreambleLengthHi = preambleLen >> 8;
Wayne Roberts 0:9c052ff8dd6a 238 pp.gfsk.PreambleLengthLo = preambleLen;
Wayne Roberts 0:9c052ff8dd6a 239 pp.gfsk.PreambleDetectorLength = GFSK_PREAMBLE_DETECTOR_LENGTH_16BITS;
Wayne Roberts 0:9c052ff8dd6a 240 pp.gfsk.SyncWordLength = 24; // 0xC194C1
Wayne Roberts 0:9c052ff8dd6a 241 pp.gfsk.AddrComp = 0;
Wayne Roberts 0:9c052ff8dd6a 242 pp.gfsk.PacketType = fixLen;
Wayne Roberts 0:9c052ff8dd6a 243 if (crcOn)
Wayne Roberts 0:9c052ff8dd6a 244 pp.gfsk.CRCType = GFSK_CRC_2_BYTE;
Wayne Roberts 0:9c052ff8dd6a 245 else
Wayne Roberts 0:9c052ff8dd6a 246 pp.gfsk.CRCType = GFSK_CRC_OFF;
Wayne Roberts 0:9c052ff8dd6a 247
Wayne Roberts 0:9c052ff8dd6a 248 //TODO pp.gfsk.PayloadLength = ;
Wayne Roberts 0:9c052ff8dd6a 249
Wayne Roberts 0:9c052ff8dd6a 250 radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, pp.buf);
Wayne Roberts 0:9c052ff8dd6a 251 }
Wayne Roberts 0:9c052ff8dd6a 252
Wayne Roberts 0:9c052ff8dd6a 253 void Radio::LoRaModemConfig(unsigned bwKHz, uint8_t sf, uint8_t cr)
Wayne Roberts 0:9c052ff8dd6a 254 {
Wayne Roberts 0:9c052ff8dd6a 255 ModulationParams_t mp;
Wayne Roberts 0:9c052ff8dd6a 256 float khz, sp;
Wayne Roberts 0:9c052ff8dd6a 257
Wayne Roberts 0:9c052ff8dd6a 258 if (radio.getPacketType() != PACKET_TYPE_LORA)
Wayne Roberts 0:9c052ff8dd6a 259 radio.setPacketType(PACKET_TYPE_LORA);
Wayne Roberts 0:9c052ff8dd6a 260
Wayne Roberts 0:9c052ff8dd6a 261 if (bwKHz > 250) {
Wayne Roberts 0:9c052ff8dd6a 262 mp.lora.bandwidth = LORA_BW_500;
Wayne Roberts 0:9c052ff8dd6a 263 khz = 500;
Wayne Roberts 0:9c052ff8dd6a 264 } else if (bwKHz > 125) {
Wayne Roberts 0:9c052ff8dd6a 265 mp.lora.bandwidth = LORA_BW_250;
Wayne Roberts 0:9c052ff8dd6a 266 khz = 250;
Wayne Roberts 0:9c052ff8dd6a 267 } else if (bwKHz > 63) {
Wayne Roberts 0:9c052ff8dd6a 268 mp.lora.bandwidth = LORA_BW_125;
Wayne Roberts 0:9c052ff8dd6a 269 khz = 125;
Wayne Roberts 0:9c052ff8dd6a 270 } else if (bwKHz > 42) {
Wayne Roberts 0:9c052ff8dd6a 271 mp.lora.bandwidth = LORA_BW_62;
Wayne Roberts 0:9c052ff8dd6a 272 khz = 62.5;
Wayne Roberts 0:9c052ff8dd6a 273 } else if (bwKHz > 32) {
Wayne Roberts 0:9c052ff8dd6a 274 mp.lora.bandwidth = LORA_BW_41;
Wayne Roberts 0:9c052ff8dd6a 275 khz = 41.67;
Wayne Roberts 0:9c052ff8dd6a 276 } else if (bwKHz > 21) {
Wayne Roberts 0:9c052ff8dd6a 277 mp.lora.bandwidth = LORA_BW_31;
Wayne Roberts 0:9c052ff8dd6a 278 khz = 31.25;
Wayne Roberts 0:9c052ff8dd6a 279 } else if (bwKHz > 16) {
Wayne Roberts 0:9c052ff8dd6a 280 mp.lora.bandwidth = LORA_BW_20;
Wayne Roberts 0:9c052ff8dd6a 281 khz = 20.83;
Wayne Roberts 0:9c052ff8dd6a 282 } else if (bwKHz > 11) {
Wayne Roberts 0:9c052ff8dd6a 283 mp.lora.bandwidth = LORA_BW_15;
Wayne Roberts 0:9c052ff8dd6a 284 khz = 15.625;
Wayne Roberts 0:9c052ff8dd6a 285 } else if (bwKHz > 11) {
Wayne Roberts 0:9c052ff8dd6a 286 mp.lora.bandwidth = LORA_BW_10;
Wayne Roberts 0:9c052ff8dd6a 287 khz = 10.42;
Wayne Roberts 0:9c052ff8dd6a 288 } else {
Wayne Roberts 0:9c052ff8dd6a 289 mp.lora.bandwidth = LORA_BW_7;
Wayne Roberts 0:9c052ff8dd6a 290 khz = 7.81;
Wayne Roberts 0:9c052ff8dd6a 291 }
Wayne Roberts 0:9c052ff8dd6a 292
Wayne Roberts 0:9c052ff8dd6a 293 mp.lora.spreadingFactor = sf;
Wayne Roberts 0:9c052ff8dd6a 294 mp.lora.codingRate = cr;
Wayne Roberts 0:9c052ff8dd6a 295
Wayne Roberts 0:9c052ff8dd6a 296 sp = (1 << mp.lora.spreadingFactor) / khz;
Wayne Roberts 0:9c052ff8dd6a 297 /* TCXO dependent */
Wayne Roberts 0:9c052ff8dd6a 298 if (sp > 16)
Wayne Roberts 0:9c052ff8dd6a 299 mp.lora.LowDatarateOptimize = 1; // param4
Wayne Roberts 0:9c052ff8dd6a 300 else
Wayne Roberts 0:9c052ff8dd6a 301 mp.lora.LowDatarateOptimize = 0; // param4
Wayne Roberts 0:9c052ff8dd6a 302
Wayne Roberts 0:9c052ff8dd6a 303 radio.xfer(OPCODE_SET_MODULATION_PARAMS, 4, 0, mp.buf);
Wayne Roberts 0:9c052ff8dd6a 304
Wayne Roberts 0:9c052ff8dd6a 305 }
Wayne Roberts 0:9c052ff8dd6a 306
Wayne Roberts 0:9c052ff8dd6a 307 void Radio::SetLoRaSymbolTimeout(uint8_t symbs)
Wayne Roberts 0:9c052ff8dd6a 308 {
Wayne Roberts 0:9c052ff8dd6a 309 if (radio.getPacketType() != PACKET_TYPE_LORA)
Wayne Roberts 0:9c052ff8dd6a 310 radio.setPacketType(PACKET_TYPE_LORA);
Wayne Roberts 0:9c052ff8dd6a 311
Wayne Roberts 0:9c052ff8dd6a 312 radio.xfer(OPCODE_SET_LORA_SYMBOL_TIMEOUT, 1, 0, &symbs);
Wayne Roberts 0:9c052ff8dd6a 313 }
Wayne Roberts 0:9c052ff8dd6a 314
Wayne Roberts 7:ba81f66e56d1 315 float Radio::GetRssiInst()
Wayne Roberts 7:ba81f66e56d1 316 {
Wayne Roberts 7:ba81f66e56d1 317 uint8_t buf[8];
Wayne Roberts 7:ba81f66e56d1 318
Wayne Roberts 7:ba81f66e56d1 319 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 7:ba81f66e56d1 320 return buf[1] / -2.0;
Wayne Roberts 7:ba81f66e56d1 321 }
Wayne Roberts 7:ba81f66e56d1 322
Wayne Roberts 0:9c052ff8dd6a 323 int Radio::Send(uint8_t size, timestamp_t maxListenTime, timestamp_t channelFreeTime, int rssiThresh)
Wayne Roberts 0:9c052ff8dd6a 324 {
Wayne Roberts 0:9c052ff8dd6a 325 uint8_t buf[8];
Wayne Roberts 0:9c052ff8dd6a 326 uint8_t pktType = radio.getPacketType();
Wayne Roberts 0:9c052ff8dd6a 327
Wayne Roberts 0:9c052ff8dd6a 328 buf[0] = 0; // TX base address
Wayne Roberts 0:9c052ff8dd6a 329 buf[1] = 0; // RX base address
Wayne Roberts 0:9c052ff8dd6a 330 radio.xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf);
Wayne Roberts 0:9c052ff8dd6a 331
Wayne Roberts 0:9c052ff8dd6a 332 if (pktType == PACKET_TYPE_GFSK) {
Wayne Roberts 0:9c052ff8dd6a 333 pp.gfsk.PayloadLength = size;
Wayne Roberts 0:9c052ff8dd6a 334 radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, pp.buf);
Wayne Roberts 0:9c052ff8dd6a 335 } else if (pktType == PACKET_TYPE_LORA) {
Wayne Roberts 0:9c052ff8dd6a 336 pp.lora.PayloadLength = size;
Wayne Roberts 0:9c052ff8dd6a 337 radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, pp.buf);
Wayne Roberts 0:9c052ff8dd6a 338 }
Wayne Roberts 0:9c052ff8dd6a 339
Wayne Roberts 0:9c052ff8dd6a 340 {
Wayne Roberts 0:9c052ff8dd6a 341 IrqFlags_t irqEnable;
Wayne Roberts 0:9c052ff8dd6a 342 irqEnable.word = 0;
Wayne Roberts 0:9c052ff8dd6a 343 irqEnable.bits.TxDone = 1;
Wayne Roberts 0:9c052ff8dd6a 344 irqEnable.bits.Timeout = 1;
Wayne Roberts 0:9c052ff8dd6a 345
Wayne Roberts 0:9c052ff8dd6a 346 buf[0] = irqEnable.word >> 8; // enable bits
Wayne Roberts 0:9c052ff8dd6a 347 buf[1] = irqEnable.word; // enable bits
Wayne Roberts 0:9c052ff8dd6a 348 buf[2] = irqEnable.word >> 8; // dio1
Wayne Roberts 0:9c052ff8dd6a 349 buf[3] = irqEnable.word; // dio1
Wayne Roberts 0:9c052ff8dd6a 350 buf[4] = 0; // dio2
Wayne Roberts 0:9c052ff8dd6a 351 buf[5] = 0; // dio2
Wayne Roberts 0:9c052ff8dd6a 352 buf[6] = 0; // dio3
Wayne Roberts 0:9c052ff8dd6a 353 buf[7] = 0; // dio3
Wayne Roberts 0:9c052ff8dd6a 354 radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
Wayne Roberts 0:9c052ff8dd6a 355 }
Wayne Roberts 0:9c052ff8dd6a 356
Wayne Roberts 0:9c052ff8dd6a 357 antswPower = 1;
Wayne Roberts 0:9c052ff8dd6a 358
Wayne Roberts 0:9c052ff8dd6a 359 if (maxListenTime > 0) {
Wayne Roberts 0:9c052ff8dd6a 360 int rssi;
Wayne Roberts 0:9c052ff8dd6a 361 us_timestamp_t startAt, chFreeAt, now;
Wayne Roberts 0:9c052ff8dd6a 362 uint8_t symbs = 0;
Wayne Roberts 0:9c052ff8dd6a 363
Wayne Roberts 0:9c052ff8dd6a 364 radio.xfer(OPCODE_SET_LORA_SYMBOL_TIMEOUT, 1, 0, &symbs);
Wayne Roberts 0:9c052ff8dd6a 365
Wayne Roberts 0:9c052ff8dd6a 366 radio.start_rx(RX_TIMEOUT_CONTINUOUS);
Wayne Roberts 0:9c052ff8dd6a 367 startAt = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 368 Lstart:
Wayne Roberts 0:9c052ff8dd6a 369 do {
Wayne Roberts 0:9c052ff8dd6a 370 now = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 371 if ((now - startAt) > maxListenTime) {
Wayne Roberts 0:9c052ff8dd6a 372 return -1;
Wayne Roberts 0:9c052ff8dd6a 373 }
Wayne Roberts 0:9c052ff8dd6a 374 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 0:9c052ff8dd6a 375 rssi = buf[1] / -2;
Wayne Roberts 0:9c052ff8dd6a 376 } while (rssi > rssiThresh);
Wayne Roberts 0:9c052ff8dd6a 377 chFreeAt = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 378 do {
Wayne Roberts 0:9c052ff8dd6a 379 now = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 380 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 0:9c052ff8dd6a 381 rssi = buf[1] / -2;
Wayne Roberts 0:9c052ff8dd6a 382 if (rssi > rssiThresh) {
Wayne Roberts 0:9c052ff8dd6a 383 goto Lstart;
Wayne Roberts 0:9c052ff8dd6a 384 }
Wayne Roberts 0:9c052ff8dd6a 385 } while ((now - chFreeAt) < channelFreeTime);
Wayne Roberts 0:9c052ff8dd6a 386 }
Wayne Roberts 0:9c052ff8dd6a 387
Wayne Roberts 5:ab124d3842a8 388 if (paOff) {
Wayne Roberts 5:ab124d3842a8 389 unsigned v = radio.readReg(REG_ADDR_ANACTRL16, 1);
Wayne Roberts 5:ab124d3842a8 390 if ((v & 0x10) == 0) {
Wayne Roberts 5:ab124d3842a8 391 v |= 0x10;
Wayne Roberts 5:ab124d3842a8 392 radio.writeReg(REG_ADDR_ANACTRL16, v, 1);
Wayne Roberts 5:ab124d3842a8 393 }
Wayne Roberts 5:ab124d3842a8 394 }
Wayne Roberts 0:9c052ff8dd6a 395 radio.start_tx(size);
Wayne Roberts 0:9c052ff8dd6a 396
Wayne Roberts 0:9c052ff8dd6a 397 return 0;
Wayne Roberts 0:9c052ff8dd6a 398 } // ..Send()
Wayne Roberts 0:9c052ff8dd6a 399
Wayne Roberts 1:e79b0a55135f 400 void Radio::SetRxMaxPayloadLength(uint8_t max)
Wayne Roberts 0:9c052ff8dd6a 401 {
Wayne Roberts 1:e79b0a55135f 402 uint8_t pktType = radio.getPacketType();
Wayne Roberts 0:9c052ff8dd6a 403
Wayne Roberts 1:e79b0a55135f 404 if (pktType == PACKET_TYPE_GFSK) {
Wayne Roberts 0:9c052ff8dd6a 405 pp.gfsk.PayloadLength = max;
Wayne Roberts 1:e79b0a55135f 406 radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, pp.buf);
Wayne Roberts 1:e79b0a55135f 407 } else if (pktType == PACKET_TYPE_LORA) {
Wayne Roberts 0:9c052ff8dd6a 408 pp.lora.PayloadLength = max;
Wayne Roberts 1:e79b0a55135f 409 radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, pp.buf);
Wayne Roberts 0:9c052ff8dd6a 410 }
Wayne Roberts 0:9c052ff8dd6a 411 }
Wayne Roberts 0:9c052ff8dd6a 412
Wayne Roberts 0:9c052ff8dd6a 413 void Radio::dio1_top_half()
Wayne Roberts 0:9c052ff8dd6a 414 {
Wayne Roberts 0:9c052ff8dd6a 415 irqAt = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 416
Wayne Roberts 0:9c052ff8dd6a 417 if (radio.chipMode == CHIPMODE_TX) {
Wayne Roberts 0:9c052ff8dd6a 418 /* TxDone handling requires low latency */
Wayne Roberts 0:9c052ff8dd6a 419 if (RadioEvents->TxDone_topHalf) {
Wayne Roberts 0:9c052ff8dd6a 420 RadioEvents->TxDone_topHalf();
Wayne Roberts 0:9c052ff8dd6a 421 }
Wayne Roberts 0:9c052ff8dd6a 422 } else {
Wayne Roberts 3:122af639cf0b 423 #ifdef RX_INDICATION
Wayne Roberts 3:122af639cf0b 424 RX_INDICATION = 0;
Wayne Roberts 3:122af639cf0b 425 #endif
Wayne Roberts 0:9c052ff8dd6a 426 }
Wayne Roberts 0:9c052ff8dd6a 427 }
Wayne Roberts 0:9c052ff8dd6a 428
Wayne Roberts 0:9c052ff8dd6a 429 void Radio::timeout_callback(bool tx)
Wayne Roberts 0:9c052ff8dd6a 430 {
Wayne Roberts 0:9c052ff8dd6a 431 if (!tx) {
Wayne Roberts 0:9c052ff8dd6a 432 if (RadioEvents->RxTimeout)
Wayne Roberts 0:9c052ff8dd6a 433 RadioEvents->RxTimeout();
Wayne Roberts 3:122af639cf0b 434 #ifdef RX_INDICATION
Wayne Roberts 3:122af639cf0b 435 RX_INDICATION = 0;
Wayne Roberts 3:122af639cf0b 436 #endif
Wayne Roberts 0:9c052ff8dd6a 437 } // else TODO tx timeout
Wayne Roberts 0:9c052ff8dd6a 438 }
Wayne Roberts 0:9c052ff8dd6a 439
Wayne Roberts 0:9c052ff8dd6a 440 void Radio::rx_done(uint8_t size, float rssi, float snr)
Wayne Roberts 0:9c052ff8dd6a 441 {
Wayne Roberts 0:9c052ff8dd6a 442 RadioEvents->RxDone(size, rssi, snr);
Wayne Roberts 0:9c052ff8dd6a 443 }
Wayne Roberts 0:9c052ff8dd6a 444
Wayne Roberts 0:9c052ff8dd6a 445 void Radio::txDoneBottom()
Wayne Roberts 0:9c052ff8dd6a 446 {
Wayne Roberts 0:9c052ff8dd6a 447 if (RadioEvents->TxDone_botHalf)
Wayne Roberts 0:9c052ff8dd6a 448 RadioEvents->TxDone_botHalf();
Wayne Roberts 0:9c052ff8dd6a 449 }
Wayne Roberts 0:9c052ff8dd6a 450
Wayne Roberts 0:9c052ff8dd6a 451 void Radio::Init(const RadioEvents_t* e)
Wayne Roberts 0:9c052ff8dd6a 452 {
Wayne Roberts 0:9c052ff8dd6a 453 radio.txDone = txDoneBottom;
Wayne Roberts 0:9c052ff8dd6a 454 radio.rxDone = rx_done;
Wayne Roberts 0:9c052ff8dd6a 455 radio.timeout = timeout_callback;
Wayne Roberts 0:9c052ff8dd6a 456 radio.chipModeChange = chipModeChange;
Wayne Roberts 0:9c052ff8dd6a 457 radio.dio1_topHalf = dio1_top_half;
Wayne Roberts 0:9c052ff8dd6a 458
Wayne Roberts 0:9c052ff8dd6a 459 RadioEvents = e;
Wayne Roberts 0:9c052ff8dd6a 460 lpt.start();
Wayne Roberts 0:9c052ff8dd6a 461
Wayne Roberts 0:9c052ff8dd6a 462 radio.SetDIO2AsRfSwitchCtrl(1);
Wayne Roberts 0:9c052ff8dd6a 463 }
Wayne Roberts 0:9c052ff8dd6a 464
Wayne Roberts 0:9c052ff8dd6a 465 void Radio::service()
Wayne Roberts 0:9c052ff8dd6a 466 {
Wayne Roberts 0:9c052ff8dd6a 467 radio.service();
Wayne Roberts 0:9c052ff8dd6a 468 }
Wayne Roberts 0:9c052ff8dd6a 469
Wayne Roberts 0:9c052ff8dd6a 470 void Radio::SetPublicNetwork(bool en)
Wayne Roberts 0:9c052ff8dd6a 471 {
Wayne Roberts 0:9c052ff8dd6a 472 uint16_t ppg;
Wayne Roberts 0:9c052ff8dd6a 473
Wayne Roberts 0:9c052ff8dd6a 474 if (en)
Wayne Roberts 0:9c052ff8dd6a 475 ppg = 0x3444;
Wayne Roberts 0:9c052ff8dd6a 476 else
Wayne Roberts 0:9c052ff8dd6a 477 ppg = 0x1424;
Wayne Roberts 0:9c052ff8dd6a 478
Wayne Roberts 0:9c052ff8dd6a 479 radio.writeReg(REG_ADDR_LORA_SYNC, ppg, 2);
Wayne Roberts 0:9c052ff8dd6a 480 }
Wayne Roberts 0:9c052ff8dd6a 481
Wayne Roberts 0:9c052ff8dd6a 482 uint32_t Radio::lora_toa_us( uint8_t pktLen )
Wayne Roberts 0:9c052ff8dd6a 483 {
Wayne Roberts 0:9c052ff8dd6a 484 double bwKHz;
Wayne Roberts 0:9c052ff8dd6a 485 unsigned preambleLen;
Wayne Roberts 0:9c052ff8dd6a 486 ModulationParams_t mp;
Wayne Roberts 0:9c052ff8dd6a 487
Wayne Roberts 0:9c052ff8dd6a 488 {
Wayne Roberts 0:9c052ff8dd6a 489 loraConfig1_t conf1;
Wayne Roberts 0:9c052ff8dd6a 490 conf1.octet = radio.readReg(REG_ADDR_LORA_CONFIG1, 1);
Wayne Roberts 0:9c052ff8dd6a 491 mp.lora.LowDatarateOptimize = conf1.bits.ppm_offset;
Wayne Roberts 0:9c052ff8dd6a 492 pp.lora.HeaderType = conf1.bits.implicit_header;
Wayne Roberts 0:9c052ff8dd6a 493 pp.lora.InvertIQ = conf1.bits.rx_invert_iq;
Wayne Roberts 0:9c052ff8dd6a 494 mp.lora.codingRate = conf1.bits.tx_coding_rate;
Wayne Roberts 0:9c052ff8dd6a 495 }
Wayne Roberts 0:9c052ff8dd6a 496
Wayne Roberts 0:9c052ff8dd6a 497 {
Wayne Roberts 0:9c052ff8dd6a 498 loraConfig2_t conf2;
Wayne Roberts 0:9c052ff8dd6a 499 conf2.octet = radio.readReg(REG_ADDR_LORA_CONFIG2, 1);
Wayne Roberts 0:9c052ff8dd6a 500 pp.lora.CRCType = conf2.bits.tx_payload_crc16_en;
Wayne Roberts 0:9c052ff8dd6a 501 }
Wayne Roberts 0:9c052ff8dd6a 502
Wayne Roberts 0:9c052ff8dd6a 503
Wayne Roberts 0:9c052ff8dd6a 504 {
Wayne Roberts 0:9c052ff8dd6a 505 uint32_t val;
Wayne Roberts 0:9c052ff8dd6a 506 val = radio.readReg(REG_ADDR_LORA_PREAMBLE_SYMBNB, 2);
Wayne Roberts 0:9c052ff8dd6a 507 pp.lora.PreambleLengthHi = val >> 8;
Wayne Roberts 0:9c052ff8dd6a 508 pp.lora.PreambleLengthLo = val;
Wayne Roberts 0:9c052ff8dd6a 509 }
Wayne Roberts 0:9c052ff8dd6a 510
Wayne Roberts 0:9c052ff8dd6a 511 preambleLen = (pp.lora.PreambleLengthHi << 8) + pp.lora.PreambleLengthLo;
Wayne Roberts 0:9c052ff8dd6a 512
Wayne Roberts 0:9c052ff8dd6a 513 {
Wayne Roberts 0:9c052ff8dd6a 514 loraConfig0_t conf0;
Wayne Roberts 0:9c052ff8dd6a 515 conf0.octet = radio.readReg(REG_ADDR_LORA_CONFIG0, 1);
Wayne Roberts 0:9c052ff8dd6a 516 mp.lora.spreadingFactor = conf0.bits.modem_sf;
Wayne Roberts 0:9c052ff8dd6a 517 mp.lora.bandwidth = conf0.bits.modem_bw;
Wayne Roberts 0:9c052ff8dd6a 518 }
Wayne Roberts 0:9c052ff8dd6a 519
Wayne Roberts 0:9c052ff8dd6a 520 switch (mp.lora.bandwidth) {
Wayne Roberts 0:9c052ff8dd6a 521 case LORA_BW_7: bwKHz = 7.81; break;
Wayne Roberts 0:9c052ff8dd6a 522 case LORA_BW_10: bwKHz = 10.42; break;
Wayne Roberts 0:9c052ff8dd6a 523 case LORA_BW_15: bwKHz = 15.625; break;
Wayne Roberts 0:9c052ff8dd6a 524 case LORA_BW_20: bwKHz = 20.83; break;
Wayne Roberts 0:9c052ff8dd6a 525 case LORA_BW_31: bwKHz = 31.25; break;
Wayne Roberts 0:9c052ff8dd6a 526 case LORA_BW_41: bwKHz = 41.67; break;
Wayne Roberts 0:9c052ff8dd6a 527 case LORA_BW_62: bwKHz = 62.5; break;
Wayne Roberts 0:9c052ff8dd6a 528 case LORA_BW_125: bwKHz = 125; break;
Wayne Roberts 0:9c052ff8dd6a 529 case LORA_BW_250: bwKHz = 250; break;
Wayne Roberts 0:9c052ff8dd6a 530 case LORA_BW_500: bwKHz = 500; break;
Wayne Roberts 0:9c052ff8dd6a 531 default: bwKHz = 0; break;
Wayne Roberts 0:9c052ff8dd6a 532 }
Wayne Roberts 0:9c052ff8dd6a 533
Wayne Roberts 0:9c052ff8dd6a 534 // Symbol rate : time for one symbol (secs)
Wayne Roberts 0:9c052ff8dd6a 535 double rs = bwKHz / ( 1 << mp.lora.spreadingFactor );
Wayne Roberts 0:9c052ff8dd6a 536 double ts = 1 / rs;
Wayne Roberts 0:9c052ff8dd6a 537 // time of preamble
Wayne Roberts 0:9c052ff8dd6a 538 double tPreamble = ( preambleLen + 4.25 ) * ts;
Wayne Roberts 0:9c052ff8dd6a 539 // Symbol length of payload and time
Wayne Roberts 0:9c052ff8dd6a 540
Wayne Roberts 0:9c052ff8dd6a 541 double tmp = ceil( ( 8 * pktLen - 4 * mp.lora.spreadingFactor +
Wayne Roberts 0:9c052ff8dd6a 542 28 + 16 * pp.lora.CRCType -
Wayne Roberts 0:9c052ff8dd6a 543 ( pp.lora.HeaderType ? 20 : 0 ) ) /
Wayne Roberts 0:9c052ff8dd6a 544 ( double )( 4 * ( mp.lora.spreadingFactor -
Wayne Roberts 0:9c052ff8dd6a 545 ( ( mp.lora.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
Wayne Roberts 0:9c052ff8dd6a 546 ( mp.lora.codingRate + 4 );
Wayne Roberts 0:9c052ff8dd6a 547 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
Wayne Roberts 0:9c052ff8dd6a 548 double tPayload = nPayload * ts;
Wayne Roberts 0:9c052ff8dd6a 549 // Time on air
Wayne Roberts 0:9c052ff8dd6a 550 double tOnAir = tPreamble + tPayload;
Wayne Roberts 0:9c052ff8dd6a 551 // return microseconds
Wayne Roberts 0:9c052ff8dd6a 552 return floor( tOnAir * 1000 + 0.999 );
Wayne Roberts 0:9c052ff8dd6a 553 }
Wayne Roberts 0:9c052ff8dd6a 554
Wayne Roberts 0:9c052ff8dd6a 555 #if 0
Wayne Roberts 0:9c052ff8dd6a 556 void Radio::PrintStatus()
Wayne Roberts 0:9c052ff8dd6a 557 {
Wayne Roberts 0:9c052ff8dd6a 558 /* uint8_t buf[4];
Wayne Roberts 0:9c052ff8dd6a 559 status_t status;
Wayne Roberts 0:9c052ff8dd6a 560 IrqFlags_t irqFlags;
Wayne Roberts 0:9c052ff8dd6a 561 radio.xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf);
Wayne Roberts 0:9c052ff8dd6a 562 irqFlags.word = buf[1] << 8;
Wayne Roberts 0:9c052ff8dd6a 563 irqFlags.word |= buf[2];
Wayne Roberts 0:9c052ff8dd6a 564
Wayne Roberts 0:9c052ff8dd6a 565 printf("dio1:%u irqFlags:%04x\r\n", radio.getDIO1(), irqFlags.word);
Wayne Roberts 0:9c052ff8dd6a 566 radio.xfer(OPCODE_GET_STATUS, 0, 1, &status.octet);
Wayne Roberts 0:9c052ff8dd6a 567 radio.PrintChipStatus(status);*/
Wayne Roberts 0:9c052ff8dd6a 568 {
Wayne Roberts 0:9c052ff8dd6a 569 loraConfig1_t conf1;
Wayne Roberts 0:9c052ff8dd6a 570 conf1.octet = radio.readReg(REG_ADDR_LORA_CONFIG1, 1);
Wayne Roberts 0:9c052ff8dd6a 571 printf("ldro%u %s %s cr%u\r\n",
Wayne Roberts 0:9c052ff8dd6a 572 conf1.bits.ppm_offset,
Wayne Roberts 0:9c052ff8dd6a 573 conf1.bits.implicit_header ? "fixed" : "var",
Wayne Roberts 0:9c052ff8dd6a 574 conf1.bits.rx_invert_iq ? "inv" : "std",
Wayne Roberts 0:9c052ff8dd6a 575 conf1.bits.tx_coding_rate
Wayne Roberts 0:9c052ff8dd6a 576 );
Wayne Roberts 0:9c052ff8dd6a 577 }
Wayne Roberts 0:9c052ff8dd6a 578
Wayne Roberts 0:9c052ff8dd6a 579 {
Wayne Roberts 0:9c052ff8dd6a 580 loraConfig2_t conf2;
Wayne Roberts 0:9c052ff8dd6a 581 conf2.octet = radio.readReg(REG_ADDR_LORA_CONFIG2, 1);
Wayne Roberts 0:9c052ff8dd6a 582 printf("crc16en:%u ", conf2.bits.tx_payload_crc16_en);
Wayne Roberts 0:9c052ff8dd6a 583 }
Wayne Roberts 0:9c052ff8dd6a 584
Wayne Roberts 0:9c052ff8dd6a 585
Wayne Roberts 0:9c052ff8dd6a 586 {
Wayne Roberts 0:9c052ff8dd6a 587 uint32_t val;
Wayne Roberts 0:9c052ff8dd6a 588 val = radio.readReg(REG_ADDR_LORA_PREAMBLE_SYMBNB, 2);
Wayne Roberts 0:9c052ff8dd6a 589 printf("prelen %lu ", val);
Wayne Roberts 0:9c052ff8dd6a 590 }
Wayne Roberts 0:9c052ff8dd6a 591
Wayne Roberts 0:9c052ff8dd6a 592 {
Wayne Roberts 0:9c052ff8dd6a 593 loraConfig0_t conf0;
Wayne Roberts 0:9c052ff8dd6a 594 conf0.octet = radio.readReg(REG_ADDR_LORA_CONFIG0, 1);
Wayne Roberts 0:9c052ff8dd6a 595 printf("sf%u, bw%u ", conf0.bits.modem_sf, conf0.bits.modem_bw);
Wayne Roberts 0:9c052ff8dd6a 596 }
Wayne Roberts 0:9c052ff8dd6a 597
Wayne Roberts 0:9c052ff8dd6a 598 printf("%.3fMHz\r\n", radio.getMHz());
Wayne Roberts 0:9c052ff8dd6a 599 }
Wayne Roberts 0:9c052ff8dd6a 600 #endif /* if 0 */
Wayne Roberts 0:9c052ff8dd6a 601
Wayne Roberts 0:9c052ff8dd6a 602 #endif /* ..SX126x_H */