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:
Mon Jun 01 15:59:56 2020 -0700
Revision:
17:5f34cbe2ac53
Parent:
15:e1c04ec39aa4
Child:
18:78c5e644d37a
support platforms without LowPowerTimer, add LR1110

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