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

PhysicalLayer.cpp (6136B)

      1 #include "PhysicalLayer.h"
      2 
      3 PhysicalLayer::PhysicalLayer(float freqStep, size_t maxPacketLength) {
      4   _freqStep = freqStep;
      5   _maxPacketLength = maxPacketLength;
      6   #if !defined(RADIOLIB_EXCLUDE_DIRECT_RECEIVE)
      7   _bufferBitPos = 0;
      8   _bufferWritePos = 0;
      9   #endif
     10 }
     11 
     12 int16_t PhysicalLayer::transmit(__FlashStringHelper* fstr, uint8_t addr) {
     13   // read flash string length
     14   size_t len = 0;
     15   PGM_P p = reinterpret_cast<PGM_P>(fstr);
     16   while(true) {
     17     char c = RADIOLIB_NONVOLATILE_READ_BYTE(p++);
     18     len++;
     19     if(c == '\0') {
     20       break;
     21     }
     22   }
     23 
     24   // dynamically allocate memory
     25   #if defined(RADIOLIB_STATIC_ONLY)
     26     char str[RADIOLIB_STATIC_ARRAY_SIZE];
     27   #else
     28     char* str = new char[len];
     29   #endif
     30 
     31   // copy string from flash
     32   p = reinterpret_cast<PGM_P>(fstr);
     33   for(size_t i = 0; i < len; i++) {
     34     str[i] = RADIOLIB_NONVOLATILE_READ_BYTE(p + i);
     35   }
     36 
     37   // transmit string
     38   int16_t state = transmit(str, addr);
     39   #if !defined(RADIOLIB_STATIC_ONLY)
     40     delete[] str;
     41   #endif
     42   return(state);
     43 }
     44 
     45 int16_t PhysicalLayer::transmit(String& str, uint8_t addr) {
     46   return(transmit(str.c_str(), addr));
     47 }
     48 
     49 int16_t PhysicalLayer::transmit(const char* str, uint8_t addr) {
     50   return(transmit((uint8_t*)str, strlen(str), addr));
     51 }
     52 
     53 int16_t PhysicalLayer::startTransmit(String& str, uint8_t addr) {
     54   return(startTransmit(str.c_str(), addr));
     55 }
     56 
     57 int16_t PhysicalLayer::startTransmit(const char* str, uint8_t addr) {
     58   return(startTransmit((uint8_t*)str, strlen(str), addr));
     59 }
     60 
     61 int16_t PhysicalLayer::readData(String& str, size_t len) {
     62   int16_t state = RADIOLIB_ERR_NONE;
     63 
     64   // read the number of actually received bytes
     65   size_t length = getPacketLength();
     66 
     67   if((len < length) && (len != 0)) {
     68     // user requested less bytes than were received, this is allowed (but frowned upon)
     69     // requests for more data than were received will only return the number of actually received bytes (unlike PhysicalLayer::receive())
     70     length = len;
     71   }
     72 
     73   // build a temporary buffer
     74   #if defined(RADIOLIB_STATIC_ONLY)
     75     uint8_t data[RADIOLIB_STATIC_ARRAY_SIZE + 1];
     76   #else
     77     uint8_t* data = new uint8_t[length + 1];
     78     if(!data) {
     79       return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
     80     }
     81   #endif
     82 
     83   // read the received data
     84   state = readData(data, length);
     85 
     86   if(state == RADIOLIB_ERR_NONE) {
     87     // add null terminator
     88     data[length] = 0;
     89 
     90     // initialize Arduino String class
     91     str = String((char*)data);
     92   }
     93 
     94   // deallocate temporary buffer
     95   #if !defined(RADIOLIB_STATIC_ONLY)
     96     delete[] data;
     97   #endif
     98 
     99   return(state);
    100 }
    101 
    102 int16_t PhysicalLayer::receive(String& str, size_t len) {
    103   int16_t state = RADIOLIB_ERR_NONE;
    104 
    105   // user can override the length of data to read
    106   size_t length = len;
    107 
    108   // build a temporary buffer
    109   #if defined(RADIOLIB_STATIC_ONLY)
    110     uint8_t data[RADIOLIB_STATIC_ARRAY_SIZE + 1];
    111   #else
    112     uint8_t* data = NULL;
    113     if(length == 0) {
    114       data = new uint8_t[_maxPacketLength + 1];
    115     } else {
    116       data = new uint8_t[length + 1];
    117     }
    118     if(!data) {
    119       return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
    120     }
    121   #endif
    122 
    123   // attempt packet reception
    124   state = receive(data, length);
    125 
    126   if(state == RADIOLIB_ERR_NONE) {
    127     // read the number of actually received bytes (for unknown packets)
    128     if(len == 0) {
    129       length = getPacketLength(false);
    130     }
    131 
    132     // add null terminator
    133     data[length] = 0;
    134 
    135     // initialize Arduino String class
    136     str = String((char*)data);
    137   }
    138 
    139   // deallocate temporary buffer
    140   #if !defined(RADIOLIB_STATIC_ONLY)
    141     delete[] data;
    142   #endif
    143 
    144   return(state);
    145 }
    146 
    147 float PhysicalLayer::getFreqStep() const {
    148   return(_freqStep);
    149 }
    150 
    151 int32_t PhysicalLayer::random(int32_t max) {
    152   if(max == 0) {
    153     return(0);
    154   }
    155 
    156   // get random bytes from the radio
    157   uint8_t randBuff[4];
    158   for(uint8_t i = 0; i < 4; i++) {
    159     randBuff[i] = randomByte();
    160   }
    161 
    162   // create 32-bit TRNG number
    163   int32_t randNum = ((int32_t)randBuff[0] << 24) | ((int32_t)randBuff[1] << 16) | ((int32_t)randBuff[2] << 8) | ((int32_t)randBuff[3]);
    164   if(randNum < 0) {
    165     randNum *= -1;
    166   }
    167   RADIOLIB_DEBUG_PRINTLN(randNum);
    168   return(randNum % max);
    169 }
    170 
    171 int32_t PhysicalLayer::random(int32_t min, int32_t max) {
    172   if(min >= max) {
    173     return(min);
    174   }
    175 
    176   return(PhysicalLayer::random(max - min) + min);
    177 }
    178 
    179 int16_t PhysicalLayer::startDirect() {
    180   // disable encodings
    181   int16_t state = setEncoding(RADIOLIB_ENCODING_NRZ);
    182   RADIOLIB_ASSERT(state);
    183 
    184   // disable shaping
    185   state = setDataShaping(RADIOLIB_SHAPING_NONE);
    186   RADIOLIB_ASSERT(state);
    187 
    188   // set frequency deviation to the lowest possible value
    189   state = setFrequencyDeviation(-1);
    190   return(state);
    191 }
    192 
    193 #if !defined(RADIOLIB_EXCLUDE_DIRECT_RECEIVE)
    194 int16_t PhysicalLayer::available() {
    195   return(_bufferWritePos);
    196 }
    197 
    198 uint8_t PhysicalLayer::read() {
    199   if(_directSyncWordLen > 0) {
    200     _gotSync = false;
    201     _syncBuffer = 0;
    202   }
    203   _bufferWritePos--;
    204   return(_buffer[_bufferReadPos++]);
    205 }
    206 
    207 int16_t PhysicalLayer::setDirectSyncWord(uint32_t syncWord, uint8_t len) {
    208   if(len > 32) {
    209     return(RADIOLIB_ERR_INVALID_SYNC_WORD);
    210   }
    211   _directSyncWordMask = 0xFFFFFFFF >> (32 - len);
    212   _directSyncWordLen = len;
    213   _directSyncWord = syncWord;
    214 
    215   // override sync word matching when length is set to 0
    216   if(_directSyncWordLen == 0) {
    217     _gotSync = true;
    218   }
    219 
    220   return(RADIOLIB_ERR_NONE);
    221 }
    222 
    223 void PhysicalLayer::updateDirectBuffer(uint8_t bit) {
    224   // check sync word
    225   if(!_gotSync) {
    226     _syncBuffer <<= 1;
    227     _syncBuffer |= bit;
    228     if((_syncBuffer & _directSyncWordMask) == _directSyncWord) {
    229       _gotSync = true;
    230       _bufferWritePos = 0;
    231       _bufferReadPos = 0;
    232       _bufferBitPos = 0;
    233     }
    234 
    235   } else {
    236     // save the bit
    237     if(bit) {
    238       _buffer[_bufferWritePos] |= 0x01 << _bufferBitPos;
    239     } else {
    240       _buffer[_bufferWritePos] &= ~(0x01 << _bufferBitPos);
    241     }
    242     _bufferBitPos++;
    243 
    244     // check complete byte
    245     if(_bufferBitPos == 8) {
    246       _buffer[_bufferWritePos] = Module::flipBits(_buffer[_bufferWritePos]);
    247       _bufferWritePos++;
    248       _bufferBitPos = 0;
    249     }
    250   }
    251 }
    252 #endif
    253 
    254 int16_t PhysicalLayer::setDIOMapping(RADIOLIB_PIN_TYPE pin, uint8_t value) {
    255   return(RADIOLIB_ERR_UNSUPPORTED);
    256 }