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 Jul 10 10:52:39 2020 -0700
Revision:
20:75635d50262e
Parent:
18:78c5e644d37a
support mbed-6

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