main.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include <Arduino.h>
  2. #include <target.h>
  3. #include <helpers/ArduinoHelpers.h>
  4. #include <helpers/IdentityStore.h>
  5. #include "KissModem.h"
  6. #if defined(NRF52_PLATFORM)
  7. #include <InternalFileSystem.h>
  8. #elif defined(RP2040_PLATFORM)
  9. #include <LittleFS.h>
  10. #elif defined(ESP32)
  11. #include <SPIFFS.h>
  12. #endif
  13. #if defined(KISS_UART_RX) && defined(KISS_UART_TX)
  14. #include <HardwareSerial.h>
  15. #endif
  16. #define NOISE_FLOOR_CALIB_INTERVAL_MS 2000
  17. #define AGC_RESET_INTERVAL_MS 30000
  18. StdRNG rng;
  19. mesh::LocalIdentity identity;
  20. KissModem* modem;
  21. static uint32_t next_noise_floor_calib_ms = 0;
  22. static uint32_t next_agc_reset_ms = 0;
  23. void halt() {
  24. while (1) ;
  25. }
  26. void loadOrCreateIdentity() {
  27. #if defined(NRF52_PLATFORM)
  28. InternalFS.begin();
  29. IdentityStore store(InternalFS, "");
  30. #elif defined(ESP32)
  31. SPIFFS.begin(true);
  32. IdentityStore store(SPIFFS, "/identity");
  33. #elif defined(RP2040_PLATFORM)
  34. LittleFS.begin();
  35. IdentityStore store(LittleFS, "/identity");
  36. store.begin();
  37. #else
  38. #error "Filesystem not defined"
  39. #endif
  40. if (!store.load("_main", identity)) {
  41. identity = radio_new_identity();
  42. while (identity.pub_key[0] == 0x00 || identity.pub_key[0] == 0xFF) {
  43. identity = radio_new_identity();
  44. }
  45. store.save("_main", identity);
  46. }
  47. }
  48. void onSetRadio(float freq, float bw, uint8_t sf, uint8_t cr) {
  49. radio_set_params(freq, bw, sf, cr);
  50. }
  51. void onSetTxPower(uint8_t power) {
  52. radio_set_tx_power(power);
  53. }
  54. float onGetCurrentRssi() {
  55. return radio_driver.getCurrentRSSI();
  56. }
  57. void onGetStats(uint32_t* rx, uint32_t* tx, uint32_t* errors) {
  58. *rx = radio_driver.getPacketsRecv();
  59. *tx = radio_driver.getPacketsSent();
  60. *errors = radio_driver.getPacketsRecvErrors();
  61. }
  62. void onSendPacket(const uint8_t* data, uint16_t len) {
  63. radio_driver.startSendRaw(data, len);
  64. }
  65. bool onIsSendComplete() {
  66. return radio_driver.isSendComplete();
  67. }
  68. void onSendFinished() {
  69. radio_driver.onSendFinished();
  70. }
  71. void setup() {
  72. board.begin();
  73. if (!radio_init()) {
  74. halt();
  75. }
  76. radio_driver.begin();
  77. rng.begin(radio_get_rng_seed());
  78. loadOrCreateIdentity();
  79. sensors.begin();
  80. #if defined(KISS_UART_RX) && defined(KISS_UART_TX)
  81. #if defined(ESP32)
  82. Serial1.setPins(KISS_UART_RX, KISS_UART_TX);
  83. Serial1.begin(115200);
  84. #elif defined(NRF52_PLATFORM)
  85. ((Uart *)&Serial1)->setPins(KISS_UART_RX, KISS_UART_TX);
  86. Serial1.begin(115200);
  87. #elif defined(RP2040_PLATFORM)
  88. ((SerialUART *)&Serial1)->setRX(KISS_UART_RX);
  89. ((SerialUART *)&Serial1)->setTX(KISS_UART_TX);
  90. Serial1.begin(115200);
  91. #elif defined(STM32_PLATFORM)
  92. ((HardwareSerial *)&Serial1)->setRx(KISS_UART_RX);
  93. ((HardwareSerial *)&Serial1)->setTx(KISS_UART_TX);
  94. Serial1.begin(115200);
  95. #else
  96. #error "KISS UART not supported on this platform"
  97. #endif
  98. modem = new KissModem(Serial1, identity, rng, radio_driver, board, sensors);
  99. #else
  100. Serial.begin(115200);
  101. uint32_t start = millis();
  102. while (!Serial && millis() - start < 3000) delay(10);
  103. delay(100);
  104. modem = new KissModem(Serial, identity, rng, radio_driver, board, sensors);
  105. #endif
  106. modem->setRadioCallback(onSetRadio);
  107. modem->setTxPowerCallback(onSetTxPower);
  108. modem->setGetCurrentRssiCallback(onGetCurrentRssi);
  109. modem->setGetStatsCallback(onGetStats);
  110. modem->setSendPacketCallback(onSendPacket);
  111. modem->setIsSendCompleteCallback(onIsSendComplete);
  112. modem->setOnSendFinishedCallback(onSendFinished);
  113. modem->begin();
  114. }
  115. void loop() {
  116. modem->loop();
  117. if (!modem->isActuallyTransmitting()) {
  118. if (!modem->isTxBusy()) {
  119. if ((uint32_t)(millis() - next_agc_reset_ms) >= AGC_RESET_INTERVAL_MS) {
  120. radio_driver.resetAGC();
  121. next_agc_reset_ms = millis();
  122. }
  123. }
  124. uint8_t rx_buf[256];
  125. int rx_len = radio_driver.recvRaw(rx_buf, sizeof(rx_buf));
  126. if (rx_len > 0) {
  127. int8_t snr = (int8_t)(radio_driver.getLastSNR() * 4);
  128. int8_t rssi = (int8_t)radio_driver.getLastRSSI();
  129. modem->onPacketReceived(snr, rssi, rx_buf, rx_len);
  130. }
  131. /* Sample noise floor right after drain: we're in STATE_RX so wrapper can collect. */
  132. for (int i = 0; i < 16; i++) {
  133. radio_driver.loop();
  134. }
  135. }
  136. /* Trigger starts a new 64-sample calibration window every 2s. */
  137. if ((uint32_t)(millis() - next_noise_floor_calib_ms) >= NOISE_FLOOR_CALIB_INTERVAL_MS) {
  138. radio_driver.triggerNoiseFloorCalibrate(0);
  139. next_noise_floor_calib_ms = millis();
  140. }
  141. radio_driver.loop();
  142. if (!modem->isActuallyTransmitting()) {
  143. for (int i = 0; i < 15; i++) {
  144. radio_driver.loop();
  145. }
  146. }
  147. }