wayne roberts / lorawan1v1

Dependencies:   sx12xx_hal

Dependents:   LoRaWAN-SanJose_Bootcamp LoRaWAN-grove-cayenne LoRaWAN-classC-demo LoRaWAN-grove-cayenne ... more

Committer:
Wayne Roberts
Date:
Mon Jun 11 14:09:16 2018 -0700
Revision:
9:fe8e08792ae9
Parent:
8:5a5ea7cc946f
sx126x: update xfer() calls

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 8:5a5ea7cc946f 1 #include "radio.h"
Wayne Roberts 8:5a5ea7cc946f 2 #ifdef SX126x_H
Wayne Roberts 8:5a5ea7cc946f 3 #include "board.h"
Wayne Roberts 8:5a5ea7cc946f 4 #include "SPIu.h"
Wayne Roberts 8:5a5ea7cc946f 5
Wayne Roberts 8:5a5ea7cc946f 6 LowPowerTimer Radio::lpt;
Wayne Roberts 8:5a5ea7cc946f 7 volatile us_timestamp_t dio1at;
Wayne Roberts 8:5a5ea7cc946f 8
Wayne Roberts 8:5a5ea7cc946f 9 #ifdef TARGET_FF_ARDUINO
Wayne Roberts 8:5a5ea7cc946f 10 SPIu spi(D11, D12, D13); // mosi, miso, sclk
Wayne Roberts 8:5a5ea7cc946f 11 //spi, nss, busy, dio1
Wayne Roberts 8:5a5ea7cc946f 12 SX126x Radio::radio(spi, D7, D3, D5);
Wayne Roberts 8:5a5ea7cc946f 13
Wayne Roberts 8:5a5ea7cc946f 14 DigitalOut antswPower(D8);
Wayne Roberts 8:5a5ea7cc946f 15 AnalogIn xtalSel(A3);
Wayne Roberts 8:5a5ea7cc946f 16
Wayne Roberts 8:5a5ea7cc946f 17 DigitalIn chipType(A2);
Wayne Roberts 8:5a5ea7cc946f 18 #define CHIP_TYPE_SX1262 0
Wayne Roberts 8:5a5ea7cc946f 19 #define CHIP_TYPE_SX1261 1
Wayne Roberts 8:5a5ea7cc946f 20
Wayne Roberts 8:5a5ea7cc946f 21 #define PINNAME_NRST A0
Wayne Roberts 8:5a5ea7cc946f 22 #endif /* TARGET_FF_ARDUINO */
Wayne Roberts 8:5a5ea7cc946f 23
Wayne Roberts 8:5a5ea7cc946f 24 const RadioEvents_t* RadioEvents;
Wayne Roberts 8:5a5ea7cc946f 25 PacketParams_t Radio::pp;
Wayne Roberts 8:5a5ea7cc946f 26 RadioModems_t Radio::_m_;
Wayne Roberts 8:5a5ea7cc946f 27
Wayne Roberts 8:5a5ea7cc946f 28 #ifdef TARGET_FF_MORPHO
Wayne Roberts 8:5a5ea7cc946f 29 DigitalOut pc3(PC_3); // debug RX indication, for nucleo boards
Wayne Roberts 8:5a5ea7cc946f 30 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 8:5a5ea7cc946f 31
Wayne Roberts 8:5a5ea7cc946f 32 void Radio::Rx(unsigned timeout)
Wayne Roberts 8:5a5ea7cc946f 33 {
Wayne Roberts 8:5a5ea7cc946f 34 antswPower = 1;
Wayne Roberts 8:5a5ea7cc946f 35
Wayne Roberts 8:5a5ea7cc946f 36 {
Wayne Roberts 8:5a5ea7cc946f 37 uint8_t buf[8];
Wayne Roberts 8:5a5ea7cc946f 38 IrqFlags_t irqEnable;
Wayne Roberts 8:5a5ea7cc946f 39 irqEnable.word = 0;
Wayne Roberts 8:5a5ea7cc946f 40 irqEnable.bits.RxDone = 1;
Wayne Roberts 8:5a5ea7cc946f 41 irqEnable.bits.Timeout = 1;
Wayne Roberts 8:5a5ea7cc946f 42
Wayne Roberts 8:5a5ea7cc946f 43 buf[0] = irqEnable.word >> 8; // enable bits
Wayne Roberts 8:5a5ea7cc946f 44 buf[1] = irqEnable.word; // enable bits
Wayne Roberts 8:5a5ea7cc946f 45 buf[2] = irqEnable.word >> 8; // dio1
Wayne Roberts 8:5a5ea7cc946f 46 buf[3] = irqEnable.word; // dio1
Wayne Roberts 8:5a5ea7cc946f 47 buf[4] = 0; // dio2
Wayne Roberts 8:5a5ea7cc946f 48 buf[5] = 0; // dio2
Wayne Roberts 8:5a5ea7cc946f 49 buf[6] = 0; // dio3
Wayne Roberts 8:5a5ea7cc946f 50 buf[7] = 0; // dio3
Wayne Roberts 9:fe8e08792ae9 51 radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 52 }
Wayne Roberts 8:5a5ea7cc946f 53
Wayne Roberts 8:5a5ea7cc946f 54 #ifdef TARGET_FF_MORPHO
Wayne Roberts 8:5a5ea7cc946f 55 pc3 = 1;
Wayne Roberts 8:5a5ea7cc946f 56 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 8:5a5ea7cc946f 57 if (timeout == 0)
Wayne Roberts 8:5a5ea7cc946f 58 radio.start_rx(RX_TIMEOUT_CONTINUOUS);
Wayne Roberts 8:5a5ea7cc946f 59 else
Wayne Roberts 8:5a5ea7cc946f 60 radio.start_rx(timeout * RC_TICKS_PER_US);
Wayne Roberts 8:5a5ea7cc946f 61 }
Wayne Roberts 8:5a5ea7cc946f 62
Wayne Roberts 8:5a5ea7cc946f 63 void Radio::Standby()
Wayne Roberts 8:5a5ea7cc946f 64 {
Wayne Roberts 8:5a5ea7cc946f 65 radio.setStandby(STBY_RC); // STBY_XOSC
Wayne Roberts 8:5a5ea7cc946f 66
Wayne Roberts 8:5a5ea7cc946f 67 antswPower = 0;
Wayne Roberts 8:5a5ea7cc946f 68 }
Wayne Roberts 8:5a5ea7cc946f 69
Wayne Roberts 8:5a5ea7cc946f 70 void Radio::Sleep()
Wayne Roberts 8:5a5ea7cc946f 71 {
Wayne Roberts 8:5a5ea7cc946f 72 radio.setSleep(true, false);
Wayne Roberts 8:5a5ea7cc946f 73
Wayne Roberts 8:5a5ea7cc946f 74 antswPower = 0;
Wayne Roberts 8:5a5ea7cc946f 75 }
Wayne Roberts 8:5a5ea7cc946f 76
Wayne Roberts 8:5a5ea7cc946f 77 void Radio::SetTxContinuousWave(unsigned hz, int8_t dbm, unsigned timeout_us)
Wayne Roberts 8:5a5ea7cc946f 78 {
Wayne Roberts 8:5a5ea7cc946f 79 SetChannel(hz);
Wayne Roberts 8:5a5ea7cc946f 80 radio.set_tx_dbm(chipType == CHIP_TYPE_SX1262, dbm);
Wayne Roberts 9:fe8e08792ae9 81 radio.xfer(OPCODE_SET_TX_CONTINUOUS, 0, 0, NULL);
Wayne Roberts 8:5a5ea7cc946f 82 }
Wayne Roberts 8:5a5ea7cc946f 83
Wayne Roberts 8:5a5ea7cc946f 84 uint32_t Radio::Random(void)
Wayne Roberts 8:5a5ea7cc946f 85 {
Wayne Roberts 8:5a5ea7cc946f 86 uint32_t ret;
Wayne Roberts 8:5a5ea7cc946f 87
Wayne Roberts 8:5a5ea7cc946f 88 radio.start_rx(RX_TIMEOUT_CONTINUOUS);
Wayne Roberts 8:5a5ea7cc946f 89
Wayne Roberts 8:5a5ea7cc946f 90 ret = radio.readReg(REG_ADDR_RANDOM, 4);
Wayne Roberts 8:5a5ea7cc946f 91
Wayne Roberts 8:5a5ea7cc946f 92 Standby();
Wayne Roberts 8:5a5ea7cc946f 93
Wayne Roberts 8:5a5ea7cc946f 94 return ret;
Wayne Roberts 8:5a5ea7cc946f 95 }
Wayne Roberts 8:5a5ea7cc946f 96
Wayne Roberts 8:5a5ea7cc946f 97 bool Radio::CheckRfFrequency(unsigned hz)
Wayne Roberts 8:5a5ea7cc946f 98 {
Wayne Roberts 8:5a5ea7cc946f 99 return true;
Wayne Roberts 8:5a5ea7cc946f 100 }
Wayne Roberts 8:5a5ea7cc946f 101
Wayne Roberts 8:5a5ea7cc946f 102 void Radio::SetChannel(unsigned hz)
Wayne Roberts 8:5a5ea7cc946f 103 {
Wayne Roberts 8:5a5ea7cc946f 104 radio.setMHz(hz / 1000000.0);
Wayne Roberts 8:5a5ea7cc946f 105 }
Wayne Roberts 8:5a5ea7cc946f 106
Wayne Roberts 8:5a5ea7cc946f 107 void Radio::SetRxConfig(
Wayne Roberts 8:5a5ea7cc946f 108 RadioModems_t modem,
Wayne Roberts 8:5a5ea7cc946f 109 uint32_t bandwidth,
Wayne Roberts 8:5a5ea7cc946f 110 uint32_t datarate,
Wayne Roberts 8:5a5ea7cc946f 111 uint8_t coderate,
Wayne Roberts 8:5a5ea7cc946f 112 uint32_t bandwidthAfc,
Wayne Roberts 8:5a5ea7cc946f 113 uint16_t preambleLen,
Wayne Roberts 8:5a5ea7cc946f 114 uint16_t symbTimeout,
Wayne Roberts 8:5a5ea7cc946f 115 bool fixLen,
Wayne Roberts 8:5a5ea7cc946f 116 uint8_t payloadLen,
Wayne Roberts 8:5a5ea7cc946f 117 bool crcOn,
Wayne Roberts 8:5a5ea7cc946f 118 bool iqInverted)
Wayne Roberts 8:5a5ea7cc946f 119 {
Wayne Roberts 8:5a5ea7cc946f 120 uint8_t buf[8];
Wayne Roberts 8:5a5ea7cc946f 121
Wayne Roberts 8:5a5ea7cc946f 122 if (modem == MODEM_FSK)
Wayne Roberts 8:5a5ea7cc946f 123 buf[0] = PACKET_TYPE_GFSK;
Wayne Roberts 8:5a5ea7cc946f 124 else
Wayne Roberts 8:5a5ea7cc946f 125 buf[0] = PACKET_TYPE_LORA;
Wayne Roberts 8:5a5ea7cc946f 126
Wayne Roberts 9:fe8e08792ae9 127 radio.xfer(OPCODE_SET_PACKET_TYPE, 1, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 128
Wayne Roberts 8:5a5ea7cc946f 129 buf[0] = 0; // TX base address
Wayne Roberts 8:5a5ea7cc946f 130 buf[1] = 0; // RX base address
Wayne Roberts 9:fe8e08792ae9 131 radio.xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 132
Wayne Roberts 8:5a5ea7cc946f 133 if (modem == MODEM_FSK) {
Wayne Roberts 8:5a5ea7cc946f 134 FSKConfig(bandwidth, datarate, 0, preambleLen, fixLen, crcOn);
Wayne Roberts 8:5a5ea7cc946f 135
Wayne Roberts 8:5a5ea7cc946f 136 pp.gfsk.PayloadLength = payloadLen;
Wayne Roberts 8:5a5ea7cc946f 137
Wayne Roberts 8:5a5ea7cc946f 138 memcpy(buf, pp.buf, 8);
Wayne Roberts 9:fe8e08792ae9 139 radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 140 } else if (modem == MODEM_LORA) {
Wayne Roberts 8:5a5ea7cc946f 141 LoRaConfig(bandwidth, datarate, coderate, preambleLen, fixLen, crcOn, iqInverted);
Wayne Roberts 8:5a5ea7cc946f 142
Wayne Roberts 8:5a5ea7cc946f 143 pp.lora.PayloadLength = payloadLen;
Wayne Roberts 8:5a5ea7cc946f 144
Wayne Roberts 8:5a5ea7cc946f 145 memcpy(buf, pp.buf, 6);
Wayne Roberts 9:fe8e08792ae9 146 radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 147
Wayne Roberts 8:5a5ea7cc946f 148 buf[0] = symbTimeout;
Wayne Roberts 9:fe8e08792ae9 149 radio.xfer(OPCODE_SET_LORA_SYMBOL_TIMEOUT, 1, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 150 }
Wayne Roberts 8:5a5ea7cc946f 151
Wayne Roberts 8:5a5ea7cc946f 152 {
Wayne Roberts 8:5a5ea7cc946f 153 IrqFlags_t irqEnable;
Wayne Roberts 8:5a5ea7cc946f 154 irqEnable.word = 0;
Wayne Roberts 8:5a5ea7cc946f 155 irqEnable.bits.RxDone = 1;
Wayne Roberts 8:5a5ea7cc946f 156 irqEnable.bits.Timeout = 1;
Wayne Roberts 8:5a5ea7cc946f 157
Wayne Roberts 8:5a5ea7cc946f 158 buf[0] = irqEnable.word >> 8; // enable bits
Wayne Roberts 8:5a5ea7cc946f 159 buf[1] = irqEnable.word; // enable bits
Wayne Roberts 8:5a5ea7cc946f 160 buf[2] = irqEnable.word >> 8; // dio1
Wayne Roberts 8:5a5ea7cc946f 161 buf[3] = irqEnable.word; // dio1
Wayne Roberts 8:5a5ea7cc946f 162 buf[4] = 0; // dio2
Wayne Roberts 8:5a5ea7cc946f 163 buf[5] = 0; // dio2
Wayne Roberts 8:5a5ea7cc946f 164 buf[6] = 0; // dio3
Wayne Roberts 8:5a5ea7cc946f 165 buf[7] = 0; // dio3
Wayne Roberts 9:fe8e08792ae9 166 radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 167 }
Wayne Roberts 8:5a5ea7cc946f 168
Wayne Roberts 8:5a5ea7cc946f 169 } // ..SetRxConfig()
Wayne Roberts 8:5a5ea7cc946f 170
Wayne Roberts 8:5a5ea7cc946f 171 void Radio::FSKConfig(
Wayne Roberts 8:5a5ea7cc946f 172 uint32_t bandwidth,
Wayne Roberts 8:5a5ea7cc946f 173 uint32_t datarate,
Wayne Roberts 8:5a5ea7cc946f 174 uint32_t fdev,
Wayne Roberts 8:5a5ea7cc946f 175 uint32_t preambleLen,
Wayne Roberts 8:5a5ea7cc946f 176 bool fixLen,
Wayne Roberts 8:5a5ea7cc946f 177 bool crcOn)
Wayne Roberts 8:5a5ea7cc946f 178 {
Wayne Roberts 8:5a5ea7cc946f 179 ModulationParams_t mp;
Wayne Roberts 8:5a5ea7cc946f 180 uint32_t u32;
Wayne Roberts 8:5a5ea7cc946f 181
Wayne Roberts 9:fe8e08792ae9 182 u32 = 32 * (XTAL_FREQ_HZ / datarate);
Wayne Roberts 9:fe8e08792ae9 183 mp.gfsk.bitrateHi = u32 >> 16; // param1
Wayne Roberts 9:fe8e08792ae9 184 mp.gfsk.bitrateMid = u32 >> 8; // param2
Wayne Roberts 9:fe8e08792ae9 185 mp.gfsk.bitrateLo = u32; // param3
Wayne Roberts 8:5a5ea7cc946f 186 mp.gfsk.PulseShape = GFSK_SHAPE_BT1_0; // param4
Wayne Roberts 8:5a5ea7cc946f 187 // param5:
Wayne Roberts 8:5a5ea7cc946f 188 if (bandwidth < 5800)
Wayne Roberts 9:fe8e08792ae9 189 mp.gfsk.bandwidth = GFSK_RX_BW_4800;
Wayne Roberts 8:5a5ea7cc946f 190 else if (bandwidth < 7300)
Wayne Roberts 9:fe8e08792ae9 191 mp.gfsk.bandwidth = GFSK_RX_BW_5800;
Wayne Roberts 8:5a5ea7cc946f 192 else if (bandwidth < 9700)
Wayne Roberts 9:fe8e08792ae9 193 mp.gfsk.bandwidth = GFSK_RX_BW_7300;
Wayne Roberts 8:5a5ea7cc946f 194 else if (bandwidth < 11700)
Wayne Roberts 9:fe8e08792ae9 195 mp.gfsk.bandwidth = GFSK_RX_BW_9700;
Wayne Roberts 8:5a5ea7cc946f 196 else if (bandwidth < 14600)
Wayne Roberts 9:fe8e08792ae9 197 mp.gfsk.bandwidth = GFSK_RX_BW_11700;
Wayne Roberts 8:5a5ea7cc946f 198 else if (bandwidth < 19500)
Wayne Roberts 9:fe8e08792ae9 199 mp.gfsk.bandwidth = GFSK_RX_BW_14600;
Wayne Roberts 8:5a5ea7cc946f 200 else if (bandwidth < 23400)
Wayne Roberts 9:fe8e08792ae9 201 mp.gfsk.bandwidth = GFSK_RX_BW_19500;
Wayne Roberts 8:5a5ea7cc946f 202 else if (bandwidth < 29300)
Wayne Roberts 9:fe8e08792ae9 203 mp.gfsk.bandwidth = GFSK_RX_BW_23400;
Wayne Roberts 8:5a5ea7cc946f 204 else if (bandwidth < 39000)
Wayne Roberts 9:fe8e08792ae9 205 mp.gfsk.bandwidth = GFSK_RX_BW_29300;
Wayne Roberts 8:5a5ea7cc946f 206 else if (bandwidth < 46900)
Wayne Roberts 9:fe8e08792ae9 207 mp.gfsk.bandwidth = GFSK_RX_BW_39000;
Wayne Roberts 8:5a5ea7cc946f 208 else if (bandwidth < 58600)
Wayne Roberts 9:fe8e08792ae9 209 mp.gfsk.bandwidth = GFSK_RX_BW_46900;
Wayne Roberts 8:5a5ea7cc946f 210 else if (bandwidth < 78200)
Wayne Roberts 9:fe8e08792ae9 211 mp.gfsk.bandwidth = GFSK_RX_BW_58600;
Wayne Roberts 8:5a5ea7cc946f 212 else if (bandwidth < 93800)
Wayne Roberts 9:fe8e08792ae9 213 mp.gfsk.bandwidth = GFSK_RX_BW_78200;
Wayne Roberts 8:5a5ea7cc946f 214 else if (bandwidth < 117300)
Wayne Roberts 9:fe8e08792ae9 215 mp.gfsk.bandwidth = GFSK_RX_BW_93800;
Wayne Roberts 8:5a5ea7cc946f 216 else if (bandwidth < 156200)
Wayne Roberts 9:fe8e08792ae9 217 mp.gfsk.bandwidth = GFSK_RX_BW_117300;
Wayne Roberts 8:5a5ea7cc946f 218 else if (bandwidth < 187200)
Wayne Roberts 9:fe8e08792ae9 219 mp.gfsk.bandwidth = GFSK_RX_BW_156200;
Wayne Roberts 8:5a5ea7cc946f 220 else if (bandwidth < 234300)
Wayne Roberts 9:fe8e08792ae9 221 mp.gfsk.bandwidth = GFSK_RX_BW_187200;
Wayne Roberts 8:5a5ea7cc946f 222 else if (bandwidth < 312000)
Wayne Roberts 9:fe8e08792ae9 223 mp.gfsk.bandwidth = GFSK_RX_BW_234300;
Wayne Roberts 8:5a5ea7cc946f 224 else if (bandwidth < 373600)
Wayne Roberts 9:fe8e08792ae9 225 mp.gfsk.bandwidth = GFSK_RX_BW_312000;
Wayne Roberts 8:5a5ea7cc946f 226 else if (bandwidth < 467000)
Wayne Roberts 9:fe8e08792ae9 227 mp.gfsk.bandwidth = GFSK_RX_BW_373600;
Wayne Roberts 8:5a5ea7cc946f 228 else
Wayne Roberts 9:fe8e08792ae9 229 mp.gfsk.bandwidth = GFSK_RX_BW_467000;
Wayne Roberts 8:5a5ea7cc946f 230
Wayne Roberts 8:5a5ea7cc946f 231 if (fdev > 0) {
Wayne Roberts 8:5a5ea7cc946f 232 u32 = fdev / FREQ_STEP;
Wayne Roberts 8:5a5ea7cc946f 233 mp.gfsk.fdevHi = u32 >> 16; // param6
Wayne Roberts 8:5a5ea7cc946f 234 mp.gfsk.fdevMid = u32 >> 8; // param7
Wayne Roberts 8:5a5ea7cc946f 235 mp.gfsk.fdevLo = u32; // param8
Wayne Roberts 8:5a5ea7cc946f 236 }
Wayne Roberts 8:5a5ea7cc946f 237
Wayne Roberts 9:fe8e08792ae9 238 radio.xfer(OPCODE_SET_MODULATION_PARAMS, 8, 0, mp.buf);
Wayne Roberts 8:5a5ea7cc946f 239
Wayne Roberts 8:5a5ea7cc946f 240
Wayne Roberts 8:5a5ea7cc946f 241 pp.gfsk.PreambleLengthHi = preambleLen >> 8;
Wayne Roberts 8:5a5ea7cc946f 242 pp.gfsk.PreambleLengthLo = preambleLen;
Wayne Roberts 8:5a5ea7cc946f 243 pp.gfsk.PreambleDetectorLength = GFSK_PREAMBLE_DETECTOR_LENGTH_16BITS;
Wayne Roberts 8:5a5ea7cc946f 244 pp.gfsk.SyncWordLength = 24; // 0xC194C1
Wayne Roberts 8:5a5ea7cc946f 245 pp.gfsk.AddrComp = 0;
Wayne Roberts 8:5a5ea7cc946f 246 pp.gfsk.PacketType = fixLen;
Wayne Roberts 8:5a5ea7cc946f 247 if (crcOn)
Wayne Roberts 8:5a5ea7cc946f 248 pp.gfsk.CRCType = GFSK_CRC_2_BYTE;
Wayne Roberts 8:5a5ea7cc946f 249 else
Wayne Roberts 8:5a5ea7cc946f 250 pp.gfsk.CRCType = GFSK_CRC_OFF;
Wayne Roberts 8:5a5ea7cc946f 251 }
Wayne Roberts 8:5a5ea7cc946f 252
Wayne Roberts 8:5a5ea7cc946f 253 void Radio::LoRaConfig(
Wayne Roberts 8:5a5ea7cc946f 254 uint32_t bandwidth,
Wayne Roberts 8:5a5ea7cc946f 255 uint8_t datarate,
Wayne Roberts 8:5a5ea7cc946f 256 uint8_t coderate,
Wayne Roberts 8:5a5ea7cc946f 257 uint16_t preambleLen,
Wayne Roberts 8:5a5ea7cc946f 258 bool fixLen,
Wayne Roberts 8:5a5ea7cc946f 259 bool crcOn,
Wayne Roberts 8:5a5ea7cc946f 260 bool iqInverted)
Wayne Roberts 8:5a5ea7cc946f 261 {
Wayne Roberts 8:5a5ea7cc946f 262 ModulationParams_t mp;
Wayne Roberts 8:5a5ea7cc946f 263 float sp, khz;
Wayne Roberts 8:5a5ea7cc946f 264
Wayne Roberts 8:5a5ea7cc946f 265 mp.lora.spreadingFactor = datarate; // param1
Wayne Roberts 8:5a5ea7cc946f 266 mp.lora.bandwidth = bandwidth + 4; // param2
Wayne Roberts 8:5a5ea7cc946f 267 mp.lora.codingRate = coderate; // param3
Wayne Roberts 8:5a5ea7cc946f 268
Wayne Roberts 8:5a5ea7cc946f 269 switch (mp.lora.bandwidth) {
Wayne Roberts 8:5a5ea7cc946f 270 case LORA_BW_7: khz = 7.81; break;
Wayne Roberts 8:5a5ea7cc946f 271 case LORA_BW_10: khz = 10.42; break;
Wayne Roberts 8:5a5ea7cc946f 272 case LORA_BW_15: khz = 15.625; break;
Wayne Roberts 8:5a5ea7cc946f 273 case LORA_BW_20: khz = 20.83; break;
Wayne Roberts 8:5a5ea7cc946f 274 case LORA_BW_31: khz = 31.25; break;
Wayne Roberts 8:5a5ea7cc946f 275 case LORA_BW_41: khz = 41.67; break;
Wayne Roberts 8:5a5ea7cc946f 276 case LORA_BW_62: khz = 62.5; break;
Wayne Roberts 8:5a5ea7cc946f 277 case LORA_BW_125: khz = 125; break;
Wayne Roberts 8:5a5ea7cc946f 278 case LORA_BW_250: khz = 250; break;
Wayne Roberts 8:5a5ea7cc946f 279 case LORA_BW_500: khz = 500; break;
Wayne Roberts 8:5a5ea7cc946f 280 default: khz = 0; break;
Wayne Roberts 8:5a5ea7cc946f 281 }
Wayne Roberts 8:5a5ea7cc946f 282 sp = (1 << mp.lora.spreadingFactor) / khz;
Wayne Roberts 8:5a5ea7cc946f 283 /* TCXO dependent */
Wayne Roberts 8:5a5ea7cc946f 284 if (sp > 16)
Wayne Roberts 8:5a5ea7cc946f 285 mp.lora.LowDatarateOptimize = 1; // param4
Wayne Roberts 8:5a5ea7cc946f 286 else
Wayne Roberts 8:5a5ea7cc946f 287 mp.lora.LowDatarateOptimize = 0; // param4
Wayne Roberts 8:5a5ea7cc946f 288
Wayne Roberts 9:fe8e08792ae9 289 radio.xfer(OPCODE_SET_MODULATION_PARAMS, 4, 0, mp.buf);
Wayne Roberts 8:5a5ea7cc946f 290
Wayne Roberts 8:5a5ea7cc946f 291 pp.lora.PreambleLengthHi = preambleLen >> 8;
Wayne Roberts 8:5a5ea7cc946f 292 pp.lora.PreambleLengthLo = preambleLen;
Wayne Roberts 8:5a5ea7cc946f 293 pp.lora.HeaderType = fixLen;
Wayne Roberts 8:5a5ea7cc946f 294 pp.lora.CRCType = crcOn;
Wayne Roberts 8:5a5ea7cc946f 295 pp.lora.InvertIQ = iqInverted;
Wayne Roberts 8:5a5ea7cc946f 296 }
Wayne Roberts 8:5a5ea7cc946f 297
Wayne Roberts 8:5a5ea7cc946f 298 void Radio::SetTxConfig(
Wayne Roberts 8:5a5ea7cc946f 299 RadioModems_t modem,
Wayne Roberts 8:5a5ea7cc946f 300 int8_t dbm,
Wayne Roberts 8:5a5ea7cc946f 301 uint32_t fdev,
Wayne Roberts 8:5a5ea7cc946f 302 uint32_t bandwidth,
Wayne Roberts 8:5a5ea7cc946f 303 uint32_t datarate,
Wayne Roberts 8:5a5ea7cc946f 304 uint8_t coderate,
Wayne Roberts 8:5a5ea7cc946f 305 uint16_t preambleLen,
Wayne Roberts 8:5a5ea7cc946f 306 bool fixLen,
Wayne Roberts 8:5a5ea7cc946f 307 bool crcOn,
Wayne Roberts 8:5a5ea7cc946f 308 bool iqInverted)
Wayne Roberts 8:5a5ea7cc946f 309 {
Wayne Roberts 8:5a5ea7cc946f 310 uint8_t buf[8];
Wayne Roberts 8:5a5ea7cc946f 311
Wayne Roberts 8:5a5ea7cc946f 312 radio.set_tx_dbm(chipType == CHIP_TYPE_SX1262, dbm);
Wayne Roberts 8:5a5ea7cc946f 313
Wayne Roberts 8:5a5ea7cc946f 314 if (modem == MODEM_FSK)
Wayne Roberts 8:5a5ea7cc946f 315 buf[0] = PACKET_TYPE_GFSK;
Wayne Roberts 8:5a5ea7cc946f 316 else
Wayne Roberts 8:5a5ea7cc946f 317 buf[0] = PACKET_TYPE_LORA;
Wayne Roberts 8:5a5ea7cc946f 318
Wayne Roberts 9:fe8e08792ae9 319 radio.xfer(OPCODE_SET_PACKET_TYPE, 1, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 320
Wayne Roberts 8:5a5ea7cc946f 321
Wayne Roberts 8:5a5ea7cc946f 322 buf[0] = 0; // TX base address
Wayne Roberts 8:5a5ea7cc946f 323 buf[1] = 0; // RX base address
Wayne Roberts 9:fe8e08792ae9 324 radio.xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 325
Wayne Roberts 8:5a5ea7cc946f 326 if (modem == MODEM_FSK) {
Wayne Roberts 8:5a5ea7cc946f 327 FSKConfig(bandwidth, datarate, fdev, preambleLen, fixLen, crcOn);
Wayne Roberts 8:5a5ea7cc946f 328 } else if (modem == MODEM_LORA) {
Wayne Roberts 8:5a5ea7cc946f 329 LoRaConfig(bandwidth, datarate, coderate, preambleLen, fixLen, crcOn, iqInverted);
Wayne Roberts 8:5a5ea7cc946f 330 }
Wayne Roberts 8:5a5ea7cc946f 331
Wayne Roberts 8:5a5ea7cc946f 332 {
Wayne Roberts 8:5a5ea7cc946f 333 IrqFlags_t irqEnable;
Wayne Roberts 8:5a5ea7cc946f 334 irqEnable.word = 0;
Wayne Roberts 8:5a5ea7cc946f 335 irqEnable.bits.TxDone = 1;
Wayne Roberts 8:5a5ea7cc946f 336 irqEnable.bits.Timeout = 1;
Wayne Roberts 8:5a5ea7cc946f 337
Wayne Roberts 8:5a5ea7cc946f 338 buf[0] = irqEnable.word >> 8; // enable bits
Wayne Roberts 8:5a5ea7cc946f 339 buf[1] = irqEnable.word; // enable bits
Wayne Roberts 8:5a5ea7cc946f 340 buf[2] = irqEnable.word >> 8; // dio1
Wayne Roberts 8:5a5ea7cc946f 341 buf[3] = irqEnable.word; // dio1
Wayne Roberts 8:5a5ea7cc946f 342 buf[4] = 0; // dio2
Wayne Roberts 8:5a5ea7cc946f 343 buf[5] = 0; // dio2
Wayne Roberts 8:5a5ea7cc946f 344 buf[6] = 0; // dio3
Wayne Roberts 8:5a5ea7cc946f 345 buf[7] = 0; // dio3
Wayne Roberts 9:fe8e08792ae9 346 radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 347 }
Wayne Roberts 8:5a5ea7cc946f 348
Wayne Roberts 8:5a5ea7cc946f 349 _m_ = modem;
Wayne Roberts 8:5a5ea7cc946f 350 /* SetPacketParams written at Send() where payloadLength provided */
Wayne Roberts 8:5a5ea7cc946f 351
Wayne Roberts 8:5a5ea7cc946f 352 antswPower = 1;
Wayne Roberts 8:5a5ea7cc946f 353 } // ..SetTxConfig()
Wayne Roberts 8:5a5ea7cc946f 354
Wayne Roberts 8:5a5ea7cc946f 355 int Radio::Send(uint8_t size, timestamp_t maxListenTime, timestamp_t channelFreeTime, int rssiThresh)
Wayne Roberts 8:5a5ea7cc946f 356 {
Wayne Roberts 8:5a5ea7cc946f 357 uint8_t buf[8];
Wayne Roberts 8:5a5ea7cc946f 358
Wayne Roberts 8:5a5ea7cc946f 359 if (_m_ == MODEM_FSK) {
Wayne Roberts 8:5a5ea7cc946f 360 pp.gfsk.PayloadLength = size;
Wayne Roberts 8:5a5ea7cc946f 361
Wayne Roberts 8:5a5ea7cc946f 362 memcpy(buf, pp.buf, 8);
Wayne Roberts 9:fe8e08792ae9 363 radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 364 } else if (_m_ == MODEM_LORA) {
Wayne Roberts 8:5a5ea7cc946f 365 pp.lora.PayloadLength = size;
Wayne Roberts 8:5a5ea7cc946f 366
Wayne Roberts 8:5a5ea7cc946f 367 memcpy(buf, pp.buf, 6);
Wayne Roberts 9:fe8e08792ae9 368 radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 369 }
Wayne Roberts 8:5a5ea7cc946f 370
Wayne Roberts 8:5a5ea7cc946f 371 if (maxListenTime > 0) {
Wayne Roberts 8:5a5ea7cc946f 372 int rssi;
Wayne Roberts 8:5a5ea7cc946f 373 us_timestamp_t startAt, chFreeAt, now;
Wayne Roberts 8:5a5ea7cc946f 374 radio.start_rx(RX_TIMEOUT_CONTINUOUS);
Wayne Roberts 8:5a5ea7cc946f 375 startAt = lpt.read_us();
Wayne Roberts 8:5a5ea7cc946f 376 Lstart:
Wayne Roberts 8:5a5ea7cc946f 377 do {
Wayne Roberts 8:5a5ea7cc946f 378 now = lpt.read_us();
Wayne Roberts 8:5a5ea7cc946f 379 if ((now - startAt) > maxListenTime) {
Wayne Roberts 8:5a5ea7cc946f 380 return -1;
Wayne Roberts 8:5a5ea7cc946f 381 }
Wayne Roberts 9:fe8e08792ae9 382 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 8:5a5ea7cc946f 383 rssi = buf[1] / -2;
Wayne Roberts 8:5a5ea7cc946f 384 } while (rssi > rssiThresh);
Wayne Roberts 8:5a5ea7cc946f 385 chFreeAt = lpt.read_us();
Wayne Roberts 8:5a5ea7cc946f 386 do {
Wayne Roberts 8:5a5ea7cc946f 387 now = lpt.read_us();
Wayne Roberts 9:fe8e08792ae9 388 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 8:5a5ea7cc946f 389 rssi = buf[1] / -2;
Wayne Roberts 8:5a5ea7cc946f 390 if (rssi > rssiThresh) {
Wayne Roberts 8:5a5ea7cc946f 391 goto Lstart;
Wayne Roberts 8:5a5ea7cc946f 392 }
Wayne Roberts 8:5a5ea7cc946f 393 } while ((now - chFreeAt) < channelFreeTime);
Wayne Roberts 8:5a5ea7cc946f 394 }
Wayne Roberts 8:5a5ea7cc946f 395
Wayne Roberts 8:5a5ea7cc946f 396 radio.start_tx(size);
Wayne Roberts 8:5a5ea7cc946f 397
Wayne Roberts 8:5a5ea7cc946f 398 return 0;
Wayne Roberts 8:5a5ea7cc946f 399 } // ..Send()
Wayne Roberts 8:5a5ea7cc946f 400
Wayne Roberts 8:5a5ea7cc946f 401 void Radio::SetRxMaxPayloadLength(RadioModems_t modem, uint8_t max)
Wayne Roberts 8:5a5ea7cc946f 402 {
Wayne Roberts 8:5a5ea7cc946f 403 uint8_t buf[8];
Wayne Roberts 8:5a5ea7cc946f 404
Wayne Roberts 8:5a5ea7cc946f 405 if (modem == MODEM_FSK) {
Wayne Roberts 8:5a5ea7cc946f 406 pp.gfsk.PayloadLength = max;
Wayne Roberts 8:5a5ea7cc946f 407 memcpy(buf, pp.buf, 8);
Wayne Roberts 9:fe8e08792ae9 408 radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 409 } else if (modem == MODEM_LORA) {
Wayne Roberts 8:5a5ea7cc946f 410 pp.lora.PayloadLength = max;
Wayne Roberts 8:5a5ea7cc946f 411 memcpy(buf, pp.buf, 6);
Wayne Roberts 9:fe8e08792ae9 412 radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, buf);
Wayne Roberts 8:5a5ea7cc946f 413 }
Wayne Roberts 8:5a5ea7cc946f 414 }
Wayne Roberts 8:5a5ea7cc946f 415
Wayne Roberts 8:5a5ea7cc946f 416 void Radio::dio1_top_half()
Wayne Roberts 8:5a5ea7cc946f 417 {
Wayne Roberts 8:5a5ea7cc946f 418 dio1at = lpt.read_us();
Wayne Roberts 8:5a5ea7cc946f 419
Wayne Roberts 8:5a5ea7cc946f 420 if (radio.chipMode == CHIPMODE_TX) {
Wayne Roberts 8:5a5ea7cc946f 421 /* TxDone handling requires low latency */
Wayne Roberts 8:5a5ea7cc946f 422 if (RadioEvents->TxDone) {
Wayne Roberts 8:5a5ea7cc946f 423 RadioEvents->TxDone(dio1at);
Wayne Roberts 8:5a5ea7cc946f 424 }
Wayne Roberts 8:5a5ea7cc946f 425 }
Wayne Roberts 8:5a5ea7cc946f 426 #ifdef TARGET_FF_MORPHO
Wayne Roberts 8:5a5ea7cc946f 427 else
Wayne Roberts 8:5a5ea7cc946f 428 pc3 = 0;
Wayne Roberts 8:5a5ea7cc946f 429 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 8:5a5ea7cc946f 430 }
Wayne Roberts 8:5a5ea7cc946f 431
Wayne Roberts 8:5a5ea7cc946f 432 void Radio::timeout_callback(bool tx)
Wayne Roberts 8:5a5ea7cc946f 433 {
Wayne Roberts 8:5a5ea7cc946f 434 if (!tx) {
Wayne Roberts 8:5a5ea7cc946f 435 if (RadioEvents->RxTimeout)
Wayne Roberts 8:5a5ea7cc946f 436 RadioEvents->RxTimeout();
Wayne Roberts 8:5a5ea7cc946f 437 #ifdef TARGET_FF_MORPHO
Wayne Roberts 8:5a5ea7cc946f 438 pc3 = 0;
Wayne Roberts 8:5a5ea7cc946f 439 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 8:5a5ea7cc946f 440 } // else TODO tx timeout
Wayne Roberts 8:5a5ea7cc946f 441 }
Wayne Roberts 8:5a5ea7cc946f 442
Wayne Roberts 8:5a5ea7cc946f 443 void Radio::rx_done(uint8_t size, float rssi, float snr)
Wayne Roberts 8:5a5ea7cc946f 444 {
Wayne Roberts 8:5a5ea7cc946f 445 RadioEvents->RxDone(radio.rx_buf, size, rssi, snr, dio1at);
Wayne Roberts 8:5a5ea7cc946f 446 }
Wayne Roberts 8:5a5ea7cc946f 447
Wayne Roberts 8:5a5ea7cc946f 448 void Radio::Init(const RadioEvents_t* e)
Wayne Roberts 8:5a5ea7cc946f 449 {
Wayne Roberts 8:5a5ea7cc946f 450 radio.txDone = NULL;
Wayne Roberts 8:5a5ea7cc946f 451 radio.rxDone = rx_done;
Wayne Roberts 8:5a5ea7cc946f 452 radio.timeout = timeout_callback;
Wayne Roberts 8:5a5ea7cc946f 453 radio.dio1_topHalf = dio1_top_half;
Wayne Roberts 8:5a5ea7cc946f 454
Wayne Roberts 8:5a5ea7cc946f 455 RadioEvents = e;
Wayne Roberts 8:5a5ea7cc946f 456 lpt.start();
Wayne Roberts 8:5a5ea7cc946f 457
Wayne Roberts 8:5a5ea7cc946f 458 radio.SetDIO2AsRfSwitchCtrl(1);
Wayne Roberts 8:5a5ea7cc946f 459 }
Wayne Roberts 8:5a5ea7cc946f 460
Wayne Roberts 8:5a5ea7cc946f 461 void Radio::UserContext()
Wayne Roberts 8:5a5ea7cc946f 462 {
Wayne Roberts 8:5a5ea7cc946f 463 radio.service();
Wayne Roberts 8:5a5ea7cc946f 464 }
Wayne Roberts 8:5a5ea7cc946f 465
Wayne Roberts 8:5a5ea7cc946f 466 void Radio::SetPublicNetwork(bool en)
Wayne Roberts 8:5a5ea7cc946f 467 {
Wayne Roberts 8:5a5ea7cc946f 468 uint16_t ppg;
Wayne Roberts 8:5a5ea7cc946f 469
Wayne Roberts 8:5a5ea7cc946f 470 if (en)
Wayne Roberts 8:5a5ea7cc946f 471 ppg = 0x3444;
Wayne Roberts 8:5a5ea7cc946f 472 else
Wayne Roberts 8:5a5ea7cc946f 473 ppg = 0x1424;
Wayne Roberts 8:5a5ea7cc946f 474
Wayne Roberts 8:5a5ea7cc946f 475 radio.writeReg(REG_ADDR_LORA_SYNC, ppg, 2);
Wayne Roberts 8:5a5ea7cc946f 476 }
Wayne Roberts 8:5a5ea7cc946f 477
Wayne Roberts 8:5a5ea7cc946f 478 void Radio::PrintStatus()
Wayne Roberts 8:5a5ea7cc946f 479 {
Wayne Roberts 8:5a5ea7cc946f 480 uint8_t buf[4];
Wayne Roberts 8:5a5ea7cc946f 481 status_t status;
Wayne Roberts 8:5a5ea7cc946f 482 IrqFlags_t irqFlags;
Wayne Roberts 9:fe8e08792ae9 483 radio.xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf);
Wayne Roberts 8:5a5ea7cc946f 484 irqFlags.word = buf[1] << 8;
Wayne Roberts 8:5a5ea7cc946f 485 irqFlags.word |= buf[2];
Wayne Roberts 8:5a5ea7cc946f 486
Wayne Roberts 8:5a5ea7cc946f 487 printf("dio1:%u irqFlags:%04x\r\n", radio.getDIO1(), irqFlags.word);
Wayne Roberts 9:fe8e08792ae9 488 radio.xfer(OPCODE_GET_STATUS, 0, 1, &status.octet);
Wayne Roberts 8:5a5ea7cc946f 489 radio.PrintChipStatus(status);
Wayne Roberts 8:5a5ea7cc946f 490 }
Wayne Roberts 8:5a5ea7cc946f 491
Wayne Roberts 8:5a5ea7cc946f 492 #endif /* ..SX126x_H */