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 }