cervin sx1265 operating with transceiver firmware

Dependents:   lr1110_wifi_geolocation_device lr1110_wifi_geolocation_gateway

To use this driver, your LR1110 must be programmed as transceiver (not modem, which is LoRaWAN only).
Visit https://github.com/Lora-net/lr1110_updater_tool to update your LR1110, or change it from modem to transceiver if necessary.

Committer:
Wayne Roberts
Date:
Fri Feb 05 16:33:27 2021 -0800
Revision:
1:29294cae9f9a
Parent:
0:987d9022c152
remove busy check from service

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:987d9022c152 1 #include "sx12xx.h"
Wayne Roberts 0:987d9022c152 2
Wayne Roberts 0:987d9022c152 3 Callback<void()> SX1265::dio9_topHalf; // low latency ISR context
Wayne Roberts 0:987d9022c152 4
Wayne Roberts 0:987d9022c152 5 void SX1265::dio9isr()
Wayne Roberts 0:987d9022c152 6 {
Wayne Roberts 0:987d9022c152 7 if (dio9_topHalf)
Wayne Roberts 0:987d9022c152 8 dio9_topHalf.call();
Wayne Roberts 0:987d9022c152 9 }
Wayne Roberts 0:987d9022c152 10
Wayne Roberts 0:987d9022c152 11 SX1265::SX1265(SPI& _spi, PinName _nss, PinName _busy, PinName _dio9, PinName _nrst, uint32_t di, unsigned tto, uint8_t tv)
Wayne Roberts 0:987d9022c152 12 : spi(_spi), nss(_nss), busy(_busy), dio9(_dio9), nrst(_nrst), default_irqs(di), tcxoStartDelay(tto), tcxoVolts(tv)
Wayne Roberts 0:987d9022c152 13 {
Wayne Roberts 0:987d9022c152 14 nss = 1;
Wayne Roberts 0:987d9022c152 15 dio9.mode(PullDown); // dio9 floats if no interrupts enabled
Wayne Roberts 0:987d9022c152 16
Wayne Roberts 0:987d9022c152 17 t.start();
Wayne Roberts 0:987d9022c152 18
Wayne Roberts 0:987d9022c152 19 if (busy) {
Wayne Roberts 0:987d9022c152 20 hw_reset();
Wayne Roberts 0:987d9022c152 21 }
Wayne Roberts 0:987d9022c152 22
Wayne Roberts 0:987d9022c152 23 dio9.rise(dio9isr);
Wayne Roberts 0:987d9022c152 24 txTimeout = 0; // default tx-timeout off
Wayne Roberts 0:987d9022c152 25 }
Wayne Roberts 0:987d9022c152 26
Wayne Roberts 0:987d9022c152 27
Wayne Roberts 0:987d9022c152 28 void SX1265::hw_reset(void)
Wayne Roberts 0:987d9022c152 29 {
Wayne Roberts 0:987d9022c152 30 nrst.output();
Wayne Roberts 0:987d9022c152 31 nrst.write(0);
Wayne Roberts 0:987d9022c152 32 ThisThread::sleep_for(2);
Wayne Roberts 0:987d9022c152 33 nrst.write(1);
Wayne Roberts 0:987d9022c152 34 nrst.input();
Wayne Roberts 0:987d9022c152 35 /* measured 211ms to startup (busy-hi during chip startup) */
Wayne Roberts 0:987d9022c152 36 ThisThread::sleep_for(200);
Wayne Roberts 0:987d9022c152 37 while (busy)
Wayne Roberts 0:987d9022c152 38 ThisThread::sleep_for(2);
Wayne Roberts 0:987d9022c152 39
Wayne Roberts 0:987d9022c152 40 enable_default_irqs_();
Wayne Roberts 0:987d9022c152 41 }
Wayne Roberts 0:987d9022c152 42
Wayne Roberts 0:987d9022c152 43 const char *SX1265::cmdStatus_toString(uint8_t s)
Wayne Roberts 0:987d9022c152 44 {
Wayne Roberts 0:987d9022c152 45 switch (s) {
Wayne Roberts 0:987d9022c152 46 case CMD_FAIL: return "CMD_FAIL";
Wayne Roberts 0:987d9022c152 47 case CMD_PERR: return "CMD_PERR";
Wayne Roberts 0:987d9022c152 48 case CMD_OK: return "CMD_OK";
Wayne Roberts 0:987d9022c152 49 case CMD_DAT: return "CMD_DAT";
Wayne Roberts 0:987d9022c152 50 default: return NULL;
Wayne Roberts 0:987d9022c152 51 }
Wayne Roberts 0:987d9022c152 52 }
Wayne Roberts 0:987d9022c152 53
Wayne Roberts 0:987d9022c152 54 uint32_t SX1265::service(void)
Wayne Roberts 0:987d9022c152 55 {
Wayne Roberts 0:987d9022c152 56 uint32_t ret = 0;
Wayne Roberts 0:987d9022c152 57 uint8_t buf[4];
Wayne Roberts 0:987d9022c152 58 uint8_t irqbuf[4];
Wayne Roberts 0:987d9022c152 59
Wayne Roberts 0:987d9022c152 60 inService = true;
Wayne Roberts 1:29294cae9f9a 61 if (dio9) {
Wayne Roberts 0:987d9022c152 62 bool try_rx = false;
Wayne Roberts 0:987d9022c152 63 irq_t irq;
Wayne Roberts 0:987d9022c152 64 stat_t stat;
Wayne Roberts 0:987d9022c152 65 stat.word = xfer(OPCODE_GET_STATUS, 4, 4, irqbuf);
Wayne Roberts 0:987d9022c152 66 if (stat.bits.rfu) {
Wayne Roberts 0:987d9022c152 67 inService = false;
Wayne Roberts 0:987d9022c152 68 return -1;
Wayne Roberts 0:987d9022c152 69 }
Wayne Roberts 0:987d9022c152 70 irq.dword = from_big_endian32(irqbuf);
Wayne Roberts 0:987d9022c152 71 ret = irq.dword;
Wayne Roberts 0:987d9022c152 72 if (stat.bits.rfu) {
Wayne Roberts 0:987d9022c152 73 ret = -1;
Wayne Roberts 0:987d9022c152 74 goto done;
Wayne Roberts 0:987d9022c152 75 }
Wayne Roberts 0:987d9022c152 76 if (irq.bits.TxDone) {
Wayne Roberts 0:987d9022c152 77 chipMode = CHIPMODE_NONE;
Wayne Roberts 0:987d9022c152 78 if (chipModeChange)
Wayne Roberts 0:987d9022c152 79 chipModeChange.call(); // might change to Rx
Wayne Roberts 0:987d9022c152 80 if (txDone)
Wayne Roberts 0:987d9022c152 81 txDone.call();
Wayne Roberts 0:987d9022c152 82 }
Wayne Roberts 0:987d9022c152 83 if (irq.bits.RxDone) {
Wayne Roberts 0:987d9022c152 84 uint8_t len, offset;
Wayne Roberts 0:987d9022c152 85 float rssi, snr;
Wayne Roberts 0:987d9022c152 86 int8_t s;
Wayne Roberts 0:987d9022c152 87
Wayne Roberts 0:987d9022c152 88 stat.word = xfer(OPCODE_GET_RX_BUFFER_STATUS, 0, 0, NULL);
Wayne Roberts 0:987d9022c152 89 stat.word = xfer(0x0000, 0, 2, buf);
Wayne Roberts 0:987d9022c152 90 rx_buf_offset = buf[1];
Wayne Roberts 0:987d9022c152 91 len = buf[0];
Wayne Roberts 0:987d9022c152 92 offset = buf[1];
Wayne Roberts 0:987d9022c152 93
Wayne Roberts 0:987d9022c152 94 buf[0] = offset;
Wayne Roberts 0:987d9022c152 95 buf[1] = len;
Wayne Roberts 0:987d9022c152 96 stat.word = xfer(OPCODE_READ_BUFFER8, 2, 0, buf);
Wayne Roberts 0:987d9022c152 97 stat.word = xfer(0x0000, 0, len, rx_buf);
Wayne Roberts 0:987d9022c152 98 stat.word = xfer(OPCODE_GET_PKT_STATUS, 0, 0, NULL);
Wayne Roberts 0:987d9022c152 99 stat.word = xfer(0x0000, 0, 3, buf);
Wayne Roberts 0:987d9022c152 100 rssi = buf[0] / -2.0;
Wayne Roberts 0:987d9022c152 101 s = buf[1];
Wayne Roberts 0:987d9022c152 102 snr = s / 4.0;
Wayne Roberts 0:987d9022c152 103
Wayne Roberts 0:987d9022c152 104 rxDone(len, rssi, snr);
Wayne Roberts 0:987d9022c152 105 stat.word = xfer(OPCODE_CLEAR_RX_BUFFER, 0, 0, NULL); // yyy
Wayne Roberts 0:987d9022c152 106 }
Wayne Roberts 0:987d9022c152 107 if (irq.bits.CadDone) {
Wayne Roberts 0:987d9022c152 108 if (cadDone)
Wayne Roberts 0:987d9022c152 109 cadDone(irq.bits.CadDetected);
Wayne Roberts 0:987d9022c152 110 }
Wayne Roberts 0:987d9022c152 111 if (irq.bits.CmdErr) {
Wayne Roberts 0:987d9022c152 112 err_opcode = prev_opcode; // culprit opcode
Wayne Roberts 0:987d9022c152 113 }
Wayne Roberts 0:987d9022c152 114 if (irq.bits.Error) {
Wayne Roberts 0:987d9022c152 115 stat.word = xfer(OPCODE_GET_ERRORS, 0, 0, NULL);
Wayne Roberts 0:987d9022c152 116 stat.word = xfer(0x0000, 0, 2, buf);
Wayne Roberts 0:987d9022c152 117 if (stat.bits.cmdStatus == CMD_DAT) {
Wayne Roberts 0:987d9022c152 118 errorStat.word = buf[0];
Wayne Roberts 0:987d9022c152 119 errorStat.word <<= 8;
Wayne Roberts 0:987d9022c152 120 errorStat.word |= buf[1];
Wayne Roberts 0:987d9022c152 121 if (errorStat.bits.hf_xosc_start_) {
Wayne Roberts 0:987d9022c152 122 buf[0] = tcxoVolts;
Wayne Roberts 0:987d9022c152 123 to_big_endian32(tcxoStartDelay, buf+1);
Wayne Roberts 0:987d9022c152 124 xfer(OPCODE_SET_TCXO_MODE, 5, 0, buf);
Wayne Roberts 0:987d9022c152 125 buf[0] = 0;
Wayne Roberts 0:987d9022c152 126 xfer(OPCODE_CALIBRATE, 1, 0, buf);
Wayne Roberts 0:987d9022c152 127
Wayne Roberts 0:987d9022c152 128 if (chipMode == CHIPMODE_RX) {
Wayne Roberts 0:987d9022c152 129 /* RX start failed due to HF xosc being a tcxo */
Wayne Roberts 0:987d9022c152 130 try_rx = true;
Wayne Roberts 0:987d9022c152 131 }
Wayne Roberts 0:987d9022c152 132 }
Wayne Roberts 0:987d9022c152 133 /* ? OPCODE_CLEAR_ERRORS ? */
Wayne Roberts 0:987d9022c152 134 }
Wayne Roberts 0:987d9022c152 135 }
Wayne Roberts 0:987d9022c152 136 if (irq.bits.Timeout) {
Wayne Roberts 0:987d9022c152 137 if (chipMode != CHIPMODE_NONE) {
Wayne Roberts 0:987d9022c152 138 if (timeout)
Wayne Roberts 0:987d9022c152 139 timeout(chipMode == CHIPMODE_TX);
Wayne Roberts 0:987d9022c152 140 }
Wayne Roberts 0:987d9022c152 141 chipMode = CHIPMODE_NONE;
Wayne Roberts 0:987d9022c152 142 if (chipModeChange)
Wayne Roberts 0:987d9022c152 143 chipModeChange.call();
Wayne Roberts 0:987d9022c152 144 }
Wayne Roberts 0:987d9022c152 145
Wayne Roberts 0:987d9022c152 146 stat.word = xfer(OPCODE_CLEAR_IRQ, 4, 0, irqbuf);
Wayne Roberts 0:987d9022c152 147
Wayne Roberts 0:987d9022c152 148 if (try_rx) {
Wayne Roberts 0:987d9022c152 149 /* RX wasnt started because xosc wasnt started */
Wayne Roberts 0:987d9022c152 150 xfer(OPCODE_SET_RX, 3, 0, rxArgs);
Wayne Roberts 0:987d9022c152 151 }
Wayne Roberts 1:29294cae9f9a 152 } // ..if (dio9)
Wayne Roberts 0:987d9022c152 153
Wayne Roberts 0:987d9022c152 154 done:
Wayne Roberts 0:987d9022c152 155 inService = false;
Wayne Roberts 0:987d9022c152 156 return ret;
Wayne Roberts 0:987d9022c152 157 }
Wayne Roberts 0:987d9022c152 158
Wayne Roberts 0:987d9022c152 159 uint16_t SX1265::xfer(uint16_t opcode, uint16_t wlen, uint16_t rlen, uint8_t* ptr)
Wayne Roberts 0:987d9022c152 160 {
Wayne Roberts 0:987d9022c152 161 const uint8_t* stopPtr;
Wayne Roberts 0:987d9022c152 162 const uint8_t* wstop;
Wayne Roberts 0:987d9022c152 163 const uint8_t* rstop;
Wayne Roberts 0:987d9022c152 164 const uint8_t nop = 0;
Wayne Roberts 0:987d9022c152 165 uint16_t oc;
Wayne Roberts 0:987d9022c152 166 stat_t ret;
Wayne Roberts 0:987d9022c152 167 unsigned f;
Wayne Roberts 0:987d9022c152 168
Wayne Roberts 0:987d9022c152 169 if (opcode == OPCODE_SET_RX) {
Wayne Roberts 0:987d9022c152 170 const uint8_t* _ptr = ptr;
Wayne Roberts 0:987d9022c152 171 rxArgs[0] = *_ptr++;
Wayne Roberts 0:987d9022c152 172 rxArgs[1] = *_ptr++;
Wayne Roberts 0:987d9022c152 173 rxArgs[2] = *_ptr++;
Wayne Roberts 0:987d9022c152 174 }
Wayne Roberts 0:987d9022c152 175
Wayne Roberts 0:987d9022c152 176 if (sleeping) {
Wayne Roberts 0:987d9022c152 177 nss = 0;
Wayne Roberts 0:987d9022c152 178 while (busy)
Wayne Roberts 0:987d9022c152 179 ;
Wayne Roberts 0:987d9022c152 180 sleeping = false;
Wayne Roberts 0:987d9022c152 181 } else {
Wayne Roberts 0:987d9022c152 182 if (busy) {
Wayne Roberts 0:987d9022c152 183 int startAt = t.read_ms();
Wayne Roberts 0:987d9022c152 184 while (busy) {
Wayne Roberts 0:987d9022c152 185 if (t.read_ms() - startAt > 50) {
Wayne Roberts 0:987d9022c152 186 ret.bits.rfu = 15;
Wayne Roberts 0:987d9022c152 187 return ret.word;
Wayne Roberts 0:987d9022c152 188 }
Wayne Roberts 0:987d9022c152 189 }
Wayne Roberts 0:987d9022c152 190 }
Wayne Roberts 0:987d9022c152 191 nss = 0;
Wayne Roberts 0:987d9022c152 192 }
Wayne Roberts 0:987d9022c152 193
Wayne Roberts 0:987d9022c152 194 prev_opcode = this_opcode;
Wayne Roberts 0:987d9022c152 195 this_opcode = opcode;
Wayne Roberts 0:987d9022c152 196
Wayne Roberts 0:987d9022c152 197 oc = opcode;
Wayne Roberts 0:987d9022c152 198 f = oc >> 8;
Wayne Roberts 0:987d9022c152 199 ret.word = spi.write(f);
Wayne Roberts 0:987d9022c152 200 ret.word <<= 8;
Wayne Roberts 0:987d9022c152 201 if (opcode != 0) {
Wayne Roberts 0:987d9022c152 202 /* two byte command sent */
Wayne Roberts 0:987d9022c152 203 ret.word |= spi.write(oc & 0xff);
Wayne Roberts 0:987d9022c152 204 } /* else: response */
Wayne Roberts 0:987d9022c152 205 else
Wayne Roberts 0:987d9022c152 206 ret.word |= 0xff; // put impossible value for stat2, indicating only stat1 returned
Wayne Roberts 0:987d9022c152 207
Wayne Roberts 0:987d9022c152 208 wstop = ptr + wlen;
Wayne Roberts 0:987d9022c152 209 rstop = ptr + rlen;
Wayne Roberts 0:987d9022c152 210 if (rlen > wlen)
Wayne Roberts 0:987d9022c152 211 stopPtr = rstop;
Wayne Roberts 0:987d9022c152 212 else
Wayne Roberts 0:987d9022c152 213 stopPtr = wstop;
Wayne Roberts 0:987d9022c152 214
Wayne Roberts 0:987d9022c152 215 for (; ptr < stopPtr; ptr++) {
Wayne Roberts 0:987d9022c152 216 if (ptr < wstop && ptr < rstop)
Wayne Roberts 0:987d9022c152 217 *ptr = spi.write(*ptr);
Wayne Roberts 0:987d9022c152 218 else if (ptr < wstop)
Wayne Roberts 0:987d9022c152 219 spi.write(*ptr);
Wayne Roberts 0:987d9022c152 220 else
Wayne Roberts 0:987d9022c152 221 *ptr = spi.write(nop); // n >= write length: send NOP
Wayne Roberts 0:987d9022c152 222 }
Wayne Roberts 0:987d9022c152 223
Wayne Roberts 0:987d9022c152 224 nss = 1;
Wayne Roberts 0:987d9022c152 225
Wayne Roberts 0:987d9022c152 226 if (opcode == OPCODE_SET_SLEEP ||
Wayne Roberts 0:987d9022c152 227 opcode == OPCODE_SET_TX ||
Wayne Roberts 0:987d9022c152 228 opcode == OPCODE_SET_RX ||
Wayne Roberts 0:987d9022c152 229 opcode == OPCODE_SET_STANDBY ||
Wayne Roberts 0:987d9022c152 230 opcode == OPCODE_SET_FS)
Wayne Roberts 0:987d9022c152 231 {
Wayne Roberts 0:987d9022c152 232 if (opcode == OPCODE_SET_TX)
Wayne Roberts 0:987d9022c152 233 chipMode = CHIPMODE_TX;
Wayne Roberts 0:987d9022c152 234 else if (opcode == OPCODE_SET_RX)
Wayne Roberts 0:987d9022c152 235 chipMode = CHIPMODE_RX;
Wayne Roberts 0:987d9022c152 236 else if (opcode == OPCODE_SET_SLEEP || opcode == OPCODE_SET_STANDBY || opcode == OPCODE_SET_FS) {
Wayne Roberts 0:987d9022c152 237 if (opcode == OPCODE_SET_SLEEP)
Wayne Roberts 0:987d9022c152 238 sleeping = true;
Wayne Roberts 0:987d9022c152 239 chipMode = CHIPMODE_NONE;
Wayne Roberts 0:987d9022c152 240 }
Wayne Roberts 0:987d9022c152 241
Wayne Roberts 0:987d9022c152 242 if (chipModeChange)
Wayne Roberts 0:987d9022c152 243 chipModeChange.call();
Wayne Roberts 0:987d9022c152 244 }
Wayne Roberts 0:987d9022c152 245
Wayne Roberts 0:987d9022c152 246 if (!inService && ret.bits.intActive)
Wayne Roberts 0:987d9022c152 247 service();
Wayne Roberts 0:987d9022c152 248
Wayne Roberts 0:987d9022c152 249 return ret.word;
Wayne Roberts 0:987d9022c152 250 }
Wayne Roberts 0:987d9022c152 251
Wayne Roberts 0:987d9022c152 252 uint32_t SX1265::from_big_endian32(const uint8_t *in)
Wayne Roberts 0:987d9022c152 253 {
Wayne Roberts 0:987d9022c152 254 uint32_t ret;
Wayne Roberts 0:987d9022c152 255 ret = *in++;
Wayne Roberts 0:987d9022c152 256 ret <<= 8;
Wayne Roberts 0:987d9022c152 257 ret |= *in++;
Wayne Roberts 0:987d9022c152 258 ret <<= 8;
Wayne Roberts 0:987d9022c152 259 ret |= *in++;
Wayne Roberts 0:987d9022c152 260 ret <<= 8;
Wayne Roberts 0:987d9022c152 261 ret |= *in;
Wayne Roberts 0:987d9022c152 262 return ret;
Wayne Roberts 0:987d9022c152 263 }
Wayne Roberts 0:987d9022c152 264
Wayne Roberts 0:987d9022c152 265 void SX1265::to_big_endian16(uint16_t in, uint8_t *out)
Wayne Roberts 0:987d9022c152 266 {
Wayne Roberts 0:987d9022c152 267 out[1] = in & 0xff;
Wayne Roberts 0:987d9022c152 268 in >>= 8;
Wayne Roberts 0:987d9022c152 269 out[0] = in & 0xff;
Wayne Roberts 0:987d9022c152 270 }
Wayne Roberts 0:987d9022c152 271
Wayne Roberts 0:987d9022c152 272 void SX1265::to_big_endian24(uint32_t in, uint8_t *out)
Wayne Roberts 0:987d9022c152 273 {
Wayne Roberts 0:987d9022c152 274 out[2] = in & 0xff;
Wayne Roberts 0:987d9022c152 275 in >>= 8;
Wayne Roberts 0:987d9022c152 276 out[1] = in & 0xff;
Wayne Roberts 0:987d9022c152 277 in >>= 8;
Wayne Roberts 0:987d9022c152 278 out[0] = in & 0xff;
Wayne Roberts 0:987d9022c152 279 }
Wayne Roberts 0:987d9022c152 280
Wayne Roberts 0:987d9022c152 281 void SX1265::to_big_endian32(uint32_t in, uint8_t *out)
Wayne Roberts 0:987d9022c152 282 {
Wayne Roberts 0:987d9022c152 283 out[3] = in & 0xff;
Wayne Roberts 0:987d9022c152 284 in >>= 8;
Wayne Roberts 0:987d9022c152 285 out[2] = in & 0xff;
Wayne Roberts 0:987d9022c152 286 in >>= 8;
Wayne Roberts 0:987d9022c152 287 out[1] = in & 0xff;
Wayne Roberts 0:987d9022c152 288 in >>= 8;
Wayne Roberts 0:987d9022c152 289 out[0] = in & 0xff;
Wayne Roberts 0:987d9022c152 290 }
Wayne Roberts 0:987d9022c152 291
Wayne Roberts 0:987d9022c152 292 int SX1265::memRegRead(uint32_t addr, uint16_t len_dwords, uint32_t *dest)
Wayne Roberts 0:987d9022c152 293 {
Wayne Roberts 0:987d9022c152 294 uint8_t buf[5];
Wayne Roberts 0:987d9022c152 295 stat_t stat;
Wayne Roberts 0:987d9022c152 296 while (len_dwords > 0) {
Wayne Roberts 0:987d9022c152 297 unsigned this_len_dwords = len_dwords;
Wayne Roberts 0:987d9022c152 298 if (this_len_dwords > 64)
Wayne Roberts 0:987d9022c152 299 this_len_dwords = 64;
Wayne Roberts 0:987d9022c152 300 buf[4] = this_len_dwords;
Wayne Roberts 0:987d9022c152 301 to_big_endian32(addr, buf);
Wayne Roberts 0:987d9022c152 302 stat.word = xfer(OPCODE_READREGMEM32, 5, 5, buf);
Wayne Roberts 0:987d9022c152 303 if (stat.bits.rfu) {
Wayne Roberts 0:987d9022c152 304 hw_reset();
Wayne Roberts 0:987d9022c152 305 return -1;
Wayne Roberts 0:987d9022c152 306 }
Wayne Roberts 0:987d9022c152 307 unsigned n, len_bytes = this_len_dwords * 4;
Wayne Roberts 0:987d9022c152 308 stat.word = xfer(0x0000, 0, len_bytes, (uint8_t*)dest);
Wayne Roberts 0:987d9022c152 309 if (stat.bits.rfu) {
Wayne Roberts 0:987d9022c152 310 hw_reset();
Wayne Roberts 0:987d9022c152 311 return -1;
Wayne Roberts 0:987d9022c152 312 } else {
Wayne Roberts 0:987d9022c152 313 if (stat.bits.cmdStatus != CMD_DAT) {
Wayne Roberts 0:987d9022c152 314 return -1;
Wayne Roberts 0:987d9022c152 315 }
Wayne Roberts 0:987d9022c152 316 for (n = 0; n < this_len_dwords; n++) {
Wayne Roberts 0:987d9022c152 317 *dest = from_big_endian32((uint8_t*)dest);
Wayne Roberts 0:987d9022c152 318 dest++;
Wayne Roberts 0:987d9022c152 319 }
Wayne Roberts 0:987d9022c152 320 }
Wayne Roberts 0:987d9022c152 321
Wayne Roberts 0:987d9022c152 322 addr += len_bytes;
Wayne Roberts 0:987d9022c152 323 len_dwords -= this_len_dwords;
Wayne Roberts 0:987d9022c152 324 } // ..while (len_dwords > 0)
Wayne Roberts 0:987d9022c152 325
Wayne Roberts 0:987d9022c152 326 return 0;
Wayne Roberts 0:987d9022c152 327 } // ..memRegRead()
Wayne Roberts 0:987d9022c152 328
Wayne Roberts 0:987d9022c152 329 void SX1265::enable_default_irqs_()
Wayne Roberts 0:987d9022c152 330 {
Wayne Roberts 0:987d9022c152 331 /* DIO9 is hi-z when no irqs enabled (floats high) */
Wayne Roberts 0:987d9022c152 332 uint8_t buf[4];
Wayne Roberts 0:987d9022c152 333 to_big_endian32(default_irqs, buf);
Wayne Roberts 0:987d9022c152 334 xfer(OPCODE_SET_DIOIRQPARAMS, 4, 4, buf);
Wayne Roberts 0:987d9022c152 335 }
Wayne Roberts 0:987d9022c152 336
Wayne Roberts 0:987d9022c152 337 float SX1265::getMHz()
Wayne Roberts 0:987d9022c152 338 {
Wayne Roberts 0:987d9022c152 339 uint32_t frf;
Wayne Roberts 0:987d9022c152 340 memRegRead(REG_ADDR_RFFREQ, 1, &frf);
Wayne Roberts 0:987d9022c152 341 return frf / 1048576.0;
Wayne Roberts 0:987d9022c152 342 }
Wayne Roberts 0:987d9022c152 343
Wayne Roberts 0:987d9022c152 344 uint8_t SX1265::setMHz(float MHz)
Wayne Roberts 0:987d9022c152 345 {
Wayne Roberts 0:987d9022c152 346 uint8_t buf[4];
Wayne Roberts 0:987d9022c152 347 to_big_endian32(MHz * 1000000, buf);
Wayne Roberts 0:987d9022c152 348 xfer(OPCODE_SET_RF_FREQ_HZ, 4, 0, buf);
Wayne Roberts 0:987d9022c152 349 return 0;
Wayne Roberts 0:987d9022c152 350 }
Wayne Roberts 0:987d9022c152 351
Wayne Roberts 0:987d9022c152 352 void SX1265::setPacketType(uint8_t pt)
Wayne Roberts 0:987d9022c152 353 {
Wayne Roberts 0:987d9022c152 354 xfer(OPCODE_SET_PACKET_TYPE, 1, 0, &pt);
Wayne Roberts 0:987d9022c152 355 }
Wayne Roberts 0:987d9022c152 356
Wayne Roberts 0:987d9022c152 357 uint8_t SX1265::getPacketType()
Wayne Roberts 0:987d9022c152 358 {
Wayne Roberts 0:987d9022c152 359 uint8_t buf;
Wayne Roberts 0:987d9022c152 360 stat_t stat;
Wayne Roberts 0:987d9022c152 361 xfer(OPCODE_GET_PACKET_TYPE, 0, 0, NULL);
Wayne Roberts 0:987d9022c152 362 stat.word = xfer(0x0000, 0, 1, &buf);
Wayne Roberts 0:987d9022c152 363 if (stat.bits.cmdStatus == CMD_DAT)
Wayne Roberts 0:987d9022c152 364 return buf;
Wayne Roberts 0:987d9022c152 365 else
Wayne Roberts 0:987d9022c152 366 return 0;
Wayne Roberts 0:987d9022c152 367 }
Wayne Roberts 0:987d9022c152 368
Wayne Roberts 0:987d9022c152 369 void SX1265::start_tx(uint8_t pktLen)
Wayne Roberts 0:987d9022c152 370 {
Wayne Roberts 0:987d9022c152 371 uint8_t buf[3];
Wayne Roberts 0:987d9022c152 372 xfer(OPCODE_WRITE_BUFFER8, pktLen, 0, tx_buf);
Wayne Roberts 0:987d9022c152 373 to_big_endian24(txTimeout, buf);
Wayne Roberts 0:987d9022c152 374 xfer(OPCODE_SET_TX, 3, 0, buf);
Wayne Roberts 0:987d9022c152 375 }
Wayne Roberts 0:987d9022c152 376
Wayne Roberts 0:987d9022c152 377 void SX1265::GetPaConfig(uint8_t *out)
Wayne Roberts 0:987d9022c152 378 {
Wayne Roberts 0:987d9022c152 379 txParamsA_t tpa;
Wayne Roberts 0:987d9022c152 380 txParamsB_t tpb;
Wayne Roberts 0:987d9022c152 381 /* PaSel also in 0x00f30088 */
Wayne Roberts 0:987d9022c152 382 memRegRead(REG_ADDR_TX_PARAMS_A, 1, &tpa.dword);
Wayne Roberts 0:987d9022c152 383 memRegRead(REG_ADDR_TX_PARAMS_B, 1, &tpb.dword);
Wayne Roberts 0:987d9022c152 384 out[0] = tpb.bits.PaSel;
Wayne Roberts 0:987d9022c152 385 out[1] = tpa.bits.RegPASupply;
Wayne Roberts 0:987d9022c152 386 out[2] = tpb.bits.PaDutyCycle;
Wayne Roberts 0:987d9022c152 387 out[3] = tpb.bits.PaHPSel;
Wayne Roberts 0:987d9022c152 388 }
Wayne Roberts 0:987d9022c152 389
Wayne Roberts 0:987d9022c152 390 void SX1265::GetLoRaModulationParameters(uint8_t *out)
Wayne Roberts 0:987d9022c152 391 {
Wayne Roberts 0:987d9022c152 392 loraConfig0_t cfg0;
Wayne Roberts 0:987d9022c152 393 memRegRead(REG_ADDR_LORA_CONFIG0, 1, &cfg0.dword);
Wayne Roberts 0:987d9022c152 394
Wayne Roberts 0:987d9022c152 395 out[0] = cfg0.bits.modem_sf;
Wayne Roberts 0:987d9022c152 396 out[1] = cfg0.bits.modem_bw;
Wayne Roberts 0:987d9022c152 397 out[2] = cfg0.bits.coding_rate;
Wayne Roberts 0:987d9022c152 398 out[3] = cfg0.bits.ppm_offset;
Wayne Roberts 0:987d9022c152 399 }
Wayne Roberts 0:987d9022c152 400
Wayne Roberts 0:987d9022c152 401 void SX1265::GetGfskModulationParameters(uint8_t *out)
Wayne Roberts 0:987d9022c152 402 {
Wayne Roberts 0:987d9022c152 403 uint32_t u32;
Wayne Roberts 0:987d9022c152 404 gfskBW_t bw_reg;
Wayne Roberts 0:987d9022c152 405 gfskConfig0_t cfg0;
Wayne Roberts 0:987d9022c152 406 uint8_t bwf;
Wayne Roberts 0:987d9022c152 407 unsigned hz;
Wayne Roberts 0:987d9022c152 408
Wayne Roberts 0:987d9022c152 409 memRegRead(REG_ADDR_GFSK_BITRATE, 1, &u32);
Wayne Roberts 0:987d9022c152 410 hz = GFSK_BITRATE_NUMERATOR / u32;
Wayne Roberts 0:987d9022c152 411 to_big_endian32(hz, out);
Wayne Roberts 0:987d9022c152 412
Wayne Roberts 0:987d9022c152 413 memRegRead(REG_ADDR_GFSK_CFG0, 1, &cfg0.dword);
Wayne Roberts 0:987d9022c152 414 switch (cfg0.bits.bt) {
Wayne Roberts 0:987d9022c152 415 case 0: /* off */ out[4] = GFSK_BT_OFF; break;
Wayne Roberts 0:987d9022c152 416 case 1: /* 0.3 */ out[4] = GFSK_BT_0_3; break;
Wayne Roberts 0:987d9022c152 417 case 2: /* 0.5 */ out[4] = GFSK_BT_0_5; break;
Wayne Roberts 0:987d9022c152 418 case 3: /* 0.7 */ out[4] = GFSK_BT_0_7; break;
Wayne Roberts 0:987d9022c152 419 case 4: /* 1.0 */ out[4] = GFSK_BT_1_0; break;
Wayne Roberts 0:987d9022c152 420 }
Wayne Roberts 0:987d9022c152 421
Wayne Roberts 0:987d9022c152 422 memRegRead(REG_ADDR_GFSK_BWF, 1, &bw_reg.dword);
Wayne Roberts 0:987d9022c152 423 bwf = bw_reg.bits.bwf_hi;
Wayne Roberts 0:987d9022c152 424 bwf <<= 3;
Wayne Roberts 0:987d9022c152 425 bwf |= bw_reg.bits.bwf_lo;
Wayne Roberts 0:987d9022c152 426 out[5] = bwf;
Wayne Roberts 0:987d9022c152 427
Wayne Roberts 0:987d9022c152 428 memRegRead(REG_ADDR_GFSK_FDEV, 1, &u32);
Wayne Roberts 0:987d9022c152 429 hz = (unsigned) ((u32 * FREQ_STEP) - 0.5);
Wayne Roberts 0:987d9022c152 430 to_big_endian32(hz, out+6);
Wayne Roberts 0:987d9022c152 431 }
Wayne Roberts 0:987d9022c152 432
Wayne Roberts 0:987d9022c152 433 void SX1265::GetLoRaPacketParameters(uint8_t *out)
Wayne Roberts 0:987d9022c152 434 {
Wayne Roberts 0:987d9022c152 435 loraConfig0_t cfg0;
Wayne Roberts 0:987d9022c152 436 loraConfigA_t cfgA;
Wayne Roberts 0:987d9022c152 437 loraConfigC_t cfgc;
Wayne Roberts 0:987d9022c152 438 unsigned pl;
Wayne Roberts 0:987d9022c152 439
Wayne Roberts 0:987d9022c152 440 memRegRead(REG_ADDR_LORA_CONFIGC, 1, &cfgc.dword);
Wayne Roberts 0:987d9022c152 441 pl = cfgc.bits.preamble_length;
Wayne Roberts 0:987d9022c152 442 out[1] = pl & 0xff;
Wayne Roberts 0:987d9022c152 443 pl >>= 8;
Wayne Roberts 0:987d9022c152 444 out[0] = pl;
Wayne Roberts 0:987d9022c152 445
Wayne Roberts 0:987d9022c152 446 memRegRead(REG_ADDR_LORA_CONFIG0, 1, &cfg0.dword);
Wayne Roberts 0:987d9022c152 447 out[2] = cfg0.bits.implicit_header;
Wayne Roberts 0:987d9022c152 448 out[3] = cfg0.bits.payload_length;
Wayne Roberts 0:987d9022c152 449 out[4] = cfg0.bits.crc_on;
Wayne Roberts 0:987d9022c152 450
Wayne Roberts 0:987d9022c152 451 memRegRead(REG_ADDR_LORA_CONFIGA, 1, &cfgA.dword);
Wayne Roberts 0:987d9022c152 452 out[5] = cfgA.bits.invertIQ;
Wayne Roberts 0:987d9022c152 453 }
Wayne Roberts 0:987d9022c152 454
Wayne Roberts 0:987d9022c152 455 void SX1265::GetGfskPacketParameters(uint8_t *out)
Wayne Roberts 0:987d9022c152 456 {
Wayne Roberts 0:987d9022c152 457 gfskConfig1_t cfg1;
Wayne Roberts 0:987d9022c152 458 gfskConfig2_t cfg2;
Wayne Roberts 0:987d9022c152 459 gfskConfig3_t cfg3;
Wayne Roberts 0:987d9022c152 460 gfskConfig4_t cfg4;
Wayne Roberts 0:987d9022c152 461 gfskConfig5_t cfg5;
Wayne Roberts 0:987d9022c152 462 uint32_t u32;
Wayne Roberts 0:987d9022c152 463
Wayne Roberts 0:987d9022c152 464 memRegRead(REG_ADDR_GFSK_CFG1, 1, &cfg1.dword);
Wayne Roberts 0:987d9022c152 465
Wayne Roberts 0:987d9022c152 466 u32 = cfg1.bits.preamble_length;
Wayne Roberts 0:987d9022c152 467 out[1] = u32;
Wayne Roberts 0:987d9022c152 468 u32 >>= 8;
Wayne Roberts 0:987d9022c152 469 out[0] = u32;
Wayne Roberts 0:987d9022c152 470
Wayne Roberts 0:987d9022c152 471 memRegRead(REG_ADDR_GFSK_CFG1, 1, &cfg1.dword);
Wayne Roberts 0:987d9022c152 472 if (cfg1.bits.preamble_det_enable)
Wayne Roberts 0:987d9022c152 473 out[2] = cfg1.bits.preamble_det_len;
Wayne Roberts 0:987d9022c152 474 else
Wayne Roberts 0:987d9022c152 475 out[2] = 0;
Wayne Roberts 0:987d9022c152 476
Wayne Roberts 0:987d9022c152 477 memRegRead(REG_ADDR_GFSK_CFG2, 1, &cfg2.dword);
Wayne Roberts 0:987d9022c152 478 out[3] = cfg2.bits.sync_word_length;
Wayne Roberts 0:987d9022c152 479
Wayne Roberts 0:987d9022c152 480 memRegRead(REG_ADDR_GFSK_PAYLOAD_LENGTH_B, 1, &cfg4.dword);
Wayne Roberts 0:987d9022c152 481 out[4] = cfg4.bits.addr_comp;
Wayne Roberts 0:987d9022c152 482
Wayne Roberts 0:987d9022c152 483 memRegRead(REG_ADDR_GFSK_CFG3, 1, &cfg3.dword);
Wayne Roberts 0:987d9022c152 484 out[5] = cfg3.bits.variable_length;
Wayne Roberts 0:987d9022c152 485
Wayne Roberts 0:987d9022c152 486 memRegRead(REG_ADDR_GFSK_PAYLOAD_LENGTH_A, 1, &u32);
Wayne Roberts 0:987d9022c152 487 out[6] = u32 & 0xff;
Wayne Roberts 0:987d9022c152 488
Wayne Roberts 0:987d9022c152 489 memRegRead(REG_ADDR_GFSK_CFG5, 1, &cfg5.dword);
Wayne Roberts 0:987d9022c152 490
Wayne Roberts 0:987d9022c152 491 if (cfg5.bits.crc_off)
Wayne Roberts 0:987d9022c152 492 out[7] |= 1;
Wayne Roberts 0:987d9022c152 493 else
Wayne Roberts 0:987d9022c152 494 out[7] &= ~1;
Wayne Roberts 0:987d9022c152 495
Wayne Roberts 0:987d9022c152 496 if (cfg5.bits.crc_size)
Wayne Roberts 0:987d9022c152 497 out[7] |= 2;
Wayne Roberts 0:987d9022c152 498 else
Wayne Roberts 0:987d9022c152 499 out[7] &= ~2;
Wayne Roberts 0:987d9022c152 500
Wayne Roberts 0:987d9022c152 501 if (cfg5.bits.crc_invert)
Wayne Roberts 0:987d9022c152 502 out[7] |= 4;
Wayne Roberts 0:987d9022c152 503 else
Wayne Roberts 0:987d9022c152 504 out[7] &= ~4;
Wayne Roberts 0:987d9022c152 505
Wayne Roberts 0:987d9022c152 506 out[8] = cfg5.bits.whitening_enable;
Wayne Roberts 0:987d9022c152 507 }
Wayne Roberts 0:987d9022c152 508