You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
LMIC feature selection (Class C, ADR, region/bandplan -- region will become runtime-selectable)
Radio driver configuration (oscillator trim, RF switch, DCDC, TCXO -- currently SX126x- and SX127x-specific queries live on the shared HalConfiguration_t base class)
SPI/communication channel (pin assignments, SPI frequency -- bundled with radio config in HalPinmap_t)
Secure element configuration (driver selection, key storage -- has its own driver abstraction via LMIC_CFG_SecureElement_DRIVER)
Debug/logging (affects timing; most users don't know how to use it safely)
The radio driver and HAL are pure C (lmic.c, radio_sx126x.c, radio_sx127x.c). hal.cpp is C++ and provides extern "C" bridge functions. This works but means radio-specific configuration queries (e.g., SX126x crystal trim) end up on the shared HalConfiguration_t class where all board files see them.
Desired architecture
Abstract initialization order:
Create OS platform
Create low-level drivers with handles (SPI, I2C, GPIO)
Create radio driver, passing SPI handle, GPIO handles, OS platform
Create SE driver, passing I2C/SPI handle as appropriate
Create LMIC, passing radio and SE driver handles
Key principles:
Radio-specific configuration should live on a radio-specific configuration object, not the shared HAL base class
Low-level operations (GPIO toggles, DIOx queries) should be passed as explicit config vars in a config structure, or as handles to low-level drivers (e.g., "antenna switch" driver)
The SE driver abstraction (LMIC_SecureElement_DECLARE_DRIVER_FNS / LMIC_SecureElement_METHOD pattern) is a reasonable model for driver dispatch
AES implementation selection is a configuration of the default SE driver, not independent
For Arduino, the C++ approach with extern "C" bridges is preferred for end-user convenience (less typing than pure C structs)
Radio driver interface
The radio driver interface (os_radio(), radio_init(), radio_config(), etc.) is currently internal and undocumented as a contract. This needs to be specified as a stable interface to support:
Non-PHY transports (LoRaWAN-over-Meshtastic / LWoM -- replaces the LoRa PHY entirely with Meshtastic packet transport, using soft RX timing and runtime region selection)
Both use cases require a well-defined radio driver contract that survives LMIC internal refactoring (v6.0.0 broke external assumptions by adding os_radio_v2() and changing radio state management).
doc/RadioDriver.md exists and is a starting point, but needs to be promoted to a formal interface specification.
Why this matters
Each new SX126x feature (crystal trim, DIO2/DIO3 config, DCDC) adds radio-specific methods to the shared base class. SX127x board files see SX126x methods and vice versa. As more radio families and non-PHY transports are supported, this becomes increasingly messy.
Scope
This is a major refactor, likely V7. For now, accept SX126x-specific queries on HalConfiguration_t but avoid namespace pollution (no unnecessary header includes).
Summary
Capture design thinking for a future major refactor of the initialization and configuration architecture.
Current state
Configuration is spread across multiple mechanisms without clean separation:
HalConfiguration_tbase class)HalPinmap_t)LMIC_CFG_SecureElement_DRIVER)The radio driver and HAL are pure C (
lmic.c,radio_sx126x.c,radio_sx127x.c).hal.cppis C++ and providesextern "C"bridge functions. This works but means radio-specific configuration queries (e.g., SX126x crystal trim) end up on the sharedHalConfiguration_tclass where all board files see them.Desired architecture
Abstract initialization order:
Key principles:
LMIC_SecureElement_DECLARE_DRIVER_FNS/LMIC_SecureElement_METHODpattern) is a reasonable model for driver dispatchextern "C"bridges is preferred for end-user convenience (less typing than pure C structs)Radio driver interface
The radio driver interface (
os_radio(),radio_init(),radio_config(), etc.) is currently internal and undocumented as a contract. This needs to be specified as a stable interface to support:Both use cases require a well-defined radio driver contract that survives LMIC internal refactoring (v6.0.0 broke external assumptions by adding
os_radio_v2()and changing radio state management).doc/RadioDriver.mdexists and is a starting point, but needs to be promoted to a formal interface specification.Why this matters
Each new SX126x feature (crystal trim, DIO2/DIO3 config, DCDC) adds radio-specific methods to the shared base class. SX127x board files see SX126x methods and vice versa. As more radio families and non-PHY transports are supported, this becomes increasingly messy.
Scope
This is a major refactor, likely V7. For now, accept SX126x-specific queries on
HalConfiguration_tbut avoid namespace pollution (no unnecessary header includes).Related