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:
Fri May 31 10:21:30 2019 -0700
Revision:
13:a354f82d12d9
Parent:
11:5111788c4298
Child:
15:e1c04ec39aa4
symbol timeout to 16bits.  Add spi clk freq initialization option.

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