sx1261/2 driver
Dependents: alarm_slave iq_sx126x sx126x_simple_TX_shield_2020a sx126x_simple_RX_shield_2020a ... more
sx126x.cpp
00001 #include "sx12xx.h" 00002 00003 Callback<void()> SX126x::dio1_topHalf; // low latency ISR context 00004 00005 void SX126x::dio1isr() 00006 { 00007 if (dio1_topHalf) 00008 dio1_topHalf.call(); 00009 } 00010 00011 SX126x::SX126x(SPI& _spi, PinName _nss, PinName _busy, PinName _dio1) 00012 : spi(_spi), nss(_nss), busy(_busy), dio1(_dio1) 00013 { 00014 uint8_t buf[8]; 00015 IrqFlags_t irqEnable; 00016 00017 nss = 1; 00018 00019 dio1.rise(dio1isr); 00020 00021 00022 irqEnable.word = 0; 00023 irqEnable.bits.TxDone = 1; 00024 irqEnable.bits.RxDone = 1; 00025 irqEnable.bits.Timeout = 1; 00026 00027 buf[0] = irqEnable.word >> 8; // enable bits 00028 buf[1] = irqEnable.word; // enable bits 00029 buf[2] = irqEnable.word >> 8; // dio1 00030 buf[3] = irqEnable.word; // dio1 00031 buf[4] = 0; // dio2 00032 buf[5] = 0; // dio2 00033 buf[6] = 0; // dio3 00034 buf[7] = 0; // dio3 00035 xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf); 00036 00037 } 00038 00039 void SX126x::PrintChipStatus(status_t status) 00040 { 00041 printf("%02x cmdStatus:", status.octet); 00042 switch (status.bits.cmdStatus) { 00043 case 0: printf("Reserved"); break; 00044 case 1: printf("RFU"); break; 00045 case 2: printf("dataAvail"); break; 00046 case 3: printf("cmdTimeout"); break; 00047 case 4: printf("cmdError"); break; 00048 case 5: printf("execFail"); break; 00049 case 6: printf("cmdTxDone"); break; 00050 } 00051 printf(" chipMode:"); 00052 switch (status.bits.chipMode) { 00053 case 0: printf("Unused"); break; 00054 case 1: printf("RFU"); break; 00055 case 2: printf("STBY_RC"); break; 00056 case 3: printf("STBY_XOSC"); break; 00057 case 4: printf("FS"); break; 00058 case 5: printf("RX"); break; 00059 case 6: printf("TX"); break; 00060 } 00061 printf("\r\n"); 00062 } 00063 00064 void SX126x::service() 00065 { 00066 IrqFlags_t irqFlags, clearIrqFlags; 00067 uint8_t buf[4]; 00068 00069 if (busy) { 00070 return; 00071 } 00072 00073 while (dio1) { 00074 xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf); 00075 irqFlags.word = buf[1] << 8; 00076 irqFlags.word |= buf[2]; 00077 clearIrqFlags.word = 0; 00078 if (irqFlags.bits.TxDone) { 00079 chipMode = CHIPMODE_NONE; 00080 if (chipModeChange) 00081 chipModeChange.call(); // might change to Rx 00082 if (txDone) 00083 txDone.call(); 00084 clearIrqFlags.bits.TxDone = 1; 00085 } 00086 if (irqFlags.bits.RxDone) { 00087 if (rxDone) { 00088 uint8_t len; 00089 float snr, rssi; 00090 int8_t s; 00091 xfer(OPCODE_GET_RX_BUFFER_STATUS, 0, 3, buf); 00092 len = buf[1]; 00093 ReadBuffer(len, buf[2]); 00094 xfer(OPCODE_GET_PACKET_STATUS, 0, 4, buf); 00095 rssi = -buf[1] / 2.0; // TODO FSK 00096 s = buf[2]; 00097 snr = s / 4.0; 00098 rxDone(len, rssi, snr); 00099 } 00100 clearIrqFlags.bits.RxDone = 1; 00101 } 00102 if (irqFlags.bits.Timeout) { 00103 if (chipMode != CHIPMODE_NONE) { 00104 if (timeout) 00105 timeout(chipMode == CHIPMODE_TX); 00106 } 00107 chipMode = CHIPMODE_NONE; 00108 if (chipModeChange) 00109 chipModeChange.call(); 00110 clearIrqFlags.bits.Timeout = 1; 00111 } 00112 if (irqFlags.bits.CadDone) { 00113 if (cadDone) 00114 cadDone(irqFlags.bits.CadDetected); 00115 00116 clearIrqFlags.bits.CadDone = 1; 00117 clearIrqFlags.bits.CadDetected = irqFlags.bits.CadDetected; 00118 } 00119 if (irqFlags.bits.PreambleDetected) { 00120 clearIrqFlags.bits.PreambleDetected = 1; 00121 if (preambleDetected) 00122 preambleDetected(); 00123 } 00124 00125 if (clearIrqFlags.word != 0) { 00126 buf[0] = clearIrqFlags.word >> 8; 00127 buf[1] = (uint8_t)clearIrqFlags.word; 00128 xfer(OPCODE_CLEAR_IRQ_STATUS, 2, 0, buf); 00129 } 00130 00131 } // ...while (dio1) 00132 00133 } // ..service() 00134 00135 void SX126x::xfer(uint8_t opcode, uint8_t wlen, uint8_t rlen, uint8_t* ptr) 00136 { 00137 const uint8_t* stopPtr; 00138 const uint8_t* wstop; 00139 const uint8_t* rstop; 00140 uint8_t nop = 0; 00141 00142 if (sleeping) { 00143 nss = 0; 00144 while (busy) 00145 ; 00146 sleeping = false; 00147 } else { 00148 while (busy) 00149 ; 00150 nss = 0; 00151 } 00152 00153 spi.write(opcode); 00154 00155 wstop = ptr + wlen; 00156 rstop = ptr + rlen; 00157 if (rlen > wlen) 00158 stopPtr = rstop; 00159 else 00160 stopPtr = wstop; 00161 00162 for (; ptr < stopPtr; ptr++) { 00163 if (ptr < wstop && ptr < rstop) 00164 *ptr = spi.write(*ptr); 00165 else if (ptr < wstop) 00166 spi.write(*ptr); 00167 else 00168 *ptr = spi.write(nop); // n >= write length: send NOP 00169 } 00170 00171 nss = 1; 00172 00173 if (opcode == OPCODE_SET_SLEEP) 00174 sleeping = true; 00175 } 00176 00177 void SX126x::start_tx(uint8_t pktLen) 00178 { 00179 uint8_t buf[8]; 00180 00181 { 00182 uint8_t i; 00183 00184 while (busy) 00185 ; 00186 00187 nss = 0; 00188 spi.write(OPCODE_WRITE_BUFFER); 00189 spi.write(0); // offset 00190 i = 0; 00191 for (i = 0; i < pktLen; i++) { 00192 spi.write(tx_buf[i]); 00193 } 00194 nss = 1; 00195 } 00196 00197 buf[0] = 0x40; 00198 buf[1] = 0x00; 00199 buf[2] = 0x00; 00200 xfer(OPCODE_SET_TX, 3, 0, buf); 00201 00202 chipMode = CHIPMODE_TX; 00203 if (chipModeChange) 00204 chipModeChange.call(); 00205 } 00206 00207 void SX126x::start_rx(unsigned timeout) 00208 { 00209 uint8_t buf[8]; 00210 00211 buf[0] = timeout >> 16; 00212 buf[1] = timeout >> 8; 00213 buf[2] = timeout; 00214 xfer(OPCODE_SET_RX, 3, 0, buf); 00215 00216 chipMode = CHIPMODE_RX; 00217 if (chipModeChange) 00218 chipModeChange.call(); 00219 } 00220 00221 uint8_t SX126x::setMHz(float MHz) 00222 { 00223 unsigned frf = MHz * MHZ_TO_FRF; 00224 uint8_t buf[4]; 00225 00226 buf[0] = frf >> 24; 00227 buf[1] = frf >> 16; 00228 buf[2] = frf >> 8; 00229 buf[3] = frf; 00230 xfer(OPCODE_SET_RF_FREQUENCY, 4, 0, buf); 00231 return buf[3]; 00232 } 00233 00234 float SX126x::getMHz() 00235 { 00236 uint32_t frf = readReg(REG_ADDR_RFFREQ, 4); 00237 return frf / (float)MHZ_TO_FRF; 00238 } 00239 00240 void SX126x::setPacketType(uint8_t type) 00241 { 00242 xfer(OPCODE_SET_PACKET_TYPE, 1, 0, &type); 00243 } 00244 00245 uint8_t SX126x::getPacketType() 00246 { 00247 uint8_t buf[2]; 00248 xfer(OPCODE_GET_PACKET_TYPE, 0, 2, buf); 00249 return buf[1]; 00250 } 00251 00252 void SX126x::SetDIO2AsRfSwitchCtrl(uint8_t en) 00253 { 00254 xfer(OPCODE_SET_DIO2_AS_RFSWITCH, 1, 0, &en); 00255 } 00256 00257 void SX126x::ReadBuffer(uint8_t size, uint8_t offset) 00258 { 00259 unsigned i; 00260 while (busy) 00261 ; 00262 00263 nss = 0; 00264 00265 spi.write(OPCODE_READ_BUFFER); 00266 spi.write(offset); 00267 spi.write(0); // NOP 00268 i = 0; 00269 for (i = 0; i < size; i++) { 00270 rx_buf[i] = spi.write(0); 00271 } 00272 00273 nss = 1; 00274 } 00275 00276 void SX126x::set_tx_dbm(bool is1262, int8_t dbm) 00277 { 00278 uint8_t buf[4]; 00279 // use OCP default 00280 00281 buf[3] = 1; 00282 if (is1262) { 00283 buf[0] = 4; 00284 buf[1] = 7; 00285 buf[2] = 0; 00286 00287 if (dbm > 22) 00288 dbm = 22; 00289 else if (dbm < -3) 00290 dbm = -3; 00291 } else { 00292 if (dbm == 15) 00293 buf[0] = 6; 00294 else 00295 buf[0] = 4; 00296 buf[1] = 0; 00297 buf[2] = 1; 00298 00299 if (dbm > 14) 00300 dbm = 14; 00301 else if (dbm < -3) 00302 dbm = -3; 00303 } 00304 xfer(OPCODE_SET_PA_CONFIG, 4, 0, buf); 00305 00306 if (is1262 && dbm > 18) { 00307 /* OCP is set by chip whenever SetPaConfig() is called */ 00308 writeReg(REG_ADDR_OCP, 0x38, 1); 00309 } 00310 00311 // SetTxParams 00312 buf[0] = dbm; 00313 //if (opt == 0) txco 00314 buf[1] = SET_RAMP_200U; 00315 xfer(OPCODE_SET_TX_PARAMS, 2, 0, buf); 00316 } 00317 00318 void SX126x::writeReg(uint16_t addr, uint32_t data, uint8_t len) 00319 { 00320 uint8_t buf[6]; 00321 uint8_t n; 00322 buf[0] = addr >> 8; 00323 buf[1] = (uint8_t)addr; 00324 for (n = len; n > 0; n--) { 00325 buf[n+1] = (uint8_t)data; 00326 data >>= 8; 00327 } 00328 xfer(OPCODE_WRITE_REGISTER, 2+len, 2+len, buf); 00329 } 00330 00331 void SX126x::setStandby(stby_t stby) 00332 { 00333 uint8_t octet = stby; 00334 xfer(OPCODE_SET_STANDBY, 1, 0, &octet); 00335 00336 chipMode = CHIPMODE_NONE; 00337 if (chipModeChange) 00338 chipModeChange.call(); 00339 } 00340 00341 void SX126x::setFS() 00342 { 00343 xfer(OPCODE_SET_FS, 0, 0, NULL); 00344 00345 chipMode = CHIPMODE_NONE; 00346 if (chipModeChange) 00347 chipModeChange.call(); 00348 } 00349 00350 void SX126x::setCAD() 00351 { 00352 xfer(OPCODE_SET_CAD, 0, 0, NULL); 00353 00354 chipMode = CHIPMODE_RX; 00355 if (chipModeChange) 00356 chipModeChange.call(); 00357 } 00358 00359 void SX126x::setSleep(bool warmStart, bool rtcWakeup) 00360 { 00361 sleepConfig_t sc; 00362 00363 sc.octet = 0; 00364 sc.bits.rtcWakeup = rtcWakeup; 00365 sc.bits.warmStart = warmStart; 00366 xfer(OPCODE_SET_SLEEP, 1, 0, &sc.octet); 00367 00368 chipMode = CHIPMODE_NONE; 00369 if (chipModeChange) 00370 chipModeChange.call(); 00371 } 00372 00373 void SX126x::hw_reset(PinName pin) 00374 { 00375 DigitalInOut nrst(pin); 00376 nrst.output(); 00377 nrst = 0; 00378 #if (MBED_MAJOR_VERSION < 6) 00379 ThisThread::sleep_for(1); 00380 #else 00381 ThisThread::sleep_for(1ms); 00382 #endif 00383 nrst = 1; 00384 nrst.mode(PullUp); 00385 nrst.input(); 00386 00387 while (busy) 00388 ; 00389 } 00390 00391 uint32_t SX126x::readReg(uint16_t addr, uint8_t len) 00392 { 00393 uint32_t ret = 0; 00394 unsigned i; 00395 00396 uint8_t buf[7]; 00397 buf[0] = addr >> 8; 00398 buf[1] = (uint8_t)addr; 00399 xfer(OPCODE_READ_REGISTER, 2, 3+len, buf); 00400 for (i = 0; i < len; i++) { 00401 ret <<= 8; 00402 ret |= buf[i+3]; 00403 } 00404 return ret; 00405 } 00406 00407 void SX126x::setBufferBase(uint8_t txAddr, uint8_t rxAddr) 00408 { 00409 uint8_t buf[2]; 00410 00411 buf[0] = 0; // TX base address 00412 buf[1] = 0; // RX base address 00413 xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf); 00414 }
Generated on Thu Jul 14 2022 14:41:34 by 1.7.2