driver for sx1280

Dependents:   alarm_slave_extended_SX1280 alarm_master_extended_Vance_SX1280

Committer:
Wayne Roberts
Date:
Fri Jul 10 09:32:04 2020 -0700
Revision:
8:7b0b2e3ca9d2
Parent:
7:aa7047cdf47b
run on mbed-6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:abb827c65ff5 1 #include "sx12xx.h"
Wayne Roberts 0:abb827c65ff5 2
Wayne Roberts 0:abb827c65ff5 3 Callback<void()> SX128x::diox_topHalf; // low latency ISR context
Wayne Roberts 0:abb827c65ff5 4
Wayne Roberts 0:abb827c65ff5 5 const float SX128x::timeOutStep[] = { 0.015625, 0.0625, 1, 4 };
Wayne Roberts 0:abb827c65ff5 6
Wayne Roberts 0:abb827c65ff5 7 void SX128x::dioxisr()
Wayne Roberts 0:abb827c65ff5 8 {
Wayne Roberts 0:abb827c65ff5 9 if (diox_topHalf)
Wayne Roberts 0:abb827c65ff5 10 diox_topHalf.call();
Wayne Roberts 0:abb827c65ff5 11 }
Wayne Roberts 0:abb827c65ff5 12
Wayne Roberts 2:8a442c3511ae 13 SX128x::SX128x(SPI& _spi, PinName _nss, PinName _busy, PinName _diox, PinName _nrst)
Wayne Roberts 2:8a442c3511ae 14 : spi(_spi), nss(_nss), busy(_busy), diox(_diox), nrst(_nrst)
Wayne Roberts 0:abb827c65ff5 15 {
Wayne Roberts 2:8a442c3511ae 16 unsigned busyCnt = 0;
Wayne Roberts 0:abb827c65ff5 17 nss = 1;
Wayne Roberts 0:abb827c65ff5 18
Wayne Roberts 2:8a442c3511ae 19 while (busy) {
Wayne Roberts 2:8a442c3511ae 20 if (++busyCnt > 0x80000) {
Wayne Roberts 2:8a442c3511ae 21 hw_reset();
Wayne Roberts 2:8a442c3511ae 22 }
Wayne Roberts 0:abb827c65ff5 23 }
Wayne Roberts 0:abb827c65ff5 24
Wayne Roberts 0:abb827c65ff5 25 periodBase = 3;
Wayne Roberts 2:8a442c3511ae 26
Wayne Roberts 2:8a442c3511ae 27 diox.rise(dioxisr);
Wayne Roberts 0:abb827c65ff5 28 }
Wayne Roberts 0:abb827c65ff5 29
Wayne Roberts 0:abb827c65ff5 30 uint8_t SX128x::xfer(uint8_t opcode, uint8_t wlen, uint8_t rlen, uint8_t* ptr)
Wayne Roberts 0:abb827c65ff5 31 {
Wayne Roberts 0:abb827c65ff5 32 const uint8_t* stopPtr;
Wayne Roberts 0:abb827c65ff5 33 const uint8_t* wstop;
Wayne Roberts 0:abb827c65ff5 34 const uint8_t* rstop;
Wayne Roberts 0:abb827c65ff5 35 uint8_t nop = 0;
Wayne Roberts 0:abb827c65ff5 36 uint8_t ret;
Wayne Roberts 0:abb827c65ff5 37
Wayne Roberts 0:abb827c65ff5 38 if (opcode != OPCODE_GET_STATUS) {
Wayne Roberts 0:abb827c65ff5 39 if (sleeping) {
Wayne Roberts 0:abb827c65ff5 40 nss = 0;
Wayne Roberts 0:abb827c65ff5 41 while (busy)
Wayne Roberts 0:abb827c65ff5 42 ;
Wayne Roberts 0:abb827c65ff5 43 sleeping = false;
Wayne Roberts 0:abb827c65ff5 44 } else {
Wayne Roberts 0:abb827c65ff5 45 while (busy)
Wayne Roberts 0:abb827c65ff5 46 ;
Wayne Roberts 0:abb827c65ff5 47
Wayne Roberts 0:abb827c65ff5 48 nss = 0;
Wayne Roberts 0:abb827c65ff5 49 }
Wayne Roberts 0:abb827c65ff5 50 } else
Wayne Roberts 0:abb827c65ff5 51 nss = 0;
Wayne Roberts 0:abb827c65ff5 52
Wayne Roberts 0:abb827c65ff5 53 ret = spi.write(opcode);
Wayne Roberts 0:abb827c65ff5 54
Wayne Roberts 0:abb827c65ff5 55 wstop = ptr + wlen;
Wayne Roberts 0:abb827c65ff5 56 rstop = ptr + rlen;
Wayne Roberts 0:abb827c65ff5 57 if (rlen > wlen)
Wayne Roberts 0:abb827c65ff5 58 stopPtr = rstop;
Wayne Roberts 0:abb827c65ff5 59 else
Wayne Roberts 0:abb827c65ff5 60 stopPtr = wstop;
Wayne Roberts 0:abb827c65ff5 61
Wayne Roberts 0:abb827c65ff5 62 for (; ptr < stopPtr; ptr++) {
Wayne Roberts 0:abb827c65ff5 63 if (ptr < wstop && ptr < rstop)
Wayne Roberts 0:abb827c65ff5 64 *ptr = spi.write(*ptr);
Wayne Roberts 0:abb827c65ff5 65 else if (ptr < wstop)
Wayne Roberts 0:abb827c65ff5 66 spi.write(*ptr);
Wayne Roberts 0:abb827c65ff5 67 else
Wayne Roberts 0:abb827c65ff5 68 *ptr = spi.write(nop); // n >= write length: send NOP
Wayne Roberts 0:abb827c65ff5 69 }
Wayne Roberts 0:abb827c65ff5 70
Wayne Roberts 0:abb827c65ff5 71 nss = 1;
Wayne Roberts 0:abb827c65ff5 72
Wayne Roberts 0:abb827c65ff5 73 if (opcode == OPCODE_SET_SLEEP)
Wayne Roberts 0:abb827c65ff5 74 sleeping = true;
Wayne Roberts 0:abb827c65ff5 75
Wayne Roberts 0:abb827c65ff5 76 return ret;
Wayne Roberts 0:abb827c65ff5 77 }
Wayne Roberts 0:abb827c65ff5 78
Wayne Roberts 0:abb827c65ff5 79 uint32_t SX128x::readReg(uint16_t addr, uint8_t len)
Wayne Roberts 0:abb827c65ff5 80 {
Wayne Roberts 0:abb827c65ff5 81 uint32_t ret = 0;
Wayne Roberts 0:abb827c65ff5 82 unsigned i;
Wayne Roberts 0:abb827c65ff5 83
Wayne Roberts 0:abb827c65ff5 84 uint8_t buf[7];
Wayne Roberts 0:abb827c65ff5 85 buf[0] = addr >> 8;
Wayne Roberts 0:abb827c65ff5 86 buf[1] = (uint8_t)addr;
Wayne Roberts 0:abb827c65ff5 87 xfer(OPCODE_READ_REGISTER, 2, 3+len, buf);
Wayne Roberts 0:abb827c65ff5 88 for (i = 0; i < len; i++) {
Wayne Roberts 0:abb827c65ff5 89 ret <<= 8;
Wayne Roberts 0:abb827c65ff5 90 ret |= buf[i+3];
Wayne Roberts 0:abb827c65ff5 91 }
Wayne Roberts 0:abb827c65ff5 92 return ret;
Wayne Roberts 0:abb827c65ff5 93 }
Wayne Roberts 0:abb827c65ff5 94
Wayne Roberts 0:abb827c65ff5 95 void SX128x::start_tx(uint8_t pktLen, float timeout_ms)
Wayne Roberts 0:abb827c65ff5 96 {
Wayne Roberts 0:abb827c65ff5 97 IrqFlags_t irqEnable;
Wayne Roberts 0:abb827c65ff5 98 uint8_t buf[8];
Wayne Roberts 0:abb827c65ff5 99
Wayne Roberts 0:abb827c65ff5 100 irqEnable.word = 0;
Wayne Roberts 0:abb827c65ff5 101 irqEnable.bits.TxDone = 1;
Wayne Roberts 0:abb827c65ff5 102 irqEnable.bits.RxTxTimeout = 1;
Wayne Roberts 0:abb827c65ff5 103
Wayne Roberts 0:abb827c65ff5 104 buf[0] = irqEnable.word >> 8; // enable bits
Wayne Roberts 0:abb827c65ff5 105 buf[1] = irqEnable.word; // enable bits
Wayne Roberts 0:abb827c65ff5 106 buf[2] = irqEnable.word >> 8; // dio1
Wayne Roberts 0:abb827c65ff5 107 buf[3] = irqEnable.word; // dio1
Wayne Roberts 0:abb827c65ff5 108 buf[4] = 0; // dio2
Wayne Roberts 0:abb827c65ff5 109 buf[5] = 0; // dio2
Wayne Roberts 0:abb827c65ff5 110 buf[6] = 0; // dio3
Wayne Roberts 0:abb827c65ff5 111 buf[7] = 0; // dio3
Wayne Roberts 0:abb827c65ff5 112 xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
Wayne Roberts 0:abb827c65ff5 113
Wayne Roberts 0:abb827c65ff5 114 {
Wayne Roberts 0:abb827c65ff5 115 uint8_t i;
Wayne Roberts 0:abb827c65ff5 116
Wayne Roberts 0:abb827c65ff5 117 while (busy)
Wayne Roberts 0:abb827c65ff5 118 ;
Wayne Roberts 0:abb827c65ff5 119
Wayne Roberts 0:abb827c65ff5 120 nss = 0;
Wayne Roberts 0:abb827c65ff5 121 spi.write(OPCODE_WRITE_BUFFER);
Wayne Roberts 0:abb827c65ff5 122 spi.write(0); // offset
Wayne Roberts 0:abb827c65ff5 123 i = 0;
Wayne Roberts 0:abb827c65ff5 124 for (i = 0; i < pktLen; i++) {
Wayne Roberts 0:abb827c65ff5 125 spi.write(tx_buf[i]);
Wayne Roberts 0:abb827c65ff5 126 }
Wayne Roberts 0:abb827c65ff5 127 nss = 1;
Wayne Roberts 0:abb827c65ff5 128 }
Wayne Roberts 0:abb827c65ff5 129
Wayne Roberts 2:8a442c3511ae 130 buf[0] = periodBase;
Wayne Roberts 0:abb827c65ff5 131 if (timeout_ms > 0) {
Wayne Roberts 0:abb827c65ff5 132 unsigned t_o = timeout_ms / timeOutStep[periodBase];
Wayne Roberts 0:abb827c65ff5 133 buf[1] = t_o >> 8;
Wayne Roberts 0:abb827c65ff5 134 buf[2] = t_o;
Wayne Roberts 0:abb827c65ff5 135 } else {
Wayne Roberts 0:abb827c65ff5 136 /* no timeout */
Wayne Roberts 0:abb827c65ff5 137 buf[1] = 0;
Wayne Roberts 0:abb827c65ff5 138 buf[2] = 0;
Wayne Roberts 0:abb827c65ff5 139 }
Wayne Roberts 0:abb827c65ff5 140 xfer(OPCODE_SET_TX, 3, 0, buf);
Wayne Roberts 0:abb827c65ff5 141
Wayne Roberts 0:abb827c65ff5 142 chipMode = CHIPMODE_TX;
Wayne Roberts 0:abb827c65ff5 143 if (chipModeChange)
Wayne Roberts 0:abb827c65ff5 144 chipModeChange.call();
Wayne Roberts 0:abb827c65ff5 145 }
Wayne Roberts 0:abb827c65ff5 146
Wayne Roberts 2:8a442c3511ae 147 void SX128x::hw_reset()
Wayne Roberts 0:abb827c65ff5 148 {
Wayne Roberts 0:abb827c65ff5 149 nrst.output();
Wayne Roberts 0:abb827c65ff5 150 nrst = 0;
Wayne Roberts 8:7b0b2e3ca9d2 151 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 8:7b0b2e3ca9d2 152 ThisThread::sleep_for(1);
Wayne Roberts 8:7b0b2e3ca9d2 153 #else
Wayne Roberts 8:7b0b2e3ca9d2 154 ThisThread::sleep_for(1ms);
Wayne Roberts 8:7b0b2e3ca9d2 155 #endif
Wayne Roberts 0:abb827c65ff5 156 nrst = 1;
Wayne Roberts 0:abb827c65ff5 157 nrst.mode(PullUp);
Wayne Roberts 0:abb827c65ff5 158 nrst.input();
Wayne Roberts 0:abb827c65ff5 159
Wayne Roberts 0:abb827c65ff5 160 while (busy)
Wayne Roberts 0:abb827c65ff5 161 ;
Wayne Roberts 0:abb827c65ff5 162 }
Wayne Roberts 0:abb827c65ff5 163
Wayne Roberts 0:abb827c65ff5 164 uint64_t SX128x::getSyncAddr(uint8_t num)
Wayne Roberts 0:abb827c65ff5 165 {
Wayne Roberts 0:abb827c65ff5 166 uint64_t ret;
Wayne Roberts 0:abb827c65ff5 167 unsigned regAdr = REG_ADDR_PKT_SYNC_ADRS_1 + ((num-1) * 5);
Wayne Roberts 0:abb827c65ff5 168 ret = readReg(regAdr, 1);
Wayne Roberts 0:abb827c65ff5 169 ret <<= 32;
Wayne Roberts 0:abb827c65ff5 170 ret |= readReg(regAdr+1, 4);
Wayne Roberts 0:abb827c65ff5 171 return ret;
Wayne Roberts 0:abb827c65ff5 172 }
Wayne Roberts 0:abb827c65ff5 173
Wayne Roberts 0:abb827c65ff5 174 void SX128x::setSyncAddr(uint8_t num, uint64_t sa)
Wayne Roberts 0:abb827c65ff5 175 {
Wayne Roberts 0:abb827c65ff5 176 unsigned regAdr = REG_ADDR_PKT_SYNC_ADRS_1 + ((num-1) * 5);
Wayne Roberts 0:abb827c65ff5 177 writeReg(regAdr+1, sa & 0xffffffff, 4);
Wayne Roberts 0:abb827c65ff5 178 sa >>= 32;
Wayne Roberts 0:abb827c65ff5 179 writeReg(regAdr, sa & 0xff, 1);
Wayne Roberts 0:abb827c65ff5 180 }
Wayne Roberts 0:abb827c65ff5 181
Wayne Roberts 0:abb827c65ff5 182 void SX128x::set_tx_dbm(int8_t dbm)
Wayne Roberts 0:abb827c65ff5 183 {
Wayne Roberts 0:abb827c65ff5 184 uint8_t buf[2];
Wayne Roberts 0:abb827c65ff5 185
Wayne Roberts 0:abb827c65ff5 186 buf[0] = dbm;
Wayne Roberts 0:abb827c65ff5 187 buf[1] = RADIO_RAMP_20_US;
Wayne Roberts 0:abb827c65ff5 188 xfer(OPCODE_SET_TX_PARAMS, 2, 0, buf);
Wayne Roberts 0:abb827c65ff5 189 }
Wayne Roberts 0:abb827c65ff5 190
Wayne Roberts 0:abb827c65ff5 191 void SX128x::setMHz(float MHz)
Wayne Roberts 0:abb827c65ff5 192 {
Wayne Roberts 0:abb827c65ff5 193 unsigned frf = MHz / PLL_STEP_MHZ;
Wayne Roberts 0:abb827c65ff5 194 uint8_t buf[3];
Wayne Roberts 0:abb827c65ff5 195
Wayne Roberts 0:abb827c65ff5 196 buf[0] = frf >> 16;
Wayne Roberts 0:abb827c65ff5 197 buf[1] = frf >> 8;
Wayne Roberts 0:abb827c65ff5 198 buf[2] = frf;
Wayne Roberts 0:abb827c65ff5 199 xfer(OPCODE_SET_RF_FREQUENCY, 3, 0, buf);
Wayne Roberts 0:abb827c65ff5 200 }
Wayne Roberts 0:abb827c65ff5 201
Wayne Roberts 0:abb827c65ff5 202 float SX128x::getMHz()
Wayne Roberts 0:abb827c65ff5 203 {
Wayne Roberts 7:aa7047cdf47b 204 uint32_t frf;
Wayne Roberts 7:aa7047cdf47b 205 if (pktType == PACKET_TYPE_LORA)
Wayne Roberts 7:aa7047cdf47b 206 frf = readReg(REG_ADDR_LORA_SD_FREQ, 3);
Wayne Roberts 7:aa7047cdf47b 207 else
Wayne Roberts 7:aa7047cdf47b 208 frf = readReg(REG_ADDR_RFFREQ, 3);
Wayne Roberts 7:aa7047cdf47b 209
Wayne Roberts 0:abb827c65ff5 210 return frf * PLL_STEP_MHZ;
Wayne Roberts 0:abb827c65ff5 211 }
Wayne Roberts 0:abb827c65ff5 212
Wayne Roberts 0:abb827c65ff5 213 void SX128x::setStandby(stby_t stby)
Wayne Roberts 0:abb827c65ff5 214 {
Wayne Roberts 0:abb827c65ff5 215 uint8_t octet = stby;
Wayne Roberts 0:abb827c65ff5 216 xfer(OPCODE_SET_STANDBY, 1, 0, &octet);
Wayne Roberts 0:abb827c65ff5 217
Wayne Roberts 0:abb827c65ff5 218 chipMode = CHIPMODE_NONE;
Wayne Roberts 0:abb827c65ff5 219 if (chipModeChange)
Wayne Roberts 0:abb827c65ff5 220 chipModeChange.call();
Wayne Roberts 0:abb827c65ff5 221 }
Wayne Roberts 0:abb827c65ff5 222
Wayne Roberts 5:aba2d8b29702 223 void SX128x::setCAD()
Wayne Roberts 5:aba2d8b29702 224 {
Wayne Roberts 5:aba2d8b29702 225 IrqFlags_t irqEnable;
Wayne Roberts 5:aba2d8b29702 226 uint8_t buf[8];
Wayne Roberts 5:aba2d8b29702 227
Wayne Roberts 5:aba2d8b29702 228 irqEnable.word = 0;
Wayne Roberts 5:aba2d8b29702 229 irqEnable.bits.CadDone = 1;
Wayne Roberts 5:aba2d8b29702 230 irqEnable.bits.CadDetected = 1;
Wayne Roberts 5:aba2d8b29702 231 irqEnable.bits.RxDone = 1;
Wayne Roberts 5:aba2d8b29702 232 irqEnable.bits.RxTxTimeout = 1;
Wayne Roberts 5:aba2d8b29702 233
Wayne Roberts 5:aba2d8b29702 234 buf[0] = irqEnable.word >> 8; // enable bits
Wayne Roberts 5:aba2d8b29702 235 buf[1] = irqEnable.word; // enable bits
Wayne Roberts 5:aba2d8b29702 236 buf[2] = irqEnable.word >> 8; // dio1
Wayne Roberts 5:aba2d8b29702 237 buf[3] = irqEnable.word; // dio1
Wayne Roberts 5:aba2d8b29702 238 buf[4] = 0; // dio2
Wayne Roberts 5:aba2d8b29702 239 buf[5] = 0; // dio2
Wayne Roberts 5:aba2d8b29702 240 buf[6] = 0; // dio3
Wayne Roberts 5:aba2d8b29702 241 buf[7] = 0; // dio3
Wayne Roberts 5:aba2d8b29702 242 xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
Wayne Roberts 5:aba2d8b29702 243
Wayne Roberts 5:aba2d8b29702 244 xfer(OPCODE_SET_CAD, 0, 0, NULL);
Wayne Roberts 5:aba2d8b29702 245
Wayne Roberts 5:aba2d8b29702 246 chipMode = CHIPMODE_RX;
Wayne Roberts 5:aba2d8b29702 247 if (chipModeChange)
Wayne Roberts 5:aba2d8b29702 248 chipModeChange.call();
Wayne Roberts 5:aba2d8b29702 249 }
Wayne Roberts 5:aba2d8b29702 250
Wayne Roberts 0:abb827c65ff5 251 void SX128x::setFS()
Wayne Roberts 0:abb827c65ff5 252 {
Wayne Roberts 0:abb827c65ff5 253 xfer(OPCODE_SET_FS, 0, 0, NULL);
Wayne Roberts 0:abb827c65ff5 254
Wayne Roberts 0:abb827c65ff5 255 chipMode = CHIPMODE_NONE;
Wayne Roberts 0:abb827c65ff5 256 if (chipModeChange)
Wayne Roberts 0:abb827c65ff5 257 chipModeChange.call();
Wayne Roberts 0:abb827c65ff5 258 }
Wayne Roberts 0:abb827c65ff5 259
Wayne Roberts 2:8a442c3511ae 260 void SX128x::setSleep(bool warm)
Wayne Roberts 0:abb827c65ff5 261 {
Wayne Roberts 0:abb827c65ff5 262 sleepConfig_t sc;
Wayne Roberts 0:abb827c65ff5 263
Wayne Roberts 2:8a442c3511ae 264 if (warm) {
Wayne Roberts 2:8a442c3511ae 265 xfer(OPCODE_SAVE_CONTEXT, 0, 0, NULL);
Wayne Roberts 2:8a442c3511ae 266 }
Wayne Roberts 0:abb827c65ff5 267
Wayne Roberts 0:abb827c65ff5 268 chipMode = CHIPMODE_NONE;
Wayne Roberts 0:abb827c65ff5 269 if (chipModeChange)
Wayne Roberts 0:abb827c65ff5 270 chipModeChange.call();
Wayne Roberts 2:8a442c3511ae 271
Wayne Roberts 2:8a442c3511ae 272 sc.octet = 0;
Wayne Roberts 2:8a442c3511ae 273 sc.retentionBits.dataRAM = warm;
Wayne Roberts 2:8a442c3511ae 274 sc.retentionBits.dataBuffer = warm;
Wayne Roberts 2:8a442c3511ae 275 sc.retentionBits.instructionRAM = warm;
Wayne Roberts 2:8a442c3511ae 276 xfer(OPCODE_SET_SLEEP, 1, 0, &sc.octet);
Wayne Roberts 0:abb827c65ff5 277 }
Wayne Roberts 0:abb827c65ff5 278
Wayne Roberts 0:abb827c65ff5 279 uint8_t SX128x::getPacketType()
Wayne Roberts 0:abb827c65ff5 280 {
Wayne Roberts 0:abb827c65ff5 281 uint8_t buf[2];
Wayne Roberts 0:abb827c65ff5 282
Wayne Roberts 0:abb827c65ff5 283 xfer(OPCODE_GET_PACKET_TYPE, 0, 2, buf);
Wayne Roberts 2:8a442c3511ae 284 pktType = buf[1];
Wayne Roberts 0:abb827c65ff5 285
Wayne Roberts 0:abb827c65ff5 286 return buf[1];
Wayne Roberts 0:abb827c65ff5 287 }
Wayne Roberts 0:abb827c65ff5 288
Wayne Roberts 0:abb827c65ff5 289 void SX128x::setPacketType(uint8_t type)
Wayne Roberts 0:abb827c65ff5 290 {
Wayne Roberts 0:abb827c65ff5 291 xfer(OPCODE_SET_PACKET_TYPE, 1, 0, &type);
Wayne Roberts 2:8a442c3511ae 292 pktType = type;
Wayne Roberts 0:abb827c65ff5 293 }
Wayne Roberts 0:abb827c65ff5 294
Wayne Roberts 0:abb827c65ff5 295 void SX128x::setBufferBase(uint8_t txAddr, uint8_t rxAddr)
Wayne Roberts 0:abb827c65ff5 296 {
Wayne Roberts 0:abb827c65ff5 297 uint8_t buf[2];
Wayne Roberts 0:abb827c65ff5 298
Wayne Roberts 0:abb827c65ff5 299 buf[0] = txAddr; // TX base address
Wayne Roberts 0:abb827c65ff5 300 buf[1] = rxAddr; // RX base address
Wayne Roberts 0:abb827c65ff5 301 xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf);
Wayne Roberts 0:abb827c65ff5 302 }
Wayne Roberts 0:abb827c65ff5 303
Wayne Roberts 0:abb827c65ff5 304 void SX128x::setRegulator(uint8_t rmp)
Wayne Roberts 0:abb827c65ff5 305 {
Wayne Roberts 0:abb827c65ff5 306 xfer(OPCODE_SET_REGULATOR_MODE, 1, 0, &rmp);
Wayne Roberts 0:abb827c65ff5 307 }
Wayne Roberts 0:abb827c65ff5 308
Wayne Roberts 0:abb827c65ff5 309 void SX128x::start_rx(float timeout_ms)
Wayne Roberts 0:abb827c65ff5 310 {
Wayne Roberts 0:abb827c65ff5 311 IrqFlags_t irqEnable;
Wayne Roberts 0:abb827c65ff5 312 uint8_t buf[8];
Wayne Roberts 0:abb827c65ff5 313 unsigned t_o;
Wayne Roberts 0:abb827c65ff5 314
Wayne Roberts 0:abb827c65ff5 315 irqEnable.word = 0;
Wayne Roberts 0:abb827c65ff5 316 irqEnable.bits.RxDone = 1;
Wayne Roberts 0:abb827c65ff5 317 irqEnable.bits.RxTxTimeout = 1;
Wayne Roberts 0:abb827c65ff5 318
Wayne Roberts 0:abb827c65ff5 319 buf[0] = irqEnable.word >> 8; // enable bits
Wayne Roberts 0:abb827c65ff5 320 buf[1] = irqEnable.word; // enable bits
Wayne Roberts 0:abb827c65ff5 321 buf[2] = irqEnable.word >> 8; // dio1
Wayne Roberts 0:abb827c65ff5 322 buf[3] = irqEnable.word; // dio1
Wayne Roberts 0:abb827c65ff5 323 buf[4] = 0; // dio2
Wayne Roberts 0:abb827c65ff5 324 buf[5] = 0; // dio2
Wayne Roberts 0:abb827c65ff5 325 buf[6] = 0; // dio3
Wayne Roberts 0:abb827c65ff5 326 buf[7] = 0; // dio3
Wayne Roberts 0:abb827c65ff5 327 xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
Wayne Roberts 0:abb827c65ff5 328
Wayne Roberts 0:abb827c65ff5 329 buf[0] = periodBase;
Wayne Roberts 0:abb827c65ff5 330 if (timeout_ms > 0) {
Wayne Roberts 0:abb827c65ff5 331 t_o = timeout_ms / timeOutStep[periodBase];
Wayne Roberts 0:abb827c65ff5 332 buf[1] = t_o >> 8;
Wayne Roberts 0:abb827c65ff5 333 buf[2] = t_o;
Wayne Roberts 0:abb827c65ff5 334 } else {
Wayne Roberts 0:abb827c65ff5 335 /* receive packets forever */
Wayne Roberts 0:abb827c65ff5 336 buf[1] = 0xff;
Wayne Roberts 0:abb827c65ff5 337 buf[2] = 0xff;
Wayne Roberts 0:abb827c65ff5 338 }
Wayne Roberts 0:abb827c65ff5 339 xfer(OPCODE_SET_RX, 3, 0, buf);
Wayne Roberts 0:abb827c65ff5 340
Wayne Roberts 0:abb827c65ff5 341 chipMode = CHIPMODE_RX;
Wayne Roberts 0:abb827c65ff5 342 if (chipModeChange) {
Wayne Roberts 0:abb827c65ff5 343 chipModeChange.call();
Wayne Roberts 0:abb827c65ff5 344 }
Wayne Roberts 0:abb827c65ff5 345 }
Wayne Roberts 0:abb827c65ff5 346
Wayne Roberts 0:abb827c65ff5 347 void SX128x::service()
Wayne Roberts 0:abb827c65ff5 348 {
Wayne Roberts 0:abb827c65ff5 349 IrqFlags_t irqFlags, clearIrqFlags;
Wayne Roberts 0:abb827c65ff5 350 uint8_t buf[6];
Wayne Roberts 0:abb827c65ff5 351 pktStatus_t pktStatus;
Wayne Roberts 2:8a442c3511ae 352 //status_t st;
Wayne Roberts 0:abb827c65ff5 353
Wayne Roberts 0:abb827c65ff5 354 if (busy) {
Wayne Roberts 0:abb827c65ff5 355 return;
Wayne Roberts 0:abb827c65ff5 356 }
Wayne Roberts 0:abb827c65ff5 357
Wayne Roberts 0:abb827c65ff5 358 while (diox) {
Wayne Roberts 0:abb827c65ff5 359 xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf);
Wayne Roberts 2:8a442c3511ae 360 /*st.octet = buf[0]; */
Wayne Roberts 0:abb827c65ff5 361 irqFlags.word = buf[1] << 8;
Wayne Roberts 0:abb827c65ff5 362 irqFlags.word |= buf[2];
Wayne Roberts 0:abb827c65ff5 363 clearIrqFlags.word = 0;
Wayne Roberts 0:abb827c65ff5 364 if (irqFlags.bits.TxDone) {
Wayne Roberts 0:abb827c65ff5 365 chipMode = CHIPMODE_NONE;
Wayne Roberts 0:abb827c65ff5 366 if (chipModeChange)
Wayne Roberts 0:abb827c65ff5 367 chipModeChange.call();
Wayne Roberts 2:8a442c3511ae 368 if (txDone)
Wayne Roberts 2:8a442c3511ae 369 txDone.call(); // might change to Rx
Wayne Roberts 2:8a442c3511ae 370 clearIrqFlags.bits.TxDone = 1;
Wayne Roberts 0:abb827c65ff5 371 }
Wayne Roberts 0:abb827c65ff5 372 if (irqFlags.bits.RxDone) {
Wayne Roberts 0:abb827c65ff5 373 if (rxDone) {
Wayne Roberts 2:8a442c3511ae 374 uint8_t len, slen;
Wayne Roberts 0:abb827c65ff5 375 xfer(OPCODE_GET_RX_BUFFER_STATUS, 0, 3, buf);
Wayne Roberts 2:8a442c3511ae 376 /*st.octet = buf[0]; */
Wayne Roberts 0:abb827c65ff5 377 if (buf[1] == 0)
Wayne Roberts 0:abb827c65ff5 378 len = readReg(REG_ADDR_LORA_TX_PAYLOAD_LENGTH, 1); // lora implicit
Wayne Roberts 0:abb827c65ff5 379 else
Wayne Roberts 0:abb827c65ff5 380 len = buf[1];
Wayne Roberts 0:abb827c65ff5 381
Wayne Roberts 0:abb827c65ff5 382 ReadBuffer(len, buf[2]);
Wayne Roberts 2:8a442c3511ae 383
Wayne Roberts 4:ac55132283cb 384 if (pktType == PACKET_TYPE_LORA || pktType == PACKET_TYPE_RANGING) {
Wayne Roberts 2:8a442c3511ae 385 slen = 3;
Wayne Roberts 4:ac55132283cb 386 pktStatus.buf[3] = 0;
Wayne Roberts 4:ac55132283cb 387 pktStatus.buf[4] = 0;
Wayne Roberts 4:ac55132283cb 388 pktStatus.buf[5] = 0;
Wayne Roberts 4:ac55132283cb 389 } else
Wayne Roberts 2:8a442c3511ae 390 slen = 6;
Wayne Roberts 2:8a442c3511ae 391
Wayne Roberts 2:8a442c3511ae 392 xfer(OPCODE_GET_PACKET_STATUS, 0, slen, pktStatus.buf);
Wayne Roberts 0:abb827c65ff5 393 rxDone(len, &pktStatus);
Wayne Roberts 0:abb827c65ff5 394 }
Wayne Roberts 2:8a442c3511ae 395
Wayne Roberts 0:abb827c65ff5 396 clearIrqFlags.bits.RxDone = 1;
Wayne Roberts 0:abb827c65ff5 397 }
Wayne Roberts 0:abb827c65ff5 398 if (irqFlags.bits.RxTxTimeout) {
Wayne Roberts 0:abb827c65ff5 399 if (chipMode != CHIPMODE_NONE) {
Wayne Roberts 0:abb827c65ff5 400 if (timeout)
Wayne Roberts 0:abb827c65ff5 401 timeout(chipMode == CHIPMODE_TX);
Wayne Roberts 0:abb827c65ff5 402 }
Wayne Roberts 0:abb827c65ff5 403 chipMode = CHIPMODE_NONE;
Wayne Roberts 0:abb827c65ff5 404 if (chipModeChange)
Wayne Roberts 0:abb827c65ff5 405 chipModeChange.call();
Wayne Roberts 0:abb827c65ff5 406 clearIrqFlags.bits.RxTxTimeout = 1;
Wayne Roberts 0:abb827c65ff5 407 }
Wayne Roberts 0:abb827c65ff5 408
Wayne Roberts 5:aba2d8b29702 409 if (irqFlags.bits.CadDone) {
Wayne Roberts 5:aba2d8b29702 410 if (cadDone)
Wayne Roberts 5:aba2d8b29702 411 cadDone(irqFlags.bits.CadDetected );
Wayne Roberts 5:aba2d8b29702 412
Wayne Roberts 5:aba2d8b29702 413 clearIrqFlags.bits.CadDone = 1;
Wayne Roberts 5:aba2d8b29702 414 clearIrqFlags.bits.CadDetected = irqFlags.bits.CadDetected;
Wayne Roberts 5:aba2d8b29702 415 }
Wayne Roberts 5:aba2d8b29702 416
Wayne Roberts 0:abb827c65ff5 417 if (clearIrqFlags.word != 0) {
Wayne Roberts 0:abb827c65ff5 418 buf[0] = clearIrqFlags.word >> 8;
Wayne Roberts 0:abb827c65ff5 419 buf[1] = (uint8_t)clearIrqFlags.word;
Wayne Roberts 0:abb827c65ff5 420 xfer(OPCODE_CLEAR_IRQ_STATUS, 2, 0, buf);
Wayne Roberts 0:abb827c65ff5 421 }
Wayne Roberts 0:abb827c65ff5 422
Wayne Roberts 0:abb827c65ff5 423 } // ...while (diox)
Wayne Roberts 0:abb827c65ff5 424
Wayne Roberts 0:abb827c65ff5 425 } // ..service()
Wayne Roberts 0:abb827c65ff5 426
Wayne Roberts 0:abb827c65ff5 427 void SX128x::writeReg(uint16_t addr, uint32_t data, uint8_t len)
Wayne Roberts 0:abb827c65ff5 428 {
Wayne Roberts 0:abb827c65ff5 429 uint8_t buf[6];
Wayne Roberts 0:abb827c65ff5 430 uint8_t n;
Wayne Roberts 0:abb827c65ff5 431 buf[0] = addr >> 8;
Wayne Roberts 0:abb827c65ff5 432 buf[1] = (uint8_t)addr;
Wayne Roberts 0:abb827c65ff5 433 for (n = len; n > 0; n--) {
Wayne Roberts 0:abb827c65ff5 434 buf[n+1] = (uint8_t)data;
Wayne Roberts 0:abb827c65ff5 435 data >>= 8;
Wayne Roberts 0:abb827c65ff5 436 }
Wayne Roberts 0:abb827c65ff5 437 xfer(OPCODE_WRITE_REGISTER, 2+len, 2+len, buf);
Wayne Roberts 0:abb827c65ff5 438 }
Wayne Roberts 0:abb827c65ff5 439
Wayne Roberts 0:abb827c65ff5 440 void SX128x::ReadBuffer(uint8_t size, uint8_t offset)
Wayne Roberts 0:abb827c65ff5 441 {
Wayne Roberts 2:8a442c3511ae 442 //status_t st;
Wayne Roberts 0:abb827c65ff5 443 unsigned i;
Wayne Roberts 2:8a442c3511ae 444
Wayne Roberts 0:abb827c65ff5 445 while (busy)
Wayne Roberts 0:abb827c65ff5 446 ;
Wayne Roberts 0:abb827c65ff5 447
Wayne Roberts 0:abb827c65ff5 448 nss = 0;
Wayne Roberts 0:abb827c65ff5 449
Wayne Roberts 2:8a442c3511ae 450 /*st.octet =*/ spi.write(OPCODE_READ_BUFFER);
Wayne Roberts 2:8a442c3511ae 451 /*st.octet =*/ spi.write(offset);
Wayne Roberts 2:8a442c3511ae 452 /*st.octet =*/ spi.write(0); // NOP
Wayne Roberts 0:abb827c65ff5 453 i = 0;
Wayne Roberts 0:abb827c65ff5 454 for (i = 0; i < size; i++) {
Wayne Roberts 0:abb827c65ff5 455 rx_buf[i] = spi.write(0);
Wayne Roberts 0:abb827c65ff5 456 }
Wayne Roberts 0:abb827c65ff5 457
Wayne Roberts 0:abb827c65ff5 458 nss = 1;
Wayne Roberts 0:abb827c65ff5 459 }
Wayne Roberts 0:abb827c65ff5 460