diff --git a/.github/workflows/build_check.yml b/.github/workflows/build_check.yml index 6f8c869..273e021 100644 --- a/.github/workflows/build_check.yml +++ b/.github/workflows/build_check.yml @@ -79,7 +79,26 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - name: Run PlatformIO Check - run: pio check --fail-on-defect high -e lora_board + run: pio check --fail-on-defect high --fail-on-defect medium --fail-on-defect low -e lora_board + + cppcheck-docker: + name: Run cppcheck in Docker + runs-on: ubuntu-latest + env: + CPPCHECK_ARGS: --enable=all --std=c++20 --inline-suppr -I lib/BoardFinder -I lib/ConfigurationManagement -I lib/Display -I lib/LoRa -I lib/LoRa_APRS -I lib/NTPClient -I lib/PowerManagement -I lib/System -I lib/TimeLib -i lib/Display -i lib/LoRa -i lib/NTPClient -i lib/TimeLib src lib + steps: + - name: checkout code + uses: actions/checkout@v3 + - run: docker pull facthunder/cppcheck:latest + - name: Run cppcheck and print result + run: docker run --rm -v ${PWD}:/src facthunder/cppcheck:latest /bin/bash -c "cppcheck $CPPCHECK_ARGS" + - name: Run cppcheck and create html + run: docker run --rm -v ${PWD}:/src facthunder/cppcheck:latest /bin/bash -c "cppcheck --xml $CPPCHECK_ARGS 2> report.xml && cppcheck-htmlreport --file=report.xml --report-dir=output" + - name: Upload report + uses: actions/upload-artifact@v3 + with: + name: Cppcheck Report + path: output hw_testing: name: Hardware Testing diff --git a/data/is-cfg.json b/data/is-cfg.json index 6f40fbb..0d3b131 100644 --- a/data/is-cfg.json +++ b/data/is-cfg.json @@ -30,7 +30,8 @@ "longitude": 0.000000 }, "use_gps": false, - "timeout": 15 + "timeout": 15, + "send_on_hf": false }, "aprs_is": { "active": true, @@ -40,8 +41,7 @@ "filter": "" }, "digi": { - "active": false, - "beacon": false + "active": false }, "lora": { "frequency_rx": 433775000, diff --git a/lib/PowerManagement/power_management.cpp b/lib/PowerManagement/power_management.cpp index e81e6bf..f93a7a1 100644 --- a/lib/PowerManagement/power_management.cpp +++ b/lib/PowerManagement/power_management.cpp @@ -1,7 +1,7 @@ #include "power_management.h" -PowerManagement::PowerManagement() { +PowerManagement::PowerManagement() : axp() { } bool PowerManagement::begin(TwoWire &port) { diff --git a/platformio.ini b/platformio.ini index 3d32fed..7693247 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,14 +12,14 @@ lib_deps = lewisxhe/AXP202X_Library @ 1.1.3 peterus/APRS-Decoder-Lib @ 0.0.6 peterus/esp-logger @ 1.0.0 - peterus/ESP-FTP-Server-Lib @ 0.11.0 + peterus/ESP-FTP-Server-Lib @ 0.13.0 knolleary/PubSubClient@^2.8 mikalhart/TinyGPSPlus @ 1.0.3 shaggydog/OneButton @ 1.5.0 - jgromes/RadioLib @ 5.7.0 + jgromes/RadioLib @ 6.0.0 check_tool = cppcheck check_flags = - cppcheck: --std=c++14 --suppress=*:*.pio\* --inline-suppr --suppress=unusedFunction -DCPPCHECK --force lib -ilib/TimeLib + cppcheck: --std=c++20 --suppress=*:*.pio\* --inline-suppr --suppress=unusedFunction -DCPPCHECK --force lib -ilib/TimeLib check_skip_packages = yes test_build_src = yes # activate for OTA Update, use the CALLSIGN from is-cfg.json as upload_port: diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index e568b9a..6390976 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -22,7 +22,7 @@ #include "TaskWifi.h" #include "project_configuration.h" -#define VERSION "23.06.0" +#define VERSION "23.23.99" #define MODULE_NAME "Main" String create_lat_aprs(double lat); diff --git a/src/TaskAprsIs.cpp b/src/TaskAprsIs.cpp index 2b880ac..81089e0 100644 --- a/src/TaskAprsIs.cpp +++ b/src/TaskAprsIs.cpp @@ -30,9 +30,11 @@ bool AprsIsTask::loop(System &system) { return false; } - std::shared_ptr msg = _aprs_is.getAPRSMessage(); - if (msg) { - _toModem.addElement(msg); + { + std::shared_ptr msg = _aprs_is.getAPRSMessage(); + if (msg) { + _toModem.addElement(msg); + } } if (!_toAprsIs.empty()) { @@ -44,7 +46,7 @@ bool AprsIsTask::loop(System &system) { } bool AprsIsTask::connect(System &system) { - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_INFO, getName(), "connecting to APRS-IS server: %s on port: %d, with filter: '%s'", system.getUserConfig()->aprs_is.server.c_str(), system.getUserConfig()->aprs_is.port, system.getUserConfig()->aprs_is.filter); + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_INFO, getName(), "connecting to APRS-IS server: %s on port: %d, with filter: '%s'", system.getUserConfig()->aprs_is.server.c_str(), system.getUserConfig()->aprs_is.port, system.getUserConfig()->aprs_is.filter.c_str()); APRS_IS::ConnectionStatus status = APRS_IS::ConnectionStatus::ERROR_CONNECTION; if (system.getUserConfig()->aprs_is.filter.isEmpty()) { status = _aprs_is.connect(system.getUserConfig()->aprs_is.server, system.getUserConfig()->aprs_is.port); diff --git a/src/TaskBeacon.cpp b/src/TaskBeacon.cpp index ba1e4a3..3a0b292 100644 --- a/src/TaskBeacon.cpp +++ b/src/TaskBeacon.cpp @@ -116,7 +116,7 @@ bool BeaconTask::sendBeacon(System &system) { _toAprsIs.addElement(_beaconMsg); } - if (system.getUserConfig()->digi.beacon) { + if (system.getUserConfig()->beacon.send_on_hf) { _toModem.addElement(_beaconMsg); } diff --git a/src/TaskMQTT.h b/src/TaskMQTT.h index d388075..082ec2e 100644 --- a/src/TaskMQTT.h +++ b/src/TaskMQTT.h @@ -8,7 +8,7 @@ class MQTTTask : public Task { public: - MQTTTask(TaskQueue> &toMQTT); + explicit MQTTTask(TaskQueue> &toMQTT); virtual ~MQTTTask(); virtual bool setup(System &system) override; diff --git a/src/TaskRadiolib.cpp b/src/TaskRadiolib.cpp index a887ece..f52fb61 100644 --- a/src/TaskRadiolib.cpp +++ b/src/TaskRadiolib.cpp @@ -4,215 +4,282 @@ #include "TaskRadiolib.h" -RadiolibTask::RadiolibTask(TaskQueue> &fromModem, TaskQueue> &toModem) : Task(TASK_RADIOLIB, TaskRadiolib), _fromModem(fromModem), _toModem(toModem) { +volatile bool RadiolibTask::_modemInterruptOccured = false; + +RadiolibTask::RadiolibTask(TaskQueue> &fromModem, TaskQueue> &toModem) : Task(TASK_RADIOLIB, TaskRadiolib), _module(0), _radio(0), _rxEnable(false), _txEnable(false), _fromModem(fromModem), _toModem(toModem), _transmitFlag(false), _frequencyTx(0.0), _frequencyRx(0.0), _frequenciesAreSame(false) { } RadiolibTask::~RadiolibTask() { - radio->clearDio0Action(); -} - -volatile bool RadiolibTask::enableInterrupt = true; // Need to catch interrupt or not. -volatile bool RadiolibTask::operationDone = false; // Caught IRQ or not. - -void RadiolibTask::setFlag(void) { - if (!enableInterrupt) { - return; - } - - operationDone = true; + _radio->clearDio0Action(); } bool RadiolibTask::setup(System &system) { SPI.begin(system.getBoardConfig()->Lora.Sck, system.getBoardConfig()->Lora.Miso, system.getBoardConfig()->Lora.Mosi, system.getBoardConfig()->Lora.CS); - module = new Module(system.getBoardConfig()->Lora.CS, system.getBoardConfig()->Lora.IRQ, system.getBoardConfig()->Lora.Reset); - radio = new SX1278(module); + _module = new Module(system.getBoardConfig()->Lora.CS, system.getBoardConfig()->Lora.IRQ, system.getBoardConfig()->Lora.Reset); + _radio = new SX1278(_module); - config = system.getUserConfig()->lora; + _rxEnable = true; + _txEnable = system.getUserConfig()->lora.tx_enable; - rxEnable = true; - txEnable = config.tx_enable; + _frequencyTx = (float)system.getUserConfig()->lora.frequencyTx / 1000000; + _frequencyRx = (float)system.getUserConfig()->lora.frequencyRx / 1000000; - float freqMHz = (float)config.frequencyRx / 1000000; - float BWkHz = (float)config.signalBandwidth / 1000; + if (system.getUserConfig()->lora.frequencyTx == system.getUserConfig()->lora.frequencyRx) { + _frequenciesAreSame = true; + } + + float BWkHz = (float)system.getUserConfig()->lora.signalBandwidth / 1000; const uint16_t preambleLength = 8; - int16_t state = radio->begin(freqMHz, BWkHz, config.spreadingFactor, config.codingRate4, RADIOLIB_SX127X_SYNC_WORD, config.power, preambleLength, config.gainRx); + int16_t state = _radio->begin(_frequencyRx, BWkHz, system.getUserConfig()->lora.spreadingFactor, system.getUserConfig()->lora.codingRate4, RADIOLIB_SX127X_SYNC_WORD, system.getUserConfig()->lora.power, preambleLength, system.getUserConfig()->lora.gainRx); if (state != RADIOLIB_ERR_NONE) { - switch (state) { - case RADIOLIB_ERR_INVALID_FREQUENCY: - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied frequency value (%fMHz) is invalid for this module.", timeString().c_str(), freqMHz); - rxEnable = false; - txEnable = false; - break; - case RADIOLIB_ERR_INVALID_BANDWIDTH: - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied bandwidth value (%fkHz) is invalid for this module. Should be 7800, 10400, 15600, 20800, 31250, 41700 ,62500, 125000, 250000, 500000.", timeString().c_str(), BWkHz); - rxEnable = false; - txEnable = false; - break; - case RADIOLIB_ERR_INVALID_SPREADING_FACTOR: - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied spreading factor value (%d) is invalid for this module.", timeString().c_str(), config.spreadingFactor); - rxEnable = false; - txEnable = false; - break; - case RADIOLIB_ERR_INVALID_CODING_RATE: - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied coding rate value (%d) is invalid for this module.", timeString().c_str(), config.codingRate4); - rxEnable = false; - txEnable = false; - break; - case RADIOLIB_ERR_INVALID_OUTPUT_POWER: - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied output power value (%d) is invalid for this module.", timeString().c_str(), config.power); - txEnable = false; - break; - case RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH: - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied preamble length is invalid.", timeString().c_str()); - txEnable = false; - break; - case RADIOLIB_ERR_INVALID_GAIN: - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied gain value (%d) is invalid.", timeString().c_str(), config.gainRx); - rxEnable = false; - break; - default: - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, code %d", timeString().c_str(), state); - rxEnable = false; - txEnable = false; - } - _stateInfo = "LoRa-Modem failed"; - _state = Error; + decodeError(system, state); } - state = radio->setCRC(true); + state = _radio->setCRC(true); if (state != RADIOLIB_ERR_NONE) { system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] setCRC failed, code %d", timeString().c_str(), state); - _stateInfo = "LoRa-Modem failed"; - _state = Error; + decodeError(system, state); } - radio->setDio0Action(setFlag); + _radio->setDio0Action(setFlag, RISING); - if (rxEnable) { - int state = startRX(RADIOLIB_SX127X_RXCONTINUOUS); - if (state != RADIOLIB_ERR_NONE) { - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] startRX failed, code %d", timeString().c_str(), state); - rxEnable = false; - _stateInfo = "LoRa-Modem failed"; - _state = Error; - } + if (_rxEnable) { + startRX(system); } - if (config.power > 17 && config.tx_enable) { - radio->setCurrentLimit(140); + if (system.getUserConfig()->lora.tx_enable && system.getUserConfig()->lora.power > 17) { + _radio->setCurrentLimit(140); } - preambleDurationMilliSec = ((uint64_t)(preambleLength + 4) << (config.spreadingFactor + 10 /* to milli-sec */)) / config.signalBandwidth; + uint32_t preambleDurationMilliSec = ((uint64_t)(preambleLength + 4) << (system.getUserConfig()->lora.spreadingFactor + 10 /* to milli-sec */)) / system.getUserConfig()->lora.signalBandwidth; + _txWaitTimer.setTimeout(preambleDurationMilliSec * 2); _stateInfo = ""; return true; } -int transmissionState = RADIOLIB_ERR_NONE; -bool transmitFlag = false; // Transmitting or not. - bool RadiolibTask::loop(System &system) { - if (operationDone) { // occurs interrupt. - enableInterrupt = false; - - if (transmitFlag) { // transmitted. - if (transmissionState == RADIOLIB_ERR_NONE) { - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] TX done", timeString().c_str()); - - } else { - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] transmitFlag failed, code %d", timeString().c_str(), transmissionState); - } - operationDone = false; - transmitFlag = false; - - txWaitTimer.setTimeout(preambleDurationMilliSec * 2); - txWaitTimer.start(); - - } else { // received. - String str; - int state = radio->readData(str); - - if (state != RADIOLIB_ERR_NONE) { - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] readData failed, code %d", timeString().c_str(), state); - } else { - if (str.substring(0, 3) != "<\xff\x01") { - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Unknown packet '%s' with RSSI %.0fdBm, SNR %.2fdB and FreqErr %fHz", timeString().c_str(), str.c_str(), radio->getRSSI(), radio->getSNR(), -radio->getFrequencyError()); - } else { - std::shared_ptr msg = std::shared_ptr(new APRSMessage()); - msg->decode(str.substring(3)); - _fromModem.addElement(msg); - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Received packet '%s' with RSSI %.0fdBm, SNR %.2fdB and FreqErr %fHz", timeString().c_str(), msg->toString().c_str(), radio->getRSSI(), radio->getSNR(), -radio->getFrequencyError()); - system.getDisplay().addFrame(std::shared_ptr(new TextFrame("LoRa", msg->toString().c_str()))); - } - } - operationDone = false; - } - - if (rxEnable) { - int state = startRX(RADIOLIB_SX127X_RXCONTINUOUS); - if (state != RADIOLIB_ERR_NONE) { - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] startRX failed, code %d", timeString().c_str(), state); - rxEnable = false; - } - } - - enableInterrupt = true; - } else { // not interrupt. - if (!txWaitTimer.check()) { - } else { - if (!txEnable) { - // system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] TX is not enabled", timeString().c_str()); - } else { - if (transmitFlag) { - // system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] TX signal detected. Waiting TX", timeString().c_str()); - } else { - if (!_toModem.empty()) { - if (config.frequencyRx == config.frequencyTx && (radio->getModemStatus() & 0x01) == 0x01) { - // system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] RX signal detected. Waiting TX", timeString().c_str()); - } else { - std::shared_ptr msg = _toModem.getElement(); - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Transmitting packet '%s'", timeString().c_str(), msg->toString().c_str()); - - int16_t state = startTX("<\xff\x01" + msg->encode()); - if (state != RADIOLIB_ERR_NONE) { - system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] startTX failed, code %d", timeString().c_str(), state); - txEnable = false; - return true; - } - } - } else { - _toModem.getElement(); // empty list, otherwise memory will get full. - } - } - } - } + if (_modemInterruptOccured) { + handleModemInterrupt(system); + } else if (_txWaitTimer.check() && !_toModem.empty()) { + handleTXing(system); } - return true; } -int16_t RadiolibTask::startRX(uint8_t mode) { - if (config.frequencyTx != config.frequencyRx) { - int16_t state = radio->setFrequency((float)config.frequencyRx / 1000000); +void RadiolibTask::setFlag(void) { + _modemInterruptOccured = true; +} + +void RadiolibTask::handleModemInterrupt(System &system) { + _modemInterruptOccured = false; + + if (_transmitFlag) { // transmitted + _transmitFlag = false; + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] TX done", timeString().c_str()); + _txWaitTimer.start(); + startRX(system); + return; + } + + // received + String str; + int state = _radio->readData(str); + if (state != RADIOLIB_ERR_NONE) { + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] readData failed, code %d", timeString().c_str(), state); + return; + } + if (str.substring(0, 3) != "<\xff\x01") { + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Unknown packet '%s' with RSSI %.0fdBm, SNR %.2fdB and FreqErr %fHz", timeString().c_str(), str.c_str(), _radio->getRSSI(), _radio->getSNR(), -_radio->getFrequencyError()); + return; + } + + std::shared_ptr msg = std::shared_ptr(new APRSMessage()); + msg->decode(str.substring(3)); + _fromModem.addElement(msg); + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Received packet '%s' with RSSI %.0fdBm, SNR %.2fdB and FreqErr %fHz", timeString().c_str(), msg->toString().c_str(), _radio->getRSSI(), _radio->getSNR(), -_radio->getFrequencyError()); + system.getDisplay().addFrame(std::shared_ptr(new TextFrame("LoRa", msg->toString().c_str()))); +} + +void RadiolibTask::handleTXing(System &system) { + if (!_txEnable) { + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] TX is not enabled", timeString().c_str()); + _toModem.getElement(); // empty list, otherwise memory will get full. + return; + } + + static bool txsignaldetected_print = false; + if (_transmitFlag) { // we are currently TXing, need to wait + if (!txsignaldetected_print) { + txsignaldetected_print = true; + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] TX signal detected. Waiting TX", timeString().c_str()); + } + return; + } + + // we are currently RXing + static bool rxsignaldetected_print = false; + if (_frequenciesAreSame && (_radio->getModemStatus() & 0x01) == 0x01) { + if (!rxsignaldetected_print) { + rxsignaldetected_print = true; + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] RX signal detected. Waiting TX", timeString().c_str()); + } + return; + } + + std::shared_ptr msg = _toModem.getElement(); + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, getName(), "[%s] Transmitting packet '%s'", timeString().c_str(), msg->toString().c_str()); + startTX(system, "<\xff\x01" + msg->encode()); + rxsignaldetected_print = false; + txsignaldetected_print = false; +} + +void RadiolibTask::startRX(System &system) { + if (!_frequenciesAreSame) { + int16_t state = _radio->setFrequency(_frequencyRx); if (state != RADIOLIB_ERR_NONE) { - return state; + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] startRX failed, Freq update, code %d", timeString().c_str(), state); + decodeError(system, state); + return; } } - return radio->startReceive(0, mode); + int16_t state = _radio->startReceive(); + if (state != RADIOLIB_ERR_NONE) { + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] startRX failed, code %d", timeString().c_str(), state); + decodeError(system, state); + } } -int16_t RadiolibTask::startTX(String &str) { - if (config.frequencyTx != config.frequencyRx) { - int16_t state = radio->setFrequency((float)config.frequencyTx / 1000000); +void RadiolibTask::startTX(System &system, String &str) { + if (!_frequenciesAreSame) { + int16_t state = _radio->setFrequency(_frequencyTx); if (state != RADIOLIB_ERR_NONE) { - return state; + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] startTX failed, Freq update, code %d", timeString().c_str(), state); + decodeError(system, state); + startRX(system); + return; } } - transmissionState = radio->startTransmit(str); - transmitFlag = true; - return RADIOLIB_ERR_NONE; + int16_t state = _radio->startTransmit(str); + if (state != RADIOLIB_ERR_NONE) { + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] startTX failed, code %d", timeString().c_str(), state); + decodeError(system, state); + startRX(system); + return; + } + _transmitFlag = true; +} + +void RadiolibTask::decodeError(System &system, int16_t state) { + switch (state) { + case RADIOLIB_ERR_UNKNOWN: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 unknown error.", timeString().c_str()); + _rxEnable = false; + _txEnable = false; + break; + case RADIOLIB_ERR_CHIP_NOT_FOUND: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, chip not found.", timeString().c_str()); + _rxEnable = false; + _txEnable = false; + break; + case RADIOLIB_ERR_PACKET_TOO_LONG: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 packet too long.", timeString().c_str()); + break; + case RADIOLIB_ERR_TX_TIMEOUT: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 tx timeout.", timeString().c_str()); + break; + case RADIOLIB_ERR_RX_TIMEOUT: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 rx timeout.", timeString().c_str()); + break; + case RADIOLIB_ERR_CRC_MISMATCH: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 crc mismatch.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_BANDWIDTH: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied bandwidth value (%fkHz) is invalid for this module. Should be 7800, 10400, 15600, 20800, 31250, 41700 ,62500, 125000, 250000, 500000.", timeString().c_str(), system.getUserConfig()->lora.signalBandwidth / 1000); + _rxEnable = false; + _txEnable = false; + break; + case RADIOLIB_ERR_INVALID_SPREADING_FACTOR: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied spreading factor value (%d) is invalid for this module.", timeString().c_str(), system.getUserConfig()->lora.spreadingFactor); + _rxEnable = false; + _txEnable = false; + break; + case RADIOLIB_ERR_INVALID_CODING_RATE: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied coding rate value (%d) is invalid for this module.", timeString().c_str(), system.getUserConfig()->lora.codingRate4); + _rxEnable = false; + _txEnable = false; + break; + case RADIOLIB_ERR_INVALID_FREQUENCY: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied frequency value (%fMHz) is invalid for this module.", timeString().c_str(), _frequencyRx); + _rxEnable = false; + _txEnable = false; + break; + case RADIOLIB_ERR_INVALID_OUTPUT_POWER: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied output power value (%d) is invalid for this module.", timeString().c_str(), system.getUserConfig()->lora.power); + _txEnable = false; + break; + case RADIOLIB_ERR_INVALID_CURRENT_LIMIT: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied current limit is invalid.", timeString().c_str()); + _txEnable = false; + break; + case RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied preamble length is invalid.", timeString().c_str()); + _txEnable = false; + break; + case RADIOLIB_ERR_INVALID_GAIN: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, The supplied gain value (%d) is invalid.", timeString().c_str(), system.getUserConfig()->lora.gainRx); + _rxEnable = false; + break; + case RADIOLIB_ERR_WRONG_MODEM: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, wrong modem selected.", timeString().c_str()); + _rxEnable = false; + _txEnable = false; + break; + case RADIOLIB_ERR_INVALID_NUM_SAMPLES: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid number of samples.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_RSSI_OFFSET: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid RSSI offset.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_ENCODING: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid encoding.", timeString().c_str()); + break; + case RADIOLIB_ERR_LORA_HEADER_DAMAGED: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 LoRa header damaged.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_DIO_PIN: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid DIO pin.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_RSSI_THRESHOLD: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid RSSI threshold.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_BIT_RATE: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid bit rate.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid frequency deviation.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_RX_BANDWIDTH: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid rx bandwidth.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_SYNC_WORD: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid sync word.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_DATA_SHAPING: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid data shaping.", timeString().c_str()); + break; + case RADIOLIB_ERR_INVALID_MODULATION: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 invalid modulation.", timeString().c_str()); + break; + default: + system.getLogger().log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, getName(), "[%s] SX1278 init failed, code %d", timeString().c_str(), state); + _rxEnable = false; + _txEnable = false; + } + _stateInfo = "LoRa-Modem failed"; + _state = Error; } diff --git a/src/TaskRadiolib.h b/src/TaskRadiolib.h index 11e59da..f07cb55 100644 --- a/src/TaskRadiolib.h +++ b/src/TaskRadiolib.h @@ -16,26 +16,34 @@ public: virtual bool loop(System &system) override; private: - Module *module; - SX1278 *radio; + Module *_module; + SX1278 *_radio; - Configuration::LoRa config; - - bool rxEnable, txEnable; + bool _rxEnable; + bool _txEnable; TaskQueue> &_fromModem; TaskQueue> &_toModem; - static volatile bool enableInterrupt; // Need to catch interrupt or not. - static volatile bool operationDone; // Caught IRQ or not. + static volatile bool _modemInterruptOccured; + + Timer _txWaitTimer; + + bool _transmitFlag; + + float _frequencyTx; + float _frequencyRx; + bool _frequenciesAreSame; static void setFlag(void); - int16_t startRX(uint8_t mode); - int16_t startTX(String &str); + void startRX(System &system); + void startTX(System &system, String &str); - uint32_t preambleDurationMilliSec; - Timer txWaitTimer; + void handleModemInterrupt(System &system); + void handleTXing(System &system); + + void decodeError(System &system, int16_t state); }; #endif diff --git a/src/project_configuration.cpp b/src/project_configuration.cpp index 47e0fc3..592b482 100644 --- a/src/project_configuration.cpp +++ b/src/project_configuration.cpp @@ -45,8 +45,9 @@ void ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocumen conf.beacon.positionLongitude = data["beacon"]["position"]["longitude"] | 0.0; conf.beacon.use_gps = data["beacon"]["use_gps"] | false; conf.beacon.timeout = data["beacon"]["timeout"] | 15; - conf.aprs_is.active = data["aprs_is"]["active"] | true; + conf.beacon.send_on_hf = data["beacon"]["send_on_hf"] | false; + conf.aprs_is.active = data["aprs_is"]["active"] | true; if (data.containsKey("aprs_is") && data["aprs_is"].containsKey("passcode")) conf.aprs_is.passcode = data["aprs_is"]["passcode"].as(); if (data.containsKey("aprs_is") && data["aprs_is"].containsKey("server")) @@ -56,7 +57,6 @@ void ProjectConfigurationManagement::readProjectConfiguration(DynamicJsonDocumen conf.aprs_is.filter = data["aprs_is"]["filter"].as(); conf.digi.active = data["digi"]["active"] | false; - conf.digi.beacon = data["digi"]["beacon"] | false; conf.lora.frequencyRx = data["lora"]["frequency_rx"] | 433775000; conf.lora.gainRx = data["lora"]["gain_rx"] | 0; @@ -145,13 +145,13 @@ void ProjectConfigurationManagement::writeProjectConfiguration(Configuration &co data["beacon"]["position"]["longitude"] = conf.beacon.positionLongitude; data["beacon"]["use_gps"] = conf.beacon.use_gps; data["beacon"]["timeout"] = conf.beacon.timeout; + data["beacon"]["send_on_hf"] = conf.beacon.send_on_hf; data["aprs_is"]["active"] = conf.aprs_is.active; data["aprs_is"]["passcode"] = conf.aprs_is.passcode; data["aprs_is"]["server"] = conf.aprs_is.server; data["aprs_is"]["port"] = conf.aprs_is.port; data["aprs_is"]["filter"] = conf.aprs_is.filter; data["digi"]["active"] = conf.digi.active; - data["digi"]["beacon"] = conf.digi.beacon; data["lora"]["frequency_rx"] = conf.lora.frequencyRx; data["lora"]["gain_rx"] = conf.lora.gainRx; data["lora"]["frequency_tx"] = conf.lora.frequencyTx; diff --git a/src/project_configuration.h b/src/project_configuration.h index 7ca1274..f5d4ad9 100644 --- a/src/project_configuration.h +++ b/src/project_configuration.h @@ -17,6 +17,9 @@ public: class Hostname { public: + Hostname() : overwrite(false) { + } + bool overwrite; String name; }; @@ -48,7 +51,7 @@ public: class Beacon { public: - Beacon() : message("LoRa iGATE & Digi, Info: github.com/peterus/LoRa_APRS_iGate"), positionLatitude(0.0), positionLongitude(0.0), use_gps(false), timeout(15) { + Beacon() : message("LoRa iGATE & Digi, Info: github.com/peterus/LoRa_APRS_iGate"), positionLatitude(0.0), positionLongitude(0.0), use_gps(false), timeout(15), send_on_hf(false) { } String message; @@ -56,6 +59,7 @@ public: double positionLongitude; bool use_gps; int timeout; + bool send_on_hf; }; class APRS_IS { @@ -72,16 +76,15 @@ public: class Digi { public: - Digi() : active(false), beacon(true) { + Digi() : active(false) { } bool active; - bool beacon; }; class LoRa { public: - LoRa() : frequencyRx(433775000), frequencyTx(433775000), power(20), spreadingFactor(12), signalBandwidth(125000), codingRate4(5), tx_enable(true) { + LoRa() : frequencyRx(433775000), gainRx(0), frequencyTx(433775000), power(20), spreadingFactor(12), signalBandwidth(125000), codingRate4(5), tx_enable(true) { } long frequencyRx;