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 Jun 12 11:27:45 2020 -0700
Revision:
18:78c5e644d37a
Parent:
17:5f34cbe2ac53
Child:
20:75635d50262e
type1SJ add

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