From d95a9a4620d4942dfaefdabd2ae7e934823b5ae8 Mon Sep 17 00:00:00 2001 From: Thomas Kuschel Date: Sun, 18 Oct 2026 21:08:32 +0200 Subject: [PATCH] lora updates with specific settings --- src/config.hpp | 35 ++++++++++++++++++++++++++++------- src/lora.cpp | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/config.hpp b/src/config.hpp index 333bef8..13473b3 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -50,18 +50,39 @@ namespace Config { constexpr uint32_t LORA_DEFAULT_FREQ_HZ = 433175000; constexpr uint32_t LORA_DEFAULT_BW_KHZ = 250; constexpr uint8_t LORA_DEFAULT_SF = 11; - constexpr uint8_t LORA_DEFAULT_CR = 6; // CR 4/6 -> Nenner ist 6 + constexpr uint8_t LORA_DEFAULT_CR = 6; // CR 4/6 -> Denominator is 6 - // Der Compiler berechnet das 24-Bit Frequenzwort automatisch vor! + // Predefined LoRa Sync Word options for hardware correlation filtering + constexpr uint8_t LORA_SYNC_WORD_PUBLIC_NETWORK_MODE = 0x34; // MeshCom (ÖVSV standard for amateur radio mesh), + // The Things Network, Helium + constexpr uint8_t LORA_SYNC_WORD_TACTICAL_NETWORK_MODE = 0x24; // Meshtastic (Civilian off-grid tactical mesh network) + constexpr uint8_t LORA_SYNC_WORD_PRIVATE_NETWORK_MODE = 0x12; // Semtech Default (Factory default / Private point-to-point) + constexpr uint8_t LORA_SYNC_WORD_CUSTOM_NETWORK_MODE = 0x55; // Custom / Experimental individual networks (highly isolated) + constexpr uint8_t LORA_SYNC_WORD_EXPERIMENTAL_NETWORK_MODE = 0xAA; // Custom / Experimental individual networks (highly isolated) + + // Active hardware synchronization configuration selector + constexpr uint8_t LORA_SYNC_WORD = LORA_SYNC_WORD_PUBLIC_NETWORK_MODE; // Selected default synchronization profile + + // Expand hardware preamble length to 12 symbols for robust network correlation (MeshCom value) + constexpr uint8_t LORA_PREAMBLE_LENGTH_LSB = 0x0C; // Semtech Factor Default is 0x08 + + // The compiler automatically pre-calculates the 24-bit frequency word at compile-time! constexpr uint64_t LORA_FRF_CALC = ((uint64_t)LORA_DEFAULT_FREQ_HZ << 19) / 32000000ULL; constexpr uint8_t LORA_FRF_MSB = static_cast((LORA_FRF_CALC >> 16) & 0xFFU); constexpr uint8_t LORA_FRF_MID = static_cast((LORA_FRF_CALC >> 8) & 0xFFU); constexpr uint8_t LORA_FRF_LSB = static_cast(LORA_FRF_CALC & 0xFFU); - // Berechne die Register-Hexwerte dynamisch basierend auf den obigen Angaben - // BW: 250kHz -> 0x08. Shiften um 4 Bits nach links = 0x80. Coding Rate 4/6 -> 6-4 = 2 -> (2 << 1) = 0x04. Gesamt = 0x84. - constexpr uint8_t LORA_MODEM_CONFIG_1 = 0x84; - // SF11 -> 0x0B. Shiften um 4 Bits nach links = 0xB0. CRC On = 0x04. Gesamt = 0xB4. - constexpr uint8_t LORA_MODEM_CONFIG_2 = 0xB4; + // --- DYNAMIC COMPILE-TIME BIT-SHIFTING EXPRESSIONS --- + // Helper to map bandwidth kHz to Semtech Register Bits (7-4 of RegModemConfig1) + constexpr uint8_t LORA_BW_REG_VAL = (LORA_DEFAULT_BW_KHZ == 62) ? 0x06 : + (LORA_DEFAULT_BW_KHZ == 125) ? 0x07 : + (LORA_DEFAULT_BW_KHZ == 250) ? 0x08 : + (LORA_DEFAULT_BW_KHZ == 500) ? 0x09 : 0x08; + + // RegModemConfig1 (0x1D): Bandwidth (Bits 7-4), Coding Rate (Bits 3-1), ImplicitHeader (Bit 0 = 0) + constexpr uint8_t LORA_MODEM_CONFIG_1 = static_cast((LORA_BW_REG_VAL << 4) | ((LORA_DEFAULT_CR - 4) << 1)); + + // RegModemConfig2 (0x1E): Spreading Factor (Bits 7-4), TxContinuous (Bit 3 = 0), RxPayloadCrcOn (Bit 2 = 1) + constexpr uint8_t LORA_MODEM_CONFIG_2 = static_cast((LORA_DEFAULT_SF << 4) | 0x04U); } diff --git a/src/lora.cpp b/src/lora.cpp index 3fc4df0..c4c966e 100644 --- a/src/lora.cpp +++ b/src/lora.cpp @@ -26,6 +26,12 @@ LoraController::LoraController() { if (m_isrSemaphore == nullptr || m_stateMutex == nullptr) { ESP_LOGE(TAG, "Fatal: Failed to allocate LoRa synchronization primitives."); + return; + } + + esp_err_t err = initializeHardware(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Fatal: Hardware initialization failed in constructor!"); } } @@ -201,6 +207,21 @@ esp_err_t LoraController::initializeHardware() { writeRegister(0x1D, Config::LORA_MODEM_CONFIG_1); writeRegister(0x1E, Config::LORA_MODEM_CONFIG_2); + // --- APPLY SELECTED MESHCOM / NETWORK SYNC PROFILE --- + writeRegister(0x39, Config::LORA_SYNC_WORD); // Write the dynamic sync word byte + + // Expand hardware preamble length to 12 symbols for robust network correlation + writeRegister(0x20, 0x00U); // RegPreambleMsb - default + writeRegister(0x21, Config::LORA_PREAMBLE_LENGTH_LSB); // RegPreambleLsb (12 = 0x0C) - Default start is 0x08 + + // --- UNMASK INTERRUPTS ON THE SEMTECH TRANSCEIVER --- + // Clear all bits in RegIrqFlagsMask (0x11) to enable all hardware interrupt events. + // Note: A set bit (1) in this register would mask (disable) the corresponding interrupt. + writeRegister(0x11, 0x00U); + + // Clear any stale interrupt flags to flush the physical DIO0 line back to logic low + writeRegister(0x12, 0xFFU); + // Zustand thread-sicher als betriebsbereit markieren if (xSemaphoreTake(m_stateMutex, portMAX_DELAY) == pdTRUE) { m_state.isInitialized = true; @@ -633,7 +654,21 @@ void LoraController::startTask(uint32_t priority) { • @brief Primary operational processing thread executing real-time ISR evaluation workflows. */ void LoraController::run() { - if (initializeHardware() != ESP_OK) return; + //if (initializeHardware() != ESP_OK) return; // moved to the constructor + + // Check if hardware is ready + bool init_success = false; + if (xSemaphoreTake(m_stateMutex, portMAX_DELAY) == pdTRUE) { + init_success = m_state.isInitialized; + xSemaphoreGive(m_stateMutex); + } + + if (!init_success) { + ESP_LOGE(TAG, "Engine abort: Hardware not initialized."); + vTaskDelete(nullptr); + return; + } + setModeReceiver(); extern DisplayController* display;