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 |
Module.cpp (13876B)
1 #include "Module.h" 2 3 #if defined(RADIOLIB_BUILD_ARDUINO) 4 5 // we need this to emulate tone() on mbed Arduino boards 6 #if defined(RADIOLIB_MBED_TONE_OVERRIDE) 7 #include "mbed.h" 8 mbed::PwmOut *pwmPin = NULL; 9 #endif 10 11 Module::Module(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE gpio): 12 _cs(cs), 13 _irq(irq), 14 _rst(rst), 15 _gpio(gpio) 16 { 17 _spi = &RADIOLIB_DEFAULT_SPI; 18 _initInterface = true; 19 20 // this is Arduino build, pre-set callbacks 21 setCb_pinMode(::pinMode); 22 setCb_digitalRead(::digitalRead); 23 setCb_digitalWrite(::digitalWrite); 24 #if !defined(RADIOLIB_TONE_UNSUPPORTED) 25 setCb_tone(::tone); 26 setCb_noTone(::noTone); 27 #endif 28 setCb_attachInterrupt(::attachInterrupt); 29 setCb_detachInterrupt(::detachInterrupt); 30 #if !defined(RADIOLIB_YIELD_UNSUPPORTED) 31 setCb_yield(::yield); 32 #endif 33 setCb_delay(::delay); 34 setCb_delayMicroseconds(::delayMicroseconds); 35 setCb_millis(::millis); 36 setCb_micros(::micros); 37 setCb_pulseIn(::pulseIn); 38 setCb_SPIbegin(&Module::SPIbegin); 39 setCb_SPIbeginTransaction(&Module::beginTransaction); 40 setCb_SPItransfer(&Module::transfer); 41 setCb_SPIendTransaction(&Module::endTransaction); 42 setCb_SPIend(&Module::end); 43 } 44 45 Module::Module(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE gpio, SPIClass& spi, SPISettings spiSettings): 46 _cs(cs), 47 _irq(irq), 48 _rst(rst), 49 _gpio(gpio), 50 _spiSettings(spiSettings) 51 { 52 _spi = &spi; 53 _initInterface = false; 54 55 // this is Arduino build, pre-set callbacks 56 setCb_pinMode(::pinMode); 57 setCb_digitalRead(::digitalRead); 58 setCb_digitalWrite(::digitalWrite); 59 #if !defined(RADIOLIB_TONE_UNSUPPORTED) 60 setCb_tone(::tone); 61 setCb_noTone(::noTone); 62 #endif 63 setCb_attachInterrupt(::attachInterrupt); 64 setCb_detachInterrupt(::detachInterrupt); 65 #if !defined(RADIOLIB_YIELD_UNSUPPORTED) 66 setCb_yield(::yield); 67 #endif 68 setCb_delay(::delay); 69 setCb_delayMicroseconds(::delayMicroseconds); 70 setCb_millis(::millis); 71 setCb_micros(::micros); 72 setCb_pulseIn(::pulseIn); 73 setCb_SPIbegin(&Module::SPIbegin); 74 setCb_SPIbeginTransaction(&Module::beginTransaction); 75 setCb_SPItransfer(&Module::transfer); 76 setCb_SPIendTransaction(&Module::endTransaction); 77 setCb_SPIend(&Module::end); 78 } 79 #else 80 81 Module::Module(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE gpio): 82 _cs(cs), 83 _irq(irq), 84 _rst(rst), 85 _gpio(gpio) 86 { 87 // not an Arduino build, it's up to the user to set all callbacks 88 } 89 90 #endif 91 92 Module::Module(const Module& mod) { 93 *this = mod; 94 } 95 96 Module& Module::operator=(const Module& mod) { 97 this->SPIreadCommand = mod.SPIreadCommand; 98 this->SPIwriteCommand = mod.SPIwriteCommand; 99 this->_cs = mod.getCs(); 100 this->_irq = mod.getIrq(); 101 this->_rst = mod.getRst(); 102 this->_gpio = mod.getGpio(); 103 104 return(*this); 105 } 106 107 void Module::init() { 108 this->pinMode(_cs, OUTPUT); 109 this->digitalWrite(_cs, HIGH); 110 #if defined(RADIOLIB_BUILD_ARDUINO) 111 if(_initInterface) { 112 (this->*cb_SPIbegin)(); 113 } 114 #endif 115 } 116 117 void Module::term() { 118 // stop hardware interfaces (if they were initialized by the library) 119 #if defined(RADIOLIB_BUILD_ARDUINO) 120 if(!_initInterface) { 121 return; 122 } 123 124 if(_spi != nullptr) { 125 this->SPIend(); 126 } 127 #endif 128 } 129 130 int16_t Module::SPIgetRegValue(uint8_t reg, uint8_t msb, uint8_t lsb) { 131 if((msb > 7) || (lsb > 7) || (lsb > msb)) { 132 return(RADIOLIB_ERR_INVALID_BIT_RANGE); 133 } 134 135 uint8_t rawValue = SPIreadRegister(reg); 136 uint8_t maskedValue = rawValue & ((0b11111111 << lsb) & (0b11111111 >> (7 - msb))); 137 return(maskedValue); 138 } 139 140 int16_t Module::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval, uint8_t checkMask) { 141 if((msb > 7) || (lsb > 7) || (lsb > msb)) { 142 return(RADIOLIB_ERR_INVALID_BIT_RANGE); 143 } 144 145 uint8_t currentValue = SPIreadRegister(reg); 146 uint8_t mask = ~((0b11111111 << (msb + 1)) | (0b11111111 >> (8 - lsb))); 147 uint8_t newValue = (currentValue & ~mask) | (value & mask); 148 SPIwriteRegister(reg, newValue); 149 150 #if defined(RADIOLIB_SPI_PARANOID) 151 // check register value each millisecond until check interval is reached 152 // some registers need a bit of time to process the change (e.g. SX127X_REG_OP_MODE) 153 uint32_t start = this->micros(); 154 uint8_t readValue = 0x00; 155 while(this->micros() - start < (checkInterval * 1000)) { 156 readValue = SPIreadRegister(reg); 157 if((readValue & checkMask) == (newValue & checkMask)) { 158 // check passed, we can stop the loop 159 return(RADIOLIB_ERR_NONE); 160 } 161 } 162 163 // check failed, print debug info 164 RADIOLIB_DEBUG_PRINTLN(); 165 RADIOLIB_DEBUG_PRINT(F("address:\t0x")); 166 RADIOLIB_DEBUG_PRINTLN(reg, HEX); 167 RADIOLIB_DEBUG_PRINT(F("bits:\t\t")); 168 RADIOLIB_DEBUG_PRINT(msb); 169 RADIOLIB_DEBUG_PRINT(' '); 170 RADIOLIB_DEBUG_PRINTLN(lsb); 171 RADIOLIB_DEBUG_PRINT(F("value:\t\t0b")); 172 RADIOLIB_DEBUG_PRINTLN(value, BIN); 173 RADIOLIB_DEBUG_PRINT(F("current:\t0b")); 174 RADIOLIB_DEBUG_PRINTLN(currentValue, BIN); 175 RADIOLIB_DEBUG_PRINT(F("mask:\t\t0b")); 176 RADIOLIB_DEBUG_PRINTLN(mask, BIN); 177 RADIOLIB_DEBUG_PRINT(F("new:\t\t0b")); 178 RADIOLIB_DEBUG_PRINTLN(newValue, BIN); 179 RADIOLIB_DEBUG_PRINT(F("read:\t\t0b")); 180 RADIOLIB_DEBUG_PRINTLN(readValue, BIN); 181 RADIOLIB_DEBUG_PRINTLN(); 182 183 return(RADIOLIB_ERR_SPI_WRITE_FAILED); 184 #else 185 return(RADIOLIB_ERR_NONE); 186 #endif 187 } 188 189 void Module::SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes) { 190 SPItransfer(SPIreadCommand, reg, NULL, inBytes, numBytes); 191 } 192 193 uint8_t Module::SPIreadRegister(uint8_t reg) { 194 uint8_t resp = 0; 195 SPItransfer(SPIreadCommand, reg, NULL, &resp, 1); 196 return(resp); 197 } 198 199 void Module::SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, uint8_t numBytes) { 200 SPItransfer(SPIwriteCommand, reg, data, NULL, numBytes); 201 } 202 203 void Module::SPIwriteRegister(uint8_t reg, uint8_t data) { 204 SPItransfer(SPIwriteCommand, reg, &data, NULL, 1); 205 } 206 207 void Module::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes) { 208 // start SPI transaction 209 this->SPIbeginTransaction(); 210 211 // pull CS low 212 this->digitalWrite(_cs, LOW); 213 214 // send SPI register address with access command 215 this->SPItransfer(reg | cmd); 216 #if defined(RADIOLIB_VERBOSE) 217 if(cmd == SPIwriteCommand) { 218 RADIOLIB_VERBOSE_PRINT('W'); 219 } else if(cmd == SPIreadCommand) { 220 RADIOLIB_VERBOSE_PRINT('R'); 221 } 222 RADIOLIB_VERBOSE_PRINT('\t') 223 RADIOLIB_VERBOSE_PRINT(reg, HEX); 224 RADIOLIB_VERBOSE_PRINT('\t'); 225 #endif 226 227 // send data or get response 228 if(cmd == SPIwriteCommand) { 229 if(dataOut != NULL) { 230 for(size_t n = 0; n < numBytes; n++) { 231 this->SPItransfer(dataOut[n]); 232 RADIOLIB_VERBOSE_PRINT(dataOut[n], HEX); 233 RADIOLIB_VERBOSE_PRINT('\t'); 234 } 235 } 236 } else if (cmd == SPIreadCommand) { 237 if(dataIn != NULL) { 238 for(size_t n = 0; n < numBytes; n++) { 239 dataIn[n] = this->SPItransfer(0x00); 240 RADIOLIB_VERBOSE_PRINT(dataIn[n], HEX); 241 RADIOLIB_VERBOSE_PRINT('\t'); 242 } 243 } 244 } 245 RADIOLIB_VERBOSE_PRINTLN(); 246 247 // release CS 248 this->digitalWrite(_cs, HIGH); 249 250 // end SPI transaction 251 this->SPIendTransaction(); 252 } 253 254 void Module::pinMode(RADIOLIB_PIN_TYPE pin, RADIOLIB_PIN_MODE mode) { 255 if((pin == RADIOLIB_NC) || (cb_pinMode == nullptr)) { 256 return; 257 } 258 cb_pinMode(pin, mode); 259 } 260 261 void Module::digitalWrite(RADIOLIB_PIN_TYPE pin, RADIOLIB_PIN_STATUS value) { 262 if((pin == RADIOLIB_NC) || (cb_digitalWrite == nullptr)) { 263 return; 264 } 265 cb_digitalWrite(pin, value); 266 } 267 268 RADIOLIB_PIN_STATUS Module::digitalRead(RADIOLIB_PIN_TYPE pin) { 269 if((pin == RADIOLIB_NC) || (cb_digitalRead == nullptr)) { 270 return((RADIOLIB_PIN_STATUS)0); 271 } 272 return(cb_digitalRead(pin)); 273 } 274 275 #if defined(ESP32) 276 // we need to cache the previous tone value for emulation on ESP32 277 int32_t prev = -1; 278 #endif 279 280 void Module::tone(RADIOLIB_PIN_TYPE pin, uint16_t value, uint32_t duration) { 281 #if !defined(RADIOLIB_TONE_UNSUPPORTED) 282 if((pin == RADIOLIB_NC) || (cb_tone == nullptr)) { 283 return; 284 } 285 cb_tone(pin, value, duration); 286 #else 287 if(pin == RADIOLIB_NC) { 288 return; 289 } 290 #if defined(ESP32) 291 // ESP32 tone() emulation 292 (void)duration; 293 if(prev == -1) { 294 ledcAttachPin(pin, RADIOLIB_TONE_ESP32_CHANNEL); 295 } 296 if(prev != value) { 297 ledcWriteTone(RADIOLIB_TONE_ESP32_CHANNEL, value); 298 } 299 prev = value; 300 #elif defined(RADIOLIB_MBED_TONE_OVERRIDE) 301 // better tone for mbed OS boards 302 (void)duration; 303 if(!pwmPin) { 304 pwmPin = new mbed::PwmOut(digitalPinToPinName(pin)); 305 } 306 pwmPin->period(1.0 / value); 307 pwmPin->write(0.5); 308 #else 309 (void)value; 310 (void)duration; 311 #endif 312 #endif 313 } 314 315 void Module::noTone(RADIOLIB_PIN_TYPE pin) { 316 #if !defined(RADIOLIB_TONE_UNSUPPORTED) 317 if((pin == RADIOLIB_NC) || (cb_noTone == nullptr)) { 318 return; 319 } 320 #if defined(ARDUINO_ARCH_STM32) 321 cb_noTone(pin, false); 322 #else 323 cb_noTone(pin); 324 #endif 325 #else 326 if(pin == RADIOLIB_NC) { 327 return; 328 } 329 #if defined(ESP32) 330 // ESP32 tone() emulation 331 ledcDetachPin(pin); 332 ledcWrite(RADIOLIB_TONE_ESP32_CHANNEL, 0); 333 prev = -1; 334 #elif defined(RADIOLIB_MBED_TONE_OVERRIDE) 335 // better tone for mbed OS boards 336 (void)pin; 337 pwmPin->suspend(); 338 #endif 339 #endif 340 } 341 342 void Module::attachInterrupt(RADIOLIB_PIN_TYPE interruptNum, void (*userFunc)(void), RADIOLIB_INTERRUPT_STATUS mode) { 343 if((interruptNum == RADIOLIB_NC) || (cb_attachInterrupt == nullptr)) { 344 return; 345 } 346 cb_attachInterrupt(interruptNum, userFunc, mode); 347 } 348 349 void Module::detachInterrupt(RADIOLIB_PIN_TYPE interruptNum) { 350 if((interruptNum == RADIOLIB_NC) || (cb_detachInterrupt == nullptr)) { 351 return; 352 } 353 cb_detachInterrupt(interruptNum); 354 } 355 356 void Module::yield() { 357 if(cb_yield == nullptr) { 358 return; 359 } 360 #if !defined(RADIOLIB_YIELD_UNSUPPORTED) 361 cb_yield(); 362 #endif 363 } 364 365 void Module::delay(uint32_t ms) { 366 if(cb_delay == nullptr) { 367 return; 368 } 369 cb_delay(ms); 370 } 371 372 void Module::delayMicroseconds(uint32_t us) { 373 if(cb_delayMicroseconds == nullptr) { 374 return; 375 } 376 cb_delayMicroseconds(us); 377 } 378 379 uint32_t Module::millis() { 380 if(cb_millis == nullptr) { 381 return(0); 382 } 383 return(cb_millis()); 384 } 385 386 uint32_t Module::micros() { 387 if(cb_micros == nullptr) { 388 return(0); 389 } 390 return(cb_micros()); 391 } 392 393 uint32_t Module::pulseIn(RADIOLIB_PIN_TYPE pin, RADIOLIB_PIN_STATUS state, uint32_t timeout) { 394 if(cb_pulseIn == nullptr) { 395 return(0); 396 } 397 return(cb_pulseIn(pin, state, timeout)); 398 } 399 400 void Module::begin() { 401 #if defined(RADIOLIB_BUILD_ARDUINO) 402 if(cb_SPIbegin == nullptr) { 403 return; 404 } 405 (this->*cb_SPIbegin)(); 406 #endif 407 } 408 409 void Module::beginTransaction() { 410 #if defined(RADIOLIB_BUILD_ARDUINO) 411 if(cb_SPIbeginTransaction == nullptr) { 412 return; 413 } 414 (this->*cb_SPIbeginTransaction)(); 415 #endif 416 } 417 418 uint8_t Module::transfer(uint8_t b) { 419 #if defined(RADIOLIB_BUILD_ARDUINO) 420 if(cb_SPItransfer == nullptr) { 421 return(0xFF); 422 } 423 return((this->*cb_SPItransfer)(b)); 424 #endif 425 } 426 427 void Module::endTransaction() { 428 #if defined(RADIOLIB_BUILD_ARDUINO) 429 if(cb_SPIendTransaction == nullptr) { 430 return; 431 } 432 (this->*cb_SPIendTransaction)(); 433 #endif 434 } 435 436 void Module::end() { 437 #if defined(RADIOLIB_BUILD_ARDUINO) 438 if(cb_SPIend == nullptr) { 439 return; 440 } 441 (this->*cb_SPIend)(); 442 #endif 443 } 444 445 #if defined(RADIOLIB_BUILD_ARDUINO) 446 void Module::SPIbegin() { 447 _spi->begin(); 448 } 449 #endif 450 451 void Module::SPIbeginTransaction() { 452 #if defined(RADIOLIB_BUILD_ARDUINO) 453 _spi->beginTransaction(_spiSettings); 454 #endif 455 } 456 457 uint8_t Module::SPItransfer(uint8_t b) { 458 #if defined(RADIOLIB_BUILD_ARDUINO) 459 return(_spi->transfer(b)); 460 #endif 461 } 462 463 void Module::SPIendTransaction() { 464 #if defined(RADIOLIB_BUILD_ARDUINO) 465 _spi->endTransaction(); 466 #endif 467 } 468 469 #if defined(RADIOLIB_BUILD_ARDUINO) 470 void Module::SPIend() { 471 _spi->end(); 472 } 473 #endif 474 475 uint8_t Module::flipBits(uint8_t b) { 476 b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; 477 b = (b & 0xCC) >> 2 | (b & 0x33) << 2; 478 b = (b & 0xAA) >> 1 | (b & 0x55) << 1; 479 return b; 480 } 481 482 uint16_t Module::flipBits16(uint16_t i) { 483 i = (i & 0xFF00) >> 8 | (i & 0x00FF) << 8; 484 i = (i & 0xF0F0) >> 4 | (i & 0x0F0F) << 4; 485 i = (i & 0xCCCC) >> 2 | (i & 0x3333) << 2; 486 i = (i & 0xAAAA) >> 1 | (i & 0x5555) << 1; 487 return i; 488 } 489 490 void Module::hexdump(uint8_t* data, size_t len) { 491 size_t rem_len = len; 492 for(int i = 0; i < len; i+=16) { 493 char str[80]; 494 sprintf(str, "%07x ", i); 495 size_t line_len = 16; 496 if(rem_len < line_len) { 497 line_len = rem_len; 498 } 499 for(int j = 0; j < line_len; j++) { 500 sprintf(&str[8 + j*3], "%02x ", data[i+j]); 501 } 502 for(int j = line_len; j < 16; j++) { 503 sprintf(&str[8 + j*3], " "); 504 } 505 str[56] = '|'; 506 str[57] = ' '; 507 for(int j = 0; j < line_len; j++) { 508 char c = data[i+j]; 509 if((c < ' ') || (c > '~')) { 510 c = '.'; 511 } 512 sprintf(&str[58 + j], "%c", c); 513 } 514 for(int j = line_len; j < 16; j++) { 515 sprintf(&str[58 + j], " "); 516 } 517 RADIOLIB_DEBUG_PRINTLN(str); 518 rem_len -= 16; 519 } 520 } 521 522 void Module::regdump(uint8_t start, uint8_t len) { 523 #if defined(RADIOLIB_STATIC_ONLY) 524 uint8_t buff[RADIOLIB_STATIC_ARRAY_SIZE]; 525 #else 526 uint8_t* buff = new uint8_t[len]; 527 #endif 528 SPIreadRegisterBurst(start, len, buff); 529 hexdump(buff, len); 530 #if !defined(RADIOLIB_STATIC_ONLY) 531 delete[] buff; 532 #endif 533 } 534 535 void Module::setRfSwitchPins(RADIOLIB_PIN_TYPE rxEn, RADIOLIB_PIN_TYPE txEn) { 536 _useRfSwitch = true; 537 _rxEn = rxEn; 538 _txEn = txEn; 539 this->pinMode(rxEn, OUTPUT); 540 this->pinMode(txEn, OUTPUT); 541 } 542 543 void Module::setRfSwitchState(RADIOLIB_PIN_STATUS rxPinState, RADIOLIB_PIN_STATUS txPinState) { 544 // check RF switch control is enabled 545 if(!_useRfSwitch) { 546 return; 547 } 548 549 // set pins 550 this->digitalWrite(_rxEn, rxPinState); 551 this->digitalWrite(_txEn, txPinState); 552 }