acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
CC1101.cpp (31059B)
1 #include "CC1101.h" 2 #if !defined(RADIOLIB_EXCLUDE_CC1101) 3 4 CC1101::CC1101(Module* module) : PhysicalLayer(RADIOLIB_CC1101_FREQUENCY_STEP_SIZE, RADIOLIB_CC1101_MAX_PACKET_LENGTH) { 5 _mod = module; 6 } 7 8 Module* CC1101::getMod() { 9 return(_mod); 10 } 11 12 int16_t CC1101::begin(float freq, float br, float freqDev, float rxBw, int8_t power, uint8_t preambleLength) { 13 // set module properties 14 _mod->SPIreadCommand = RADIOLIB_CC1101_CMD_READ; 15 _mod->SPIwriteCommand = RADIOLIB_CC1101_CMD_WRITE; 16 _mod->init(); 17 _mod->pinMode(_mod->getIrq(), INPUT); 18 19 // try to find the CC1101 chip 20 uint8_t i = 0; 21 bool flagFound = false; 22 while((i < 10) && !flagFound) { 23 int16_t version = getChipVersion(); 24 if((version == RADIOLIB_CC1101_VERSION_CURRENT) || (version == RADIOLIB_CC1101_VERSION_LEGACY) || (version == RADIOLIB_CC1101_VERSION_CLONE)) { 25 flagFound = true; 26 } else { 27 #if defined(RADIOLIB_DEBUG) 28 RADIOLIB_DEBUG_PRINT(F("CC1101 not found! (")); 29 RADIOLIB_DEBUG_PRINT(i + 1); 30 RADIOLIB_DEBUG_PRINT(F(" of 10 tries) RADIOLIB_CC1101_REG_VERSION == ")); 31 32 char buffHex[7]; 33 sprintf(buffHex, "0x%04X", version); 34 RADIOLIB_DEBUG_PRINT(buffHex); 35 RADIOLIB_DEBUG_PRINT(F(", expected 0x0004/0x0014")); 36 RADIOLIB_DEBUG_PRINTLN(); 37 #endif 38 _mod->delay(10); 39 i++; 40 } 41 } 42 43 if(!flagFound) { 44 RADIOLIB_DEBUG_PRINTLN(F("No CC1101 found!")); 45 _mod->term(); 46 return(RADIOLIB_ERR_CHIP_NOT_FOUND); 47 } else { 48 RADIOLIB_DEBUG_PRINTLN(F("M\tCC1101")); 49 } 50 51 // configure settings not accessible by API 52 int16_t state = config(); 53 RADIOLIB_ASSERT(state); 54 55 // configure publicly accessible settings 56 state = setFrequency(freq); 57 RADIOLIB_ASSERT(state); 58 59 // configure bitrate 60 state = setBitRate(br); 61 RADIOLIB_ASSERT(state); 62 63 // configure default RX bandwidth 64 state = setRxBandwidth(rxBw); 65 RADIOLIB_ASSERT(state); 66 67 // configure default frequency deviation 68 state = setFrequencyDeviation(freqDev); 69 RADIOLIB_ASSERT(state); 70 71 // configure default TX output power 72 state = setOutputPower(power); 73 RADIOLIB_ASSERT(state); 74 75 // set default packet length mode 76 state = variablePacketLengthMode(); 77 RADIOLIB_ASSERT(state); 78 79 // configure default preamble length 80 state = setPreambleLength(preambleLength); 81 RADIOLIB_ASSERT(state); 82 83 // set default data shaping 84 state = setDataShaping(RADIOLIB_SHAPING_NONE); 85 RADIOLIB_ASSERT(state); 86 87 // set default encoding 88 state = setEncoding(RADIOLIB_ENCODING_NRZ); 89 RADIOLIB_ASSERT(state); 90 91 // set default sync word 92 state = setSyncWord(0x12, 0xAD, 0, false); 93 RADIOLIB_ASSERT(state); 94 95 // flush FIFOs 96 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); 97 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); 98 99 return(state); 100 } 101 102 int16_t CC1101::transmit(uint8_t* data, size_t len, uint8_t addr) { 103 // calculate timeout (5ms + 500 % of expected time-on-air) 104 uint32_t timeout = 5000000 + (uint32_t)((((float)(len * 8)) / (_br * 1000.0)) * 5000000.0); 105 106 // start transmission 107 int16_t state = startTransmit(data, len, addr); 108 RADIOLIB_ASSERT(state); 109 110 // wait for transmission start or timeout 111 uint32_t start = _mod->micros(); 112 while(!_mod->digitalRead(_mod->getIrq())) { 113 _mod->yield(); 114 115 if(_mod->micros() - start > timeout) { 116 standby(); 117 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); 118 return(RADIOLIB_ERR_TX_TIMEOUT); 119 } 120 } 121 122 // wait for transmission end or timeout 123 start = _mod->micros(); 124 while(_mod->digitalRead(_mod->getIrq())) { 125 _mod->yield(); 126 127 if(_mod->micros() - start > timeout) { 128 standby(); 129 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); 130 return(RADIOLIB_ERR_TX_TIMEOUT); 131 } 132 } 133 134 // set mode to standby 135 standby(); 136 137 // flush Tx FIFO 138 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); 139 140 return(state); 141 } 142 143 int16_t CC1101::receive(uint8_t* data, size_t len) { 144 // calculate timeout (500 ms + 400 full max-length packets at current bit rate) 145 uint32_t timeout = 500000 + (1.0/(_br*1000.0))*(RADIOLIB_CC1101_MAX_PACKET_LENGTH*400.0); 146 147 // start reception 148 int16_t state = startReceive(); 149 RADIOLIB_ASSERT(state); 150 151 // wait for packet or timeout 152 uint32_t start = _mod->micros(); 153 while(!_mod->digitalRead(_mod->getIrq())) { 154 _mod->yield(); 155 156 if(_mod->micros() - start > timeout) { 157 standby(); 158 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); 159 return(RADIOLIB_ERR_RX_TIMEOUT); 160 } 161 } 162 163 // read packet data 164 return(readData(data, len)); 165 } 166 167 int16_t CC1101::standby() { 168 // set idle mode 169 SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); 170 171 // set RF switch (if present) 172 _mod->setRfSwitchState(LOW, LOW); 173 return(RADIOLIB_ERR_NONE); 174 } 175 176 int16_t CC1101::transmitDirect(uint32_t frf) { 177 return transmitDirect(true, frf); 178 } 179 180 int16_t CC1101::transmitDirectAsync(uint32_t frf) { 181 return transmitDirect(false, frf); 182 } 183 184 int16_t CC1101::transmitDirect(bool sync, uint32_t frf) { 185 // set RF switch (if present) 186 _mod->setRfSwitchState(LOW, HIGH); 187 188 // user requested to start transmitting immediately (required for RTTY) 189 if(frf != 0) { 190 SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ2, (frf & 0xFF0000) >> 16); 191 SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ1, (frf & 0x00FF00) >> 8); 192 SPIwriteRegister(RADIOLIB_CC1101_REG_FREQ0, frf & 0x0000FF); 193 194 SPIsendCommand(RADIOLIB_CC1101_CMD_TX); 195 } 196 197 // activate direct mode 198 int16_t state = directMode(sync); 199 RADIOLIB_ASSERT(state); 200 201 // start transmitting 202 SPIsendCommand(RADIOLIB_CC1101_CMD_TX); 203 return(state); 204 } 205 206 int16_t CC1101::receiveDirect() { 207 return receiveDirect(true); 208 } 209 210 int16_t CC1101::receiveDirectAsync() { 211 return receiveDirect(false); 212 } 213 214 int16_t CC1101::receiveDirect(bool sync) { 215 // set RF switch (if present) 216 _mod->setRfSwitchState(HIGH, LOW); 217 218 // activate direct mode 219 int16_t state = directMode(sync); 220 RADIOLIB_ASSERT(state); 221 222 // start receiving 223 SPIsendCommand(RADIOLIB_CC1101_CMD_RX); 224 return(RADIOLIB_ERR_NONE); 225 } 226 227 int16_t CC1101::packetMode() { 228 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, RADIOLIB_CC1101_CRC_AUTOFLUSH_OFF | RADIOLIB_CC1101_APPEND_STATUS_ON | RADIOLIB_CC1101_ADR_CHK_NONE, 3, 0); 229 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_WHITE_DATA_OFF | RADIOLIB_CC1101_PKT_FORMAT_NORMAL, 6, 4); 230 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_CRC_ON | _packetLengthConfig, 2, 0); 231 return(state); 232 } 233 234 void CC1101::setGdo0Action(void (*func)(void), RADIOLIB_INTERRUPT_STATUS dir) { 235 _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getIrq()), func, dir); 236 } 237 238 void CC1101::clearGdo0Action() { 239 _mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getIrq())); 240 } 241 242 void CC1101::setGdo2Action(void (*func)(void), RADIOLIB_INTERRUPT_STATUS dir) { 243 if(_mod->getGpio() != RADIOLIB_NC) { 244 return; 245 } 246 _mod->pinMode(_mod->getGpio(), INPUT); 247 _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()), func, dir); 248 } 249 250 void CC1101::clearGdo2Action() { 251 if(_mod->getGpio() != RADIOLIB_NC) { 252 return; 253 } 254 _mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio())); 255 } 256 257 int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) { 258 // check packet length 259 if(len > RADIOLIB_CC1101_MAX_PACKET_LENGTH) { 260 return(RADIOLIB_ERR_PACKET_TOO_LONG); 261 } 262 263 // set mode to standby 264 standby(); 265 266 // flush Tx FIFO 267 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); 268 269 // set GDO0 mapping 270 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED); 271 RADIOLIB_ASSERT(state); 272 273 // data put on FIFO. 274 uint8_t dataSent = 0; 275 276 // optionally write packet length 277 if (_packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) { 278 279 // enforce variable len limit. 280 if (len > RADIOLIB_CC1101_MAX_PACKET_LENGTH - 1) { 281 return (RADIOLIB_ERR_PACKET_TOO_LONG); 282 } 283 284 SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, len); 285 dataSent += 1; 286 } 287 288 // check address filtering 289 uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0); 290 if(filter != RADIOLIB_CC1101_ADR_CHK_NONE) { 291 SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, addr); 292 dataSent += 1; 293 } 294 295 // fill the FIFO. 296 uint8_t initialWrite = min((uint8_t)len, (uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - dataSent)); 297 SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, data, initialWrite); 298 dataSent += initialWrite; 299 300 // set RF switch (if present) 301 _mod->setRfSwitchState(LOW, HIGH); 302 303 // set mode to transmit 304 SPIsendCommand(RADIOLIB_CC1101_CMD_TX); 305 306 // keep feeding the FIFO until the packet is over. 307 while (dataSent < len) { 308 // get number of bytes in FIFO. 309 uint8_t bytesInFIFO = SPIgetRegValue(RADIOLIB_CC1101_REG_TXBYTES, 6, 0); 310 311 // if there's room then put other data. 312 if (bytesInFIFO < RADIOLIB_CC1101_FIFO_SIZE) { 313 uint8_t bytesToWrite = min((uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - bytesInFIFO), (uint8_t)(len - dataSent)); 314 SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, &data[dataSent], bytesToWrite); 315 dataSent += bytesToWrite; 316 } else { 317 // wait for radio to send some data. 318 /* 319 * Does this work for all rates? If 1 ms is longer than the 1ms delay 320 * then the entire FIFO will be transmitted during that delay. 321 * 322 * TODO: test this on real hardware 323 */ 324 delayMicroseconds(250); 325 } 326 } 327 328 return (state); 329 } 330 331 int16_t CC1101::startReceive() { 332 // set mode to standby 333 standby(); 334 335 // flush Rx FIFO 336 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); 337 338 // set GDO0 mapping: Asserted when RX FIFO > 4 bytes. 339 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_RX_FIFO_FULL_OR_PKT_END); 340 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FIFOTHR, RADIOLIB_CC1101_FIFO_THR_TX_61_RX_4, 3, 0); 341 RADIOLIB_ASSERT(state); 342 343 // set RF switch (if present) 344 _mod->setRfSwitchState(HIGH, LOW); 345 346 // set mode to receive 347 SPIsendCommand(RADIOLIB_CC1101_CMD_RX); 348 349 return(state); 350 } 351 352 int16_t CC1101::readData(uint8_t* data, size_t len) { 353 // get packet length 354 size_t length = getPacketLength(); 355 if((len != 0) && (len < length)) { 356 // user requested less data than we got, only return what was requested 357 length = len; 358 } 359 360 // check address filtering 361 uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0); 362 if(filter != RADIOLIB_CC1101_ADR_CHK_NONE) { 363 SPIreadRegister(RADIOLIB_CC1101_REG_FIFO); 364 } 365 366 uint8_t bytesInFIFO = SPIgetRegValue(RADIOLIB_CC1101_REG_RXBYTES, 6, 0); 367 size_t readBytes = 0; 368 uint32_t lastPop = millis(); 369 370 // keep reading from FIFO until we get all the packet. 371 while (readBytes < length) { 372 if (bytesInFIFO == 0) { 373 if (millis() - lastPop > 5) { 374 // readData was required to read a packet longer than the one received. 375 RADIOLIB_DEBUG_PRINTLN(F("No data for more than 5mS. Stop here.")); 376 break; 377 } else { 378 delay(1); 379 bytesInFIFO = SPIgetRegValue(RADIOLIB_CC1101_REG_RXBYTES, 6, 0); 380 continue; 381 } 382 } 383 384 // read the minimum between "remaining length" and bytesInFifo 385 uint8_t bytesToRead = min((uint8_t)(length - readBytes), bytesInFIFO); 386 SPIreadRegisterBurst(RADIOLIB_CC1101_REG_FIFO, bytesToRead, &(data[readBytes])); 387 readBytes += bytesToRead; 388 lastPop = millis(); 389 390 // Get how many bytes are left in FIFO. 391 bytesInFIFO = SPIgetRegValue(RADIOLIB_CC1101_REG_RXBYTES, 6, 0); 392 } 393 394 // check if status bytes are enabled (default: RADIOLIB_CC1101_APPEND_STATUS_ON) 395 bool isAppendStatus = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 2, 2) == RADIOLIB_CC1101_APPEND_STATUS_ON; 396 397 // for some reason, we need this delay here to get the correct status bytes 398 delay(3); 399 400 // If status byte is enabled at least 2 bytes (2 status bytes + any following packet) will remain in FIFO. 401 if (isAppendStatus) { 402 // read RSSI byte 403 _rawRSSI = SPIgetRegValue(RADIOLIB_CC1101_REG_FIFO); 404 405 // read LQI and CRC byte 406 uint8_t val = SPIgetRegValue(RADIOLIB_CC1101_REG_FIFO); 407 _rawLQI = val & 0x7F; 408 409 // check CRC 410 if (_crcOn && (val & RADIOLIB_CC1101_CRC_OK) == RADIOLIB_CC1101_CRC_ERROR) { 411 _packetLengthQueried = false; 412 return (RADIOLIB_ERR_CRC_MISMATCH); 413 } 414 } 415 416 // clear internal flag so getPacketLength can return the new packet length 417 _packetLengthQueried = false; 418 419 // Flush then standby according to RXOFF_MODE (default: RADIOLIB_CC1101_RXOFF_IDLE) 420 if (SPIgetRegValue(RADIOLIB_CC1101_REG_MCSM1, 3, 2) == RADIOLIB_CC1101_RXOFF_IDLE) { 421 422 // flush Rx FIFO 423 SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); 424 425 // set mode to standby 426 standby(); 427 } 428 429 return(RADIOLIB_ERR_NONE); 430 } 431 432 int16_t CC1101::setFrequency(float freq) { 433 // check allowed frequency range 434 if(!(((freq > 300.0) && (freq < 348.0)) || 435 ((freq > 387.0) && (freq < 464.0)) || 436 ((freq > 779.0) && (freq < 928.0)))) { 437 return(RADIOLIB_ERR_INVALID_FREQUENCY); 438 } 439 440 // set mode to standby 441 SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); 442 443 //set carrier frequency 444 uint32_t base = 1; 445 uint32_t FRF = (freq * (base << 16)) / 26.0; 446 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ2, (FRF & 0xFF0000) >> 16, 7, 0); 447 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ1, (FRF & 0x00FF00) >> 8, 7, 0); 448 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FREQ0, FRF & 0x0000FF, 7, 0); 449 450 if(state == RADIOLIB_ERR_NONE) { 451 _freq = freq; 452 } 453 454 // Update the TX power accordingly to new freq. (PA values depend on chosen freq) 455 return(setOutputPower(_power)); 456 } 457 458 int16_t CC1101::setBitRate(float br) { 459 RADIOLIB_CHECK_RANGE(br, 0.025, 600.0, RADIOLIB_ERR_INVALID_BIT_RATE); 460 461 // set mode to standby 462 SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); 463 464 // calculate exponent and mantissa values 465 uint8_t e = 0; 466 uint8_t m = 0; 467 getExpMant(br * 1000.0, 256, 28, 14, e, m); 468 469 // set bit rate value 470 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, e, 3, 0); 471 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG3, m); 472 if(state == RADIOLIB_ERR_NONE) { 473 CC1101::_br = br; 474 } 475 return(state); 476 } 477 478 int16_t CC1101::setRxBandwidth(float rxBw) { 479 RADIOLIB_CHECK_RANGE(rxBw, 58.0, 812.0, RADIOLIB_ERR_INVALID_RX_BANDWIDTH); 480 481 // set mode to standby 482 SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); 483 484 // calculate exponent and mantissa values 485 for(int8_t e = 3; e >= 0; e--) { 486 for(int8_t m = 3; m >= 0; m --) { 487 float point = (RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0)/(8 * (m + 4) * ((uint32_t)1 << e)); 488 if(fabs((rxBw * 1000.0) - point) <= 1000) { 489 // set Rx channel filter bandwidth 490 return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG4, (e << 6) | (m << 4), 7, 4)); 491 } 492 } 493 } 494 495 return(RADIOLIB_ERR_INVALID_RX_BANDWIDTH); 496 } 497 498 int16_t CC1101::setFrequencyDeviation(float freqDev) { 499 // set frequency deviation to lowest available setting (required for digimodes) 500 float newFreqDev = freqDev; 501 if(freqDev < 0.0) { 502 newFreqDev = 1.587; 503 } 504 505 RADIOLIB_CHECK_RANGE(newFreqDev, 1.587, 380.8, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION); 506 507 // set mode to standby 508 SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); 509 510 // calculate exponent and mantissa values 511 uint8_t e = 0; 512 uint8_t m = 0; 513 getExpMant(newFreqDev * 1000.0, 8, 17, 7, e, m); 514 515 // set frequency deviation value 516 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_DEVIATN, (e << 4), 6, 4); 517 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_DEVIATN, m, 2, 0); 518 return(state); 519 } 520 521 int16_t CC1101::setOutputPower(int8_t power) { 522 // round to the known frequency settings 523 uint8_t f; 524 if(_freq < 374.0) { 525 // 315 MHz 526 f = 0; 527 } else if(_freq < 650.5) { 528 // 434 MHz 529 f = 1; 530 } else if(_freq < 891.5) { 531 // 868 MHz 532 f = 2; 533 } else { 534 // 915 MHz 535 f = 3; 536 } 537 538 // get raw power setting 539 uint8_t paTable[8][4] = {{0x12, 0x12, 0x03, 0x03}, 540 {0x0D, 0x0E, 0x0F, 0x0E}, 541 {0x1C, 0x1D, 0x1E, 0x1E}, 542 {0x34, 0x34, 0x27, 0x27}, 543 {0x51, 0x60, 0x50, 0x8E}, 544 {0x85, 0x84, 0x81, 0xCD}, 545 {0xCB, 0xC8, 0xCB, 0xC7}, 546 {0xC2, 0xC0, 0xC2, 0xC0}}; 547 548 uint8_t powerRaw; 549 switch(power) { 550 case -30: 551 powerRaw = paTable[0][f]; 552 break; 553 case -20: 554 powerRaw = paTable[1][f]; 555 break; 556 case -15: 557 powerRaw = paTable[2][f]; 558 break; 559 case -10: 560 powerRaw = paTable[3][f]; 561 break; 562 case 0: 563 powerRaw = paTable[4][f]; 564 break; 565 case 5: 566 powerRaw = paTable[5][f]; 567 break; 568 case 7: 569 powerRaw = paTable[6][f]; 570 break; 571 case 10: 572 powerRaw = paTable[7][f]; 573 break; 574 default: 575 return(RADIOLIB_ERR_INVALID_OUTPUT_POWER); 576 } 577 578 // store the value 579 _power = power; 580 581 if(_modulation == RADIOLIB_CC1101_MOD_FORMAT_ASK_OOK){ 582 // Amplitude modulation: 583 // PA_TABLE[0] is the power to be used when transmitting a 0 (no power) 584 // PA_TABLE[1] is the power to be used when transmitting a 1 (full power) 585 586 uint8_t paValues[2] = {0x00, powerRaw}; 587 SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_PATABLE, paValues, 2); 588 return(RADIOLIB_ERR_NONE); 589 590 } else { 591 // Freq modulation: 592 // PA_TABLE[0] is the power to be used when transmitting. 593 return(SPIsetRegValue(RADIOLIB_CC1101_REG_PATABLE, powerRaw)); 594 } 595 } 596 597 int16_t CC1101::setSyncWord(uint8_t* syncWord, uint8_t len, uint8_t maxErrBits, bool requireCarrierSense) { 598 if((maxErrBits > 1) || (len != 2)) { 599 return(RADIOLIB_ERR_INVALID_SYNC_WORD); 600 } 601 602 // sync word must not contain value 0x00 603 for(uint8_t i = 0; i < len; i++) { 604 if(syncWord[i] == 0x00) { 605 return(RADIOLIB_ERR_INVALID_SYNC_WORD); 606 } 607 } 608 609 _syncWordLength = len; 610 611 // enable sync word filtering 612 int16_t state = enableSyncWordFiltering(maxErrBits, requireCarrierSense); 613 RADIOLIB_ASSERT(state); 614 615 // set sync word register 616 state = SPIsetRegValue(RADIOLIB_CC1101_REG_SYNC1, syncWord[0]); 617 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_SYNC0, syncWord[1]); 618 619 return(state); 620 } 621 622 int16_t CC1101::setSyncWord(uint8_t syncH, uint8_t syncL, uint8_t maxErrBits, bool requireCarrierSense) { 623 uint8_t syncWord[] = { syncH, syncL }; 624 return(setSyncWord(syncWord, sizeof(syncWord), maxErrBits, requireCarrierSense)); 625 } 626 627 int16_t CC1101::setPreambleLength(uint8_t preambleLength) { 628 // check allowed values 629 uint8_t value; 630 switch(preambleLength){ 631 case 16: 632 value = RADIOLIB_CC1101_NUM_PREAMBLE_2; 633 break; 634 case 24: 635 value = RADIOLIB_CC1101_NUM_PREAMBLE_3; 636 break; 637 case 32: 638 value = RADIOLIB_CC1101_NUM_PREAMBLE_4; 639 break; 640 case 48: 641 value = RADIOLIB_CC1101_NUM_PREAMBLE_6; 642 break; 643 case 64: 644 value = RADIOLIB_CC1101_NUM_PREAMBLE_8; 645 break; 646 case 96: 647 value = RADIOLIB_CC1101_NUM_PREAMBLE_12; 648 break; 649 case 128: 650 value = RADIOLIB_CC1101_NUM_PREAMBLE_16; 651 break; 652 case 192: 653 value = RADIOLIB_CC1101_NUM_PREAMBLE_24; 654 break; 655 default: 656 return(RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH); 657 } 658 659 660 return SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG1, value, 6, 4); 661 } 662 663 664 int16_t CC1101::setNodeAddress(uint8_t nodeAddr, uint8_t numBroadcastAddrs) { 665 RADIOLIB_CHECK_RANGE(numBroadcastAddrs, 1, 2, RADIOLIB_ERR_INVALID_NUM_BROAD_ADDRS); 666 667 // enable address filtering 668 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, numBroadcastAddrs + 0x01, 1, 0); 669 RADIOLIB_ASSERT(state); 670 671 // set node address 672 return(SPIsetRegValue(RADIOLIB_CC1101_REG_ADDR, nodeAddr)); 673 } 674 675 int16_t CC1101::disableAddressFiltering() { 676 // disable address filtering 677 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, RADIOLIB_CC1101_ADR_CHK_NONE, 1, 0); 678 RADIOLIB_ASSERT(state); 679 680 // set node address to default (0x00) 681 return(SPIsetRegValue(RADIOLIB_CC1101_REG_ADDR, 0x00)); 682 } 683 684 685 int16_t CC1101::setOOK(bool enableOOK) { 686 // Change modulation 687 if(enableOOK) { 688 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_ASK_OOK, 6, 4); 689 RADIOLIB_ASSERT(state); 690 691 // PA_TABLE[0] is (by default) the power value used when transmitting a "0". 692 // Set PA_TABLE[1] to be used when transmitting a "1". 693 state = SPIsetRegValue(RADIOLIB_CC1101_REG_FREND0, 1, 2, 0); 694 RADIOLIB_ASSERT(state); 695 696 // update current modulation 697 _modulation = RADIOLIB_CC1101_MOD_FORMAT_ASK_OOK; 698 } else { 699 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_2_FSK, 6, 4); 700 RADIOLIB_ASSERT(state); 701 702 // Reset FREND0 to default value. 703 state = SPIsetRegValue(RADIOLIB_CC1101_REG_FREND0, 0, 2, 0); 704 RADIOLIB_ASSERT(state); 705 706 // update current modulation 707 _modulation = RADIOLIB_CC1101_MOD_FORMAT_2_FSK; 708 } 709 710 // Update PA_TABLE values according to the new _modulation. 711 return(setOutputPower(_power)); 712 } 713 714 float CC1101::getRSSI() { 715 float rssi; 716 717 if (_directMode) { 718 if(_rawRSSI >= 128) { 719 rssi = (((float)_rawRSSI - 256.0)/2.0) - 74.0; 720 } else { 721 rssi = (((float)_rawRSSI)/2.0) - 74.0; 722 } 723 } else { 724 uint8_t rawRssi = SPIreadRegister(RADIOLIB_CC1101_REG_RSSI); 725 if (rawRssi >= 128) 726 { 727 rssi = ((rawRssi - 256) / 2) - 74; 728 } 729 else 730 { 731 rssi = (rawRssi / 2) - 74; 732 } 733 } 734 return(rssi); 735 } 736 737 uint8_t CC1101::getLQI() const { 738 return(_rawLQI); 739 } 740 741 size_t CC1101::getPacketLength(bool update) { 742 if(!_packetLengthQueried && update) { 743 if (_packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) { 744 _packetLength = SPIreadRegister(RADIOLIB_CC1101_REG_FIFO); 745 } else { 746 _packetLength = SPIreadRegister(RADIOLIB_CC1101_REG_PKTLEN); 747 } 748 749 _packetLengthQueried = true; 750 } 751 752 return(_packetLength); 753 } 754 755 int16_t CC1101::fixedPacketLengthMode(uint8_t len) { 756 return(setPacketMode(RADIOLIB_CC1101_LENGTH_CONFIG_FIXED, len)); 757 } 758 759 int16_t CC1101::variablePacketLengthMode(uint8_t maxLen) { 760 return(setPacketMode(RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE, maxLen)); 761 } 762 763 int16_t CC1101::enableSyncWordFiltering(uint8_t maxErrBits, bool requireCarrierSense) { 764 switch(maxErrBits){ 765 case 0: 766 // in 16 bit sync word, expect all 16 bits 767 return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, (requireCarrierSense ? RADIOLIB_CC1101_SYNC_MODE_16_16_THR : RADIOLIB_CC1101_SYNC_MODE_16_16), 2, 0)); 768 case 1: 769 // in 16 bit sync word, expect at least 15 bits 770 return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, (requireCarrierSense ? RADIOLIB_CC1101_SYNC_MODE_15_16_THR : RADIOLIB_CC1101_SYNC_MODE_15_16), 2, 0)); 771 default: 772 return(RADIOLIB_ERR_INVALID_SYNC_WORD); 773 } 774 } 775 776 int16_t CC1101::disableSyncWordFiltering(bool requireCarrierSense) { 777 return(SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, (requireCarrierSense ? RADIOLIB_CC1101_SYNC_MODE_NONE_THR : RADIOLIB_CC1101_SYNC_MODE_NONE), 2, 0)); 778 } 779 780 int16_t CC1101::setCrcFiltering(bool crcOn) { 781 _crcOn = crcOn; 782 783 if (crcOn == true) { 784 return(SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_CRC_ON, 2, 2)); 785 } else { 786 return(SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_CRC_OFF, 2, 2)); 787 } 788 } 789 790 int16_t CC1101::setPromiscuousMode(bool promiscuous) { 791 int16_t state = RADIOLIB_ERR_NONE; 792 793 if (_promiscuous == promiscuous) { 794 return(state); 795 } 796 797 if (promiscuous == true) { 798 // disable preamble and sync word filtering and insertion 799 state = disableSyncWordFiltering(); 800 RADIOLIB_ASSERT(state); 801 802 // disable CRC filtering 803 state = setCrcFiltering(false); 804 } else { 805 // enable preamble and sync word filtering and insertion 806 state = enableSyncWordFiltering(); 807 RADIOLIB_ASSERT(state); 808 809 // enable CRC filtering 810 state = setCrcFiltering(true); 811 } 812 813 _promiscuous = promiscuous; 814 815 return(state); 816 } 817 818 bool CC1101::getPromiscuousMode() { 819 return (_promiscuous); 820 } 821 822 int16_t CC1101::setDataShaping(uint8_t sh) { 823 // set mode to standby 824 int16_t state = standby(); 825 RADIOLIB_ASSERT(state); 826 827 // set data shaping 828 switch(sh) { 829 case RADIOLIB_SHAPING_NONE: 830 state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_2_FSK, 6, 4); 831 break; 832 case RADIOLIB_SHAPING_0_5: 833 state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MOD_FORMAT_GFSK, 6, 4); 834 break; 835 default: 836 return(RADIOLIB_ERR_INVALID_DATA_SHAPING); 837 } 838 return(state); 839 } 840 841 int16_t CC1101::setEncoding(uint8_t encoding) { 842 // set mode to standby 843 int16_t state = standby(); 844 RADIOLIB_ASSERT(state); 845 846 // set encoding 847 switch(encoding) { 848 case RADIOLIB_ENCODING_NRZ: 849 state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MANCHESTER_EN_OFF, 3, 3); 850 RADIOLIB_ASSERT(state); 851 return(SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_WHITE_DATA_OFF, 6, 6)); 852 case RADIOLIB_ENCODING_MANCHESTER: 853 state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MANCHESTER_EN_ON, 3, 3); 854 RADIOLIB_ASSERT(state); 855 return(SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_WHITE_DATA_OFF, 6, 6)); 856 case RADIOLIB_ENCODING_WHITENING: 857 state = SPIsetRegValue(RADIOLIB_CC1101_REG_MDMCFG2, RADIOLIB_CC1101_MANCHESTER_EN_OFF, 3, 3); 858 RADIOLIB_ASSERT(state); 859 return(SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_WHITE_DATA_ON, 6, 6)); 860 default: 861 return(RADIOLIB_ERR_INVALID_ENCODING); 862 } 863 } 864 865 void CC1101::setRfSwitchPins(RADIOLIB_PIN_TYPE rxEn, RADIOLIB_PIN_TYPE txEn) { 866 _mod->setRfSwitchPins(rxEn, txEn); 867 } 868 869 uint8_t CC1101::randomByte() { 870 // set mode to Rx 871 SPIsendCommand(RADIOLIB_CC1101_CMD_RX); 872 RADIOLIB_DEBUG_PRINTLN("random"); 873 874 // wait a bit for the RSSI reading to stabilise 875 _mod->delay(10); 876 877 // read RSSI value 8 times, always keep just the least significant bit 878 uint8_t randByte = 0x00; 879 for(uint8_t i = 0; i < 8; i++) { 880 randByte |= ((SPIreadRegister(RADIOLIB_CC1101_REG_RSSI) & 0x01) << i); 881 } 882 883 // set mode to standby 884 SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); 885 886 return(randByte); 887 } 888 889 int16_t CC1101::getChipVersion() { 890 return(SPIgetRegValue(RADIOLIB_CC1101_REG_VERSION)); 891 } 892 893 #if !defined(RADIOLIB_EXCLUDE_DIRECT_RECEIVE) 894 void CC1101::setDirectAction(void (*func)(void)) { 895 setGdo0Action(func); 896 } 897 898 void CC1101::readBit(RADIOLIB_PIN_TYPE pin) { 899 updateDirectBuffer((uint8_t)digitalRead(pin)); 900 } 901 #endif 902 903 int16_t CC1101::setDIOMapping(RADIOLIB_PIN_TYPE pin, uint8_t value) { 904 if (pin > 2) 905 return RADIOLIB_ERR_INVALID_DIO_PIN; 906 907 return(SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0 - pin, value)); 908 } 909 910 int16_t CC1101::config() { 911 // Reset the radio. Registers may be dirty from previous usage. 912 SPIsendCommand(RADIOLIB_CC1101_CMD_RESET); 913 914 // Wait a ridiculous amount of time to be sure radio is ready. 915 _mod->delay(150); 916 917 // enable automatic frequency synthesizer calibration 918 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_MCSM0, RADIOLIB_CC1101_FS_AUTOCAL_IDLE_TO_RXTX, 5, 4); 919 RADIOLIB_ASSERT(state); 920 921 // set packet mode 922 state = packetMode(); 923 924 return(state); 925 } 926 927 int16_t CC1101::directMode(bool sync) { 928 // set mode to standby 929 SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); 930 931 int16_t state = 0; 932 _directMode = sync; 933 if (sync) { 934 // set GDO0 and GDO2 mapping 935 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SERIAL_CLOCK , 5, 0); 936 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_SERIAL_DATA_SYNC , 5, 0); 937 938 // set continuous mode 939 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_PKT_FORMAT_SYNCHRONOUS, 5, 4); 940 } 941 else { 942 // set GDO0 mapping 943 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SERIAL_DATA_ASYNC , 5, 0); 944 945 // set asynchronous continuous mode 946 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_PKT_FORMAT_ASYNCHRONOUS, 5, 4); 947 } 948 949 state |= SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, RADIOLIB_CC1101_LENGTH_CONFIG_INFINITE, 1, 0); 950 return(state); 951 } 952 953 void CC1101::getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant) { 954 // get table origin point (exp = 0, mant = 0) 955 float origin = (mantOffset * RADIOLIB_CC1101_CRYSTAL_FREQ * 1000000.0)/((uint32_t)1 << divExp); 956 957 // iterate over possible exponent values 958 for(int8_t e = expMax; e >= 0; e--) { 959 // get table column start value (exp = e, mant = 0); 960 float intervalStart = ((uint32_t)1 << e) * origin; 961 962 // check if target value is in this column 963 if(target >= intervalStart) { 964 // save exponent value 965 exp = e; 966 967 // calculate size of step between table rows 968 float stepSize = intervalStart/(float)mantOffset; 969 970 // get target point position (exp = e, mant = m) 971 mant = ((target - intervalStart) / stepSize); 972 973 // we only need the first match, terminate 974 return; 975 } 976 } 977 } 978 979 int16_t CC1101::setPacketMode(uint8_t mode, uint16_t len) { 980 // check length 981 if (len > RADIOLIB_CC1101_MAX_PACKET_LENGTH) { 982 return(RADIOLIB_ERR_PACKET_TOO_LONG); 983 } 984 985 // set PKTCTRL0.LENGTH_CONFIG 986 int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_PKTCTRL0, mode, 1, 0); 987 RADIOLIB_ASSERT(state); 988 989 // set length to register 990 state = SPIsetRegValue(RADIOLIB_CC1101_REG_PKTLEN, len); 991 RADIOLIB_ASSERT(state); 992 993 // update the cached value 994 _packetLength = len; 995 _packetLengthConfig = mode; 996 return(state); 997 } 998 999 int16_t CC1101::SPIgetRegValue(uint8_t reg, uint8_t msb, uint8_t lsb) { 1000 // status registers require special command 1001 if(reg > RADIOLIB_CC1101_REG_TEST0) { 1002 reg |= RADIOLIB_CC1101_CMD_ACCESS_STATUS_REG; 1003 } 1004 1005 return(_mod->SPIgetRegValue(reg, msb, lsb)); 1006 } 1007 1008 int16_t CC1101::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval) { 1009 // status registers require special command 1010 if(reg > RADIOLIB_CC1101_REG_TEST0) { 1011 reg |= RADIOLIB_CC1101_CMD_ACCESS_STATUS_REG; 1012 } 1013 1014 return(_mod->SPIsetRegValue(reg, value, msb, lsb, checkInterval)); 1015 } 1016 1017 void CC1101::SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes) { 1018 _mod->SPIreadRegisterBurst(reg | RADIOLIB_CC1101_CMD_BURST, numBytes, inBytes); 1019 } 1020 1021 uint8_t CC1101::SPIreadRegister(uint8_t reg) { 1022 // status registers require special command 1023 if(reg > RADIOLIB_CC1101_REG_TEST0) { 1024 reg |= RADIOLIB_CC1101_CMD_ACCESS_STATUS_REG; 1025 } 1026 1027 return(_mod->SPIreadRegister(reg)); 1028 } 1029 1030 void CC1101::SPIwriteRegister(uint8_t reg, uint8_t data) { 1031 // status registers require special command 1032 if(reg > RADIOLIB_CC1101_REG_TEST0) { 1033 reg |= RADIOLIB_CC1101_CMD_ACCESS_STATUS_REG; 1034 } 1035 1036 return(_mod->SPIwriteRegister(reg, data)); 1037 } 1038 1039 void CC1101::SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, size_t len) { 1040 _mod->SPIwriteRegisterBurst(reg | RADIOLIB_CC1101_CMD_BURST, data, len); 1041 } 1042 1043 void CC1101::SPIsendCommand(uint8_t cmd) { 1044 // pull NSS low 1045 _mod->digitalWrite(_mod->getCs(), LOW); 1046 1047 // start transfer 1048 _mod->SPIbeginTransaction(); 1049 1050 // send the command byte 1051 _mod->SPItransfer(cmd); 1052 1053 // stop transfer 1054 _mod->SPIendTransaction(); 1055 _mod->digitalWrite(_mod->getCs(), HIGH); 1056 } 1057 1058 #endif