driver for sx1280
Dependents: alarm_slave_extended_SX1280 alarm_master_extended_Vance_SX1280
sx1280.cpp
00001 #include "sx12xx.h" 00002 00003 Callback<void()> SX128x::diox_topHalf; // low latency ISR context 00004 00005 const float SX128x::timeOutStep[] = { 0.015625, 0.0625, 1, 4 }; 00006 00007 void SX128x::dioxisr() 00008 { 00009 if (diox_topHalf) 00010 diox_topHalf.call(); 00011 } 00012 00013 SX128x::SX128x(SPI& _spi, PinName _nss, PinName _busy, PinName _diox, PinName _nrst) 00014 : spi(_spi), nss(_nss), busy(_busy), diox(_diox), nrst(_nrst) 00015 { 00016 unsigned busyCnt = 0; 00017 nss = 1; 00018 00019 while (busy) { 00020 if (++busyCnt > 0x80000) { 00021 hw_reset(); 00022 } 00023 } 00024 00025 periodBase = 3; 00026 00027 diox.rise(dioxisr); 00028 } 00029 00030 uint8_t SX128x::xfer(uint8_t opcode, uint8_t wlen, uint8_t rlen, uint8_t* ptr) 00031 { 00032 const uint8_t* stopPtr; 00033 const uint8_t* wstop; 00034 const uint8_t* rstop; 00035 uint8_t nop = 0; 00036 uint8_t ret; 00037 00038 if (opcode != OPCODE_GET_STATUS) { 00039 if (sleeping) { 00040 nss = 0; 00041 while (busy) 00042 ; 00043 sleeping = false; 00044 } else { 00045 while (busy) 00046 ; 00047 00048 nss = 0; 00049 } 00050 } else 00051 nss = 0; 00052 00053 ret = spi.write(opcode); 00054 00055 wstop = ptr + wlen; 00056 rstop = ptr + rlen; 00057 if (rlen > wlen) 00058 stopPtr = rstop; 00059 else 00060 stopPtr = wstop; 00061 00062 for (; ptr < stopPtr; ptr++) { 00063 if (ptr < wstop && ptr < rstop) 00064 *ptr = spi.write(*ptr); 00065 else if (ptr < wstop) 00066 spi.write(*ptr); 00067 else 00068 *ptr = spi.write(nop); // n >= write length: send NOP 00069 } 00070 00071 nss = 1; 00072 00073 if (opcode == OPCODE_SET_SLEEP) 00074 sleeping = true; 00075 00076 return ret; 00077 } 00078 00079 uint32_t SX128x::readReg(uint16_t addr, uint8_t len) 00080 { 00081 uint32_t ret = 0; 00082 unsigned i; 00083 00084 uint8_t buf[7]; 00085 buf[0] = addr >> 8; 00086 buf[1] = (uint8_t)addr; 00087 xfer(OPCODE_READ_REGISTER, 2, 3+len, buf); 00088 for (i = 0; i < len; i++) { 00089 ret <<= 8; 00090 ret |= buf[i+3]; 00091 } 00092 return ret; 00093 } 00094 00095 void SX128x::start_tx(uint8_t pktLen, float timeout_ms) 00096 { 00097 IrqFlags_t irqEnable; 00098 uint8_t buf[8]; 00099 00100 irqEnable.word = 0; 00101 irqEnable.bits.TxDone = 1; 00102 irqEnable.bits.RxTxTimeout = 1; 00103 00104 buf[0] = irqEnable.word >> 8; // enable bits 00105 buf[1] = irqEnable.word; // enable bits 00106 buf[2] = irqEnable.word >> 8; // dio1 00107 buf[3] = irqEnable.word; // dio1 00108 buf[4] = 0; // dio2 00109 buf[5] = 0; // dio2 00110 buf[6] = 0; // dio3 00111 buf[7] = 0; // dio3 00112 xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf); 00113 00114 { 00115 uint8_t i; 00116 00117 while (busy) 00118 ; 00119 00120 nss = 0; 00121 spi.write(OPCODE_WRITE_BUFFER); 00122 spi.write(0); // offset 00123 i = 0; 00124 for (i = 0; i < pktLen; i++) { 00125 spi.write(tx_buf[i]); 00126 } 00127 nss = 1; 00128 } 00129 00130 buf[0] = periodBase; 00131 if (timeout_ms > 0) { 00132 unsigned t_o = timeout_ms / timeOutStep[periodBase]; 00133 buf[1] = t_o >> 8; 00134 buf[2] = t_o; 00135 } else { 00136 /* no timeout */ 00137 buf[1] = 0; 00138 buf[2] = 0; 00139 } 00140 xfer(OPCODE_SET_TX, 3, 0, buf); 00141 00142 chipMode = CHIPMODE_TX; 00143 if (chipModeChange) 00144 chipModeChange.call(); 00145 } 00146 00147 void SX128x::hw_reset() 00148 { 00149 nrst.output(); 00150 nrst = 0; 00151 #if (MBED_MAJOR_VERSION < 6) 00152 ThisThread::sleep_for(1); 00153 #else 00154 ThisThread::sleep_for(1ms); 00155 #endif 00156 nrst = 1; 00157 nrst.mode(PullUp); 00158 nrst.input(); 00159 00160 while (busy) 00161 ; 00162 } 00163 00164 uint64_t SX128x::getSyncAddr(uint8_t num) 00165 { 00166 uint64_t ret; 00167 unsigned regAdr = REG_ADDR_PKT_SYNC_ADRS_1 + ((num-1) * 5); 00168 ret = readReg(regAdr, 1); 00169 ret <<= 32; 00170 ret |= readReg(regAdr+1, 4); 00171 return ret; 00172 } 00173 00174 void SX128x::setSyncAddr(uint8_t num, uint64_t sa) 00175 { 00176 unsigned regAdr = REG_ADDR_PKT_SYNC_ADRS_1 + ((num-1) * 5); 00177 writeReg(regAdr+1, sa & 0xffffffff, 4); 00178 sa >>= 32; 00179 writeReg(regAdr, sa & 0xff, 1); 00180 } 00181 00182 void SX128x::set_tx_dbm(int8_t dbm) 00183 { 00184 uint8_t buf[2]; 00185 00186 buf[0] = dbm; 00187 buf[1] = RADIO_RAMP_20_US; 00188 xfer(OPCODE_SET_TX_PARAMS, 2, 0, buf); 00189 } 00190 00191 void SX128x::setMHz(float MHz) 00192 { 00193 unsigned frf = MHz / PLL_STEP_MHZ; 00194 uint8_t buf[3]; 00195 00196 buf[0] = frf >> 16; 00197 buf[1] = frf >> 8; 00198 buf[2] = frf; 00199 xfer(OPCODE_SET_RF_FREQUENCY, 3, 0, buf); 00200 } 00201 00202 float SX128x::getMHz() 00203 { 00204 uint32_t frf; 00205 if (pktType == PACKET_TYPE_LORA) 00206 frf = readReg(REG_ADDR_LORA_SD_FREQ, 3); 00207 else 00208 frf = readReg(REG_ADDR_RFFREQ, 3); 00209 00210 return frf * PLL_STEP_MHZ; 00211 } 00212 00213 void SX128x::setStandby(stby_t stby) 00214 { 00215 uint8_t octet = stby; 00216 xfer(OPCODE_SET_STANDBY, 1, 0, &octet); 00217 00218 chipMode = CHIPMODE_NONE; 00219 if (chipModeChange) 00220 chipModeChange.call(); 00221 } 00222 00223 void SX128x::setCAD() 00224 { 00225 IrqFlags_t irqEnable; 00226 uint8_t buf[8]; 00227 00228 irqEnable.word = 0; 00229 irqEnable.bits.CadDone = 1; 00230 irqEnable.bits.CadDetected = 1; 00231 irqEnable.bits.RxDone = 1; 00232 irqEnable.bits.RxTxTimeout = 1; 00233 00234 buf[0] = irqEnable.word >> 8; // enable bits 00235 buf[1] = irqEnable.word; // enable bits 00236 buf[2] = irqEnable.word >> 8; // dio1 00237 buf[3] = irqEnable.word; // dio1 00238 buf[4] = 0; // dio2 00239 buf[5] = 0; // dio2 00240 buf[6] = 0; // dio3 00241 buf[7] = 0; // dio3 00242 xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf); 00243 00244 xfer(OPCODE_SET_CAD, 0, 0, NULL); 00245 00246 chipMode = CHIPMODE_RX; 00247 if (chipModeChange) 00248 chipModeChange.call(); 00249 } 00250 00251 void SX128x::setFS() 00252 { 00253 xfer(OPCODE_SET_FS, 0, 0, NULL); 00254 00255 chipMode = CHIPMODE_NONE; 00256 if (chipModeChange) 00257 chipModeChange.call(); 00258 } 00259 00260 void SX128x::setSleep(bool warm) 00261 { 00262 sleepConfig_t sc; 00263 00264 if (warm) { 00265 xfer(OPCODE_SAVE_CONTEXT, 0, 0, NULL); 00266 } 00267 00268 chipMode = CHIPMODE_NONE; 00269 if (chipModeChange) 00270 chipModeChange.call(); 00271 00272 sc.octet = 0; 00273 sc.retentionBits.dataRAM = warm; 00274 sc.retentionBits.dataBuffer = warm; 00275 sc.retentionBits.instructionRAM = warm; 00276 xfer(OPCODE_SET_SLEEP, 1, 0, &sc.octet); 00277 } 00278 00279 uint8_t SX128x::getPacketType() 00280 { 00281 uint8_t buf[2]; 00282 00283 xfer(OPCODE_GET_PACKET_TYPE, 0, 2, buf); 00284 pktType = buf[1]; 00285 00286 return buf[1]; 00287 } 00288 00289 void SX128x::setPacketType(uint8_t type) 00290 { 00291 xfer(OPCODE_SET_PACKET_TYPE, 1, 0, &type); 00292 pktType = type; 00293 } 00294 00295 void SX128x::setBufferBase(uint8_t txAddr, uint8_t rxAddr) 00296 { 00297 uint8_t buf[2]; 00298 00299 buf[0] = txAddr; // TX base address 00300 buf[1] = rxAddr; // RX base address 00301 xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf); 00302 } 00303 00304 void SX128x::setRegulator(uint8_t rmp) 00305 { 00306 xfer(OPCODE_SET_REGULATOR_MODE, 1, 0, &rmp); 00307 } 00308 00309 void SX128x::start_rx(float timeout_ms) 00310 { 00311 IrqFlags_t irqEnable; 00312 uint8_t buf[8]; 00313 unsigned t_o; 00314 00315 irqEnable.word = 0; 00316 irqEnable.bits.RxDone = 1; 00317 irqEnable.bits.RxTxTimeout = 1; 00318 00319 buf[0] = irqEnable.word >> 8; // enable bits 00320 buf[1] = irqEnable.word; // enable bits 00321 buf[2] = irqEnable.word >> 8; // dio1 00322 buf[3] = irqEnable.word; // dio1 00323 buf[4] = 0; // dio2 00324 buf[5] = 0; // dio2 00325 buf[6] = 0; // dio3 00326 buf[7] = 0; // dio3 00327 xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf); 00328 00329 buf[0] = periodBase; 00330 if (timeout_ms > 0) { 00331 t_o = timeout_ms / timeOutStep[periodBase]; 00332 buf[1] = t_o >> 8; 00333 buf[2] = t_o; 00334 } else { 00335 /* receive packets forever */ 00336 buf[1] = 0xff; 00337 buf[2] = 0xff; 00338 } 00339 xfer(OPCODE_SET_RX, 3, 0, buf); 00340 00341 chipMode = CHIPMODE_RX; 00342 if (chipModeChange) { 00343 chipModeChange.call(); 00344 } 00345 } 00346 00347 void SX128x::service() 00348 { 00349 IrqFlags_t irqFlags, clearIrqFlags; 00350 uint8_t buf[6]; 00351 pktStatus_t pktStatus; 00352 //status_t st; 00353 00354 if (busy) { 00355 return; 00356 } 00357 00358 while (diox) { 00359 xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf); 00360 /*st.octet = buf[0]; */ 00361 irqFlags.word = buf[1] << 8; 00362 irqFlags.word |= buf[2]; 00363 clearIrqFlags.word = 0; 00364 if (irqFlags.bits.TxDone) { 00365 chipMode = CHIPMODE_NONE; 00366 if (chipModeChange) 00367 chipModeChange.call(); 00368 if (txDone) 00369 txDone.call(); // might change to Rx 00370 clearIrqFlags.bits.TxDone = 1; 00371 } 00372 if (irqFlags.bits.RxDone) { 00373 if (rxDone) { 00374 uint8_t len, slen; 00375 xfer(OPCODE_GET_RX_BUFFER_STATUS, 0, 3, buf); 00376 /*st.octet = buf[0]; */ 00377 if (buf[1] == 0) 00378 len = readReg(REG_ADDR_LORA_TX_PAYLOAD_LENGTH, 1); // lora implicit 00379 else 00380 len = buf[1]; 00381 00382 ReadBuffer(len, buf[2]); 00383 00384 if (pktType == PACKET_TYPE_LORA || pktType == PACKET_TYPE_RANGING) { 00385 slen = 3; 00386 pktStatus.buf[3] = 0; 00387 pktStatus.buf[4] = 0; 00388 pktStatus.buf[5] = 0; 00389 } else 00390 slen = 6; 00391 00392 xfer(OPCODE_GET_PACKET_STATUS, 0, slen, pktStatus.buf); 00393 rxDone(len, &pktStatus); 00394 } 00395 00396 clearIrqFlags.bits.RxDone = 1; 00397 } 00398 if (irqFlags.bits.RxTxTimeout) { 00399 if (chipMode != CHIPMODE_NONE) { 00400 if (timeout) 00401 timeout(chipMode == CHIPMODE_TX); 00402 } 00403 chipMode = CHIPMODE_NONE; 00404 if (chipModeChange) 00405 chipModeChange.call(); 00406 clearIrqFlags.bits.RxTxTimeout = 1; 00407 } 00408 00409 if (irqFlags.bits.CadDone) { 00410 if (cadDone) 00411 cadDone(irqFlags.bits.CadDetected ); 00412 00413 clearIrqFlags.bits.CadDone = 1; 00414 clearIrqFlags.bits.CadDetected = irqFlags.bits.CadDetected; 00415 } 00416 00417 if (clearIrqFlags.word != 0) { 00418 buf[0] = clearIrqFlags.word >> 8; 00419 buf[1] = (uint8_t)clearIrqFlags.word; 00420 xfer(OPCODE_CLEAR_IRQ_STATUS, 2, 0, buf); 00421 } 00422 00423 } // ...while (diox) 00424 00425 } // ..service() 00426 00427 void SX128x::writeReg(uint16_t addr, uint32_t data, uint8_t len) 00428 { 00429 uint8_t buf[6]; 00430 uint8_t n; 00431 buf[0] = addr >> 8; 00432 buf[1] = (uint8_t)addr; 00433 for (n = len; n > 0; n--) { 00434 buf[n+1] = (uint8_t)data; 00435 data >>= 8; 00436 } 00437 xfer(OPCODE_WRITE_REGISTER, 2+len, 2+len, buf); 00438 } 00439 00440 void SX128x::ReadBuffer(uint8_t size, uint8_t offset) 00441 { 00442 //status_t st; 00443 unsigned i; 00444 00445 while (busy) 00446 ; 00447 00448 nss = 0; 00449 00450 /*st.octet =*/ spi.write(OPCODE_READ_BUFFER); 00451 /*st.octet =*/ spi.write(offset); 00452 /*st.octet =*/ spi.write(0); // NOP 00453 i = 0; 00454 for (i = 0; i < size; i++) { 00455 rx_buf[i] = spi.write(0); 00456 } 00457 00458 nss = 1; 00459 } 00460
Generated on Sun Jul 17 2022 01:33:56 by 1.7.2