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