diff --git a/.clusterfuzzlite/router_fuzzer.cpp b/.clusterfuzzlite/router_fuzzer.cpp index bc4d248db..71e88dbff 100644 --- a/.clusterfuzzlite/router_fuzzer.cpp +++ b/.clusterfuzzlite/router_fuzzer.cpp @@ -76,7 +76,7 @@ bool loopCanSleep() // Called just prior to starting Meshtastic. Allows for setting config values before startup. void lateInitVariant() { - settingsMap[logoutputlevel] = level_error; + portduino_config.logoutputlevel = level_error; channelFile.channels[0] = meshtastic_Channel{ .has_settings = true, .settings = @@ -132,7 +132,7 @@ int portduino_main(int argc, char **argv); // Renamed "main" function from Mesht // Start Meshtastic in a thread and wait till it has reached the ON state. int LLVMFuzzerInitialize(int *argc, char ***argv) { - settingsMap[maxtophone] = 5; + portduino_config.maxtophone = 5; meshtasticThread = std::thread([program = *argv[0]]() { char nodeIdStr[12]; diff --git a/src/DebugConfiguration.cpp b/src/DebugConfiguration.cpp index 1c081ae29..d65c4f1e8 100644 --- a/src/DebugConfiguration.cpp +++ b/src/DebugConfiguration.cpp @@ -146,7 +146,7 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess { int result; #ifdef ARCH_PORTDUINO - bool utf = !settingsMap[ascii_logs]; + bool utf = !portduino_config.ascii_logs; #else bool utf = true; #endif diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 7c8d77651..efab84399 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -57,7 +57,7 @@ size_t RedirectablePrint::vprintf(const char *logLevel, const char *format, va_l #endif #ifdef ARCH_PORTDUINO - bool color = !settingsMap[ascii_logs]; + bool color = !portduino_config.ascii_logs; #else bool color = true; #endif @@ -99,7 +99,7 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format, size_t r = 0; #ifdef ARCH_PORTDUINO - bool color = !settingsMap[ascii_logs]; + bool color = !portduino_config.ascii_logs; #else bool color = true; #endif @@ -288,7 +288,7 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...) #if ARCH_PORTDUINO // level trace is special, two possible ways to handle it. if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) { - if (settingsStrings[traceFilename] != "") { + if (portduino_config.traceFilename != "") { va_list arg; va_start(arg, format); try { @@ -297,18 +297,18 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...) } va_end(arg); } - if (settingsMap[logoutputlevel] < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) { + if (portduino_config.logoutputlevel < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) { delete[] newFormat; return; } } - if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) { + if (portduino_config.logoutputlevel < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) { delete[] newFormat; return; - } else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) { + } else if (portduino_config.logoutputlevel < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) { delete[] newFormat; return; - } else if (settingsMap[logoutputlevel] < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) { + } else if (portduino_config.logoutputlevel < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) { delete[] newFormat; return; } diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 9ae7ae97d..b23109268 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1422,7 +1422,7 @@ GPS *GPS::createGps() _en_gpio = PIN_GPS_EN; #endif #ifdef ARCH_PORTDUINO - if (!settingsMap[has_gps]) + if (!portduino_config.has_gps) return nullptr; #endif if (!_rx_gpio || !_serial_gps) // Configured to have no GPS at all diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 76c423133..3e45bed45 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -370,7 +370,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE); #elif ARCH_PORTDUINO if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { - if (settingsMap[displayPanel] != no_screen) { + if (portduino_config.displayPanel != no_screen) { LOG_DEBUG("Make TFTDisplay!"); dispdev = new TFTDisplay(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE); @@ -618,7 +618,7 @@ void Screen::setup() #if ARCH_PORTDUINO if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { - if (settingsMap[touchscreenModule]) { + if (portduino_config.touchscreenModule) { touchScreenImpl1 = new TouchScreenImpl1(dispdev->getWidth(), dispdev->getHeight(), static_cast(dispdev)->getTouch); touchScreenImpl1->init(); diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index b1814005e..08acc3e55 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -767,24 +767,24 @@ class LGFX : public lgfx::LGFX_Device LGFX(void) { - if (settingsMap[displayPanel] == st7789) + if (portduino_config.displayPanel == st7789) _panel_instance = new lgfx::Panel_ST7789; - else if (settingsMap[displayPanel] == st7735) + else if (portduino_config.displayPanel == st7735) _panel_instance = new lgfx::Panel_ST7735; - else if (settingsMap[displayPanel] == st7735s) + else if (portduino_config.displayPanel == st7735s) _panel_instance = new lgfx::Panel_ST7735S; - else if (settingsMap[displayPanel] == st7796) + else if (portduino_config.displayPanel == st7796) _panel_instance = new lgfx::Panel_ST7796; - else if (settingsMap[displayPanel] == ili9341) + else if (portduino_config.displayPanel == ili9341) _panel_instance = new lgfx::Panel_ILI9341; - else if (settingsMap[displayPanel] == ili9342) + else if (portduino_config.displayPanel == ili9342) _panel_instance = new lgfx::Panel_ILI9342; - else if (settingsMap[displayPanel] == ili9488) + else if (portduino_config.displayPanel == ili9488) _panel_instance = new lgfx::Panel_ILI9488; - else if (settingsMap[displayPanel] == hx8357d) + else if (portduino_config.displayPanel == hx8357d) _panel_instance = new lgfx::Panel_HX8357D; #if defined(LGFX_SDL) - else if (settingsMap[displayPanel] == x11) { + else if (portduino_config.displayPanel == x11) { _panel_instance = new lgfx::Panel_sdl; } #endif @@ -795,61 +795,61 @@ class LGFX : public lgfx::LGFX_Device auto buscfg = _bus_instance.config(); buscfg.spi_mode = 0; - buscfg.spi_host = settingsMap[displayspidev]; + buscfg.spi_host = portduino_config.display_spi_dev_int; - buscfg.pin_dc = settingsMap[displayDC]; // Set SPI DC pin number (-1 = disable) + buscfg.pin_dc = portduino_config.displayDC.pin; // Set SPI DC pin number (-1 = disable) _bus_instance.config(buscfg); // applies the set value to the bus. _panel_instance->setBus(&_bus_instance); // set the bus on the panel. auto cfg = _panel_instance->config(); // Gets a structure for display panel settings. - LOG_DEBUG("Width: %d, Height: %d", settingsMap[displayWidth], settingsMap[displayHeight]); - cfg.pin_cs = settingsMap[displayCS]; // Pin number where CS is connected (-1 = disable) - cfg.pin_rst = settingsMap[displayReset]; - if (settingsMap[displayRotate]) { - cfg.panel_width = settingsMap[displayHeight]; // actual displayable width - cfg.panel_height = settingsMap[displayWidth]; // actual displayable height + LOG_DEBUG("Width: %d, Height: %d", portduino_config.displayWidth, portduino_config.displayHeight); + cfg.pin_cs = portduino_config.displayCS.pin; // Pin number where CS is connected (-1 = disable) + cfg.pin_rst = portduino_config.displayReset.pin; + if (portduino_config.displayRotate) { + cfg.panel_width = portduino_config.displayHeight; // actual displayable width + cfg.panel_height = portduino_config.displayWidth; // actual displayable height } else { - cfg.panel_width = settingsMap[displayWidth]; // actual displayable width - cfg.panel_height = settingsMap[displayHeight]; // actual displayable height + cfg.panel_width = portduino_config.displayWidth; // actual displayable width + cfg.panel_height = portduino_config.displayHeight; // actual displayable height } - cfg.offset_x = settingsMap[displayOffsetX]; // Panel offset amount in X direction - cfg.offset_y = settingsMap[displayOffsetY]; // Panel offset amount in Y direction - cfg.offset_rotation = settingsMap[displayOffsetRotate]; // Rotation direction value offset 0~7 (4~7 is mirrored) - cfg.invert = settingsMap[displayInvert]; // Set to true if the light/darkness of the panel is reversed + cfg.offset_x = portduino_config.displayOffsetX; // Panel offset amount in X direction + cfg.offset_y = portduino_config.displayOffsetY; // Panel offset amount in Y direction + cfg.offset_rotation = portduino_config.displayOffsetRotate; // Rotation direction value offset 0~7 (4~7 is mirrored) + cfg.invert = portduino_config.displayInvert; // Set to true if the light/darkness of the panel is reversed _panel_instance->config(cfg); // Configure settings for touch control. - if (settingsMap[touchscreenModule]) { - if (settingsMap[touchscreenModule] == xpt2046) { + if (portduino_config.touchscreenModule) { + if (portduino_config.touchscreenModule == xpt2046) { _touch_instance = new lgfx::Touch_XPT2046; - } else if (settingsMap[touchscreenModule] == stmpe610) { + } else if (portduino_config.touchscreenModule == stmpe610) { _touch_instance = new lgfx::Touch_STMPE610; - } else if (settingsMap[touchscreenModule] == ft5x06) { + } else if (portduino_config.touchscreenModule == ft5x06) { _touch_instance = new lgfx::Touch_FT5x06; } auto touch_cfg = _touch_instance->config(); - touch_cfg.pin_cs = settingsMap[touchscreenCS]; + touch_cfg.pin_cs = portduino_config.touchscreenCS.pin; touch_cfg.x_min = 0; - touch_cfg.x_max = settingsMap[displayHeight] - 1; + touch_cfg.x_max = portduino_config.displayHeight - 1; touch_cfg.y_min = 0; - touch_cfg.y_max = settingsMap[displayWidth] - 1; - touch_cfg.pin_int = settingsMap[touchscreenIRQ]; + touch_cfg.y_max = portduino_config.displayWidth - 1; + touch_cfg.pin_int = portduino_config.touchscreenIRQ.pin; touch_cfg.bus_shared = true; - touch_cfg.offset_rotation = settingsMap[touchscreenRotate]; - if (settingsMap[touchscreenI2CAddr] != -1) { - touch_cfg.i2c_addr = settingsMap[touchscreenI2CAddr]; + touch_cfg.offset_rotation = portduino_config.touchscreenRotate; + if (portduino_config.touchscreenI2CAddr != -1) { + touch_cfg.i2c_addr = portduino_config.touchscreenI2CAddr; } else { - touch_cfg.spi_host = settingsMap[touchscreenspidev]; + touch_cfg.spi_host = portduino_config.touchscreen_spi_dev_int; } _touch_instance->config(touch_cfg); _panel_instance->setTouch(_touch_instance); } #if defined(LGFX_SDL) - if (settingsMap[displayPanel] == x11) { + if (portduino_config.displayPanel == x11) { lgfx::Panel_sdl *sdl_panel_ = (lgfx::Panel_sdl *)_panel_instance; sdl_panel_->setup(); sdl_panel_->addKeyCodeMapping(SDLK_RETURN, SDL_SCANCODE_KP_ENTER); @@ -1115,10 +1115,10 @@ TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY g backlightEnable = p; #if ARCH_PORTDUINO - if (settingsMap[displayRotate]) { - setGeometry(GEOMETRY_RAWMODE, settingsMap[configNames::displayWidth], settingsMap[configNames::displayHeight]); + if (portduino_config.displayRotate) { + setGeometry(GEOMETRY_RAWMODE, portduino_config.displayWidth, portduino_config.displayWidth); } else { - setGeometry(GEOMETRY_RAWMODE, settingsMap[configNames::displayHeight], settingsMap[configNames::displayWidth]); + setGeometry(GEOMETRY_RAWMODE, portduino_config.displayHeight, portduino_config.displayHeight); } #elif defined(SCREEN_ROTATE) @@ -1231,7 +1231,7 @@ void TFTDisplay::sdlLoop() #if defined(LGFX_SDL) static int lastPressed = 0; static int shuttingDown = false; - if (settingsMap[displayPanel] == x11) { + if (portduino_config.displayPanel == x11) { lgfx::Panel_sdl *sdl_panel_ = (lgfx::Panel_sdl *)tft->_panel_instance; if (sdl_panel_->loop() && !shuttingDown) { LOG_WARN("Window Closed!"); @@ -1279,8 +1279,8 @@ void TFTDisplay::sendCommand(uint8_t com) backlightEnable->set(true); #if ARCH_PORTDUINO display(true); - if (settingsMap[displayBacklight] > 0) - digitalWrite(settingsMap[displayBacklight], TFT_BACKLIGHT_ON); + if (portduino_config.displayBacklight.pin > 0) + digitalWrite(portduino_config.displayBacklight.pin, TFT_BACKLIGHT_ON); #elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) tft->wakeup(); tft->powerSaveOff(); @@ -1303,8 +1303,8 @@ void TFTDisplay::sendCommand(uint8_t com) backlightEnable->set(false); #if ARCH_PORTDUINO tft->clear(); - if (settingsMap[displayBacklight] > 0) - digitalWrite(settingsMap[displayBacklight], !TFT_BACKLIGHT_ON); + if (portduino_config.displayBacklight.pin > 0) + digitalWrite(portduino_config.displayBacklight.pin, !TFT_BACKLIGHT_ON); #elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) tft->sleep(); tft->powerSaveOn(); diff --git a/src/graphics/tftSetup.cpp b/src/graphics/tftSetup.cpp index b2e92bdae..5654fa02a 100644 --- a/src/graphics/tftSetup.cpp +++ b/src/graphics/tftSetup.cpp @@ -41,78 +41,78 @@ void tftSetup(void) PacketAPI::create(PacketServer::init()); deviceScreen->init(new PacketClient); #else - if (settingsMap[displayPanel] != no_screen) { + if (portduino_config.displayPanel != no_screen) { DisplayDriverConfig displayConfig; static char *panels[] = {"NOSCREEN", "X11", "FB", "ST7789", "ST7735", "ST7735S", "ST7796", "ILI9341", "ILI9342", "ILI9486", "ILI9488", "HX8357D"}; static char *touch[] = {"NOTOUCH", "XPT2046", "STMPE610", "GT911", "FT5x06"}; #if defined(USE_X11) - if (settingsMap[displayPanel] == x11) { - if (settingsMap[displayWidth] && settingsMap[displayHeight]) - displayConfig = DisplayDriverConfig(DisplayDriverConfig::device_t::X11, (uint16_t)settingsMap[displayWidth], - (uint16_t)settingsMap[displayHeight]); + if (portduino_config.displayPanel == x11) { + if (portduino_config.displayWidth && portduino_config.displayHeight) + displayConfig = DisplayDriverConfig(DisplayDriverConfig::device_t::X11, (uint16_t)portduino_config.displayWidth, + (uint16_t)portduino_config.displayHeight); else displayConfig.device(DisplayDriverConfig::device_t::X11); } else #elif defined(USE_FRAMEBUFFER) - if (settingsMap[displayPanel] == fb) { - if (settingsMap[displayWidth] && settingsMap[displayHeight]) - displayConfig = DisplayDriverConfig(DisplayDriverConfig::device_t::FB, (uint16_t)settingsMap[displayWidth], - (uint16_t)settingsMap[displayHeight]); + if (portduino_config.displayPanel == fb) { + if (portduino_config.displayWidth && portduino_config.displayHeight) + displayConfig = DisplayDriverConfig(DisplayDriverConfig::device_t::FB, (uint16_t)portduino_config.displayWidth, + (uint16_t)portduino_config.displayHeight); else displayConfig.device(DisplayDriverConfig::device_t::FB); } else #endif { displayConfig.device(DisplayDriverConfig::device_t::CUSTOM_TFT) - .panel(DisplayDriverConfig::panel_config_t{.type = panels[settingsMap[displayPanel]], - .panel_width = (uint16_t)settingsMap[displayWidth], - .panel_height = (uint16_t)settingsMap[displayHeight], - .rotation = (bool)settingsMap[displayRotate], - .pin_cs = (int16_t)settingsMap[displayCS], - .pin_rst = (int16_t)settingsMap[displayReset], - .offset_x = (uint16_t)settingsMap[displayOffsetX], - .offset_y = (uint16_t)settingsMap[displayOffsetY], - .offset_rotation = (uint8_t)settingsMap[displayOffsetRotate], - .invert = settingsMap[displayInvert] ? true : false, - .rgb_order = (bool)settingsMap[displayRGBOrder], - .dlen_16bit = settingsMap[displayPanel] == ili9486 || - settingsMap[displayPanel] == ili9488}) - .bus(DisplayDriverConfig::bus_config_t{.freq_write = (uint32_t)settingsMap[displayBusFrequency], + .panel(DisplayDriverConfig::panel_config_t{.type = panels[portduino_config.displayPanel], + .panel_width = (uint16_t)portduino_config.displayWidth, + .panel_height = (uint16_t)portduino_config.displayHeight, + .rotation = (bool)portduino_config.displayRotate, + .pin_cs = (int16_t)portduino_config.displayCS.pin, + .pin_rst = (int16_t)portduino_config.displayReset.pin, + .offset_x = (uint16_t)portduino_config.displayOffsetX, + .offset_y = (uint16_t)portduino_config.displayOffsetY, + .offset_rotation = (uint8_t)portduino_config.displayOffsetRotate, + .invert = portduino_config.displayInvert ? true : false, + .rgb_order = (bool)portduino_config.displayRGBOrder, + .dlen_16bit = portduino_config.displayPanel == ili9486 || + portduino_config.displayPanel == ili9488}) + .bus(DisplayDriverConfig::bus_config_t{.freq_write = (uint32_t)portduino_config.displayBusFrequency, .freq_read = 16000000, - .spi{.pin_dc = (int8_t)settingsMap[displayDC], + .spi{.pin_dc = (int8_t)portduino_config.displayDC.pin, .use_lock = true, - .spi_host = (uint16_t)settingsMap[displayspidev]}}) - .input(DisplayDriverConfig::input_config_t{.keyboardDevice = settingsStrings[keyboardDevice], - .pointerDevice = settingsStrings[pointerDevice]}) - .light(DisplayDriverConfig::light_config_t{.pin_bl = (int16_t)settingsMap[displayBacklight], - .pwm_channel = (int8_t)settingsMap[displayBacklightPWMChannel], - .invert = (bool)settingsMap[displayBacklightInvert]}); - if (settingsMap[touchscreenI2CAddr] == -1) { + .spi_host = (uint16_t)portduino_config.display_spi_dev_int}}) + .input(DisplayDriverConfig::input_config_t{.keyboardDevice = portduino_config.keyboardDevice, + .pointerDevice = portduino_config.pointerDevice}) + .light(DisplayDriverConfig::light_config_t{.pin_bl = (int16_t)portduino_config.displayBacklight.pin, + .pwm_channel = (int8_t)portduino_config.displayBacklightPWMChannel.pin, + .invert = (bool)portduino_config.displayBacklightInvert}); + if (portduino_config.touchscreenI2CAddr == -1) { displayConfig.touch( - DisplayDriverConfig::touch_config_t{.type = touch[settingsMap[touchscreenModule]], - .freq = (uint32_t)settingsMap[touchscreenBusFrequency], - .pin_int = (int16_t)settingsMap[touchscreenIRQ], - .offset_rotation = (uint8_t)settingsMap[touchscreenRotate], + DisplayDriverConfig::touch_config_t{.type = touch[portduino_config.touchscreenModule], + .freq = (uint32_t)portduino_config.touchscreenBusFrequency, + .pin_int = (int16_t)portduino_config.touchscreenIRQ.pin, + .offset_rotation = (uint8_t)portduino_config.touchscreenRotate, .spi{ - .spi_host = (int8_t)settingsMap[touchscreenspidev], + .spi_host = (int8_t)portduino_config.touchscreen_spi_dev_int, }, - .pin_cs = (int16_t)settingsMap[touchscreenCS]}); + .pin_cs = (int16_t)portduino_config.touchscreenCS.pin}); } else { displayConfig.touch(DisplayDriverConfig::touch_config_t{ - .type = touch[settingsMap[touchscreenModule]], - .freq = (uint32_t)settingsMap[touchscreenBusFrequency], + .type = touch[portduino_config.touchscreenModule], + .freq = (uint32_t)portduino_config.touchscreenBusFrequency, .x_min = 0, - .x_max = - (int16_t)((settingsMap[touchscreenRotate] & 1 ? settingsMap[displayWidth] : settingsMap[displayHeight]) - - 1), + .x_max = (int16_t)((portduino_config.touchscreenRotate & 1 ? portduino_config.displayWidth + : portduino_config.displayHeight) - + 1), .y_min = 0, - .y_max = - (int16_t)((settingsMap[touchscreenRotate] & 1 ? settingsMap[displayHeight] : settingsMap[displayWidth]) - - 1), - .pin_int = (int16_t)settingsMap[touchscreenIRQ], - .offset_rotation = (uint8_t)settingsMap[touchscreenRotate], - .i2c{.i2c_addr = (uint8_t)settingsMap[touchscreenI2CAddr]}}); + .y_max = (int16_t)((portduino_config.touchscreenRotate & 1 ? portduino_config.displayHeight + : portduino_config.displayWidth) - + 1), + .pin_int = (int16_t)portduino_config.touchscreenIRQ.pin, + .offset_rotation = (uint8_t)portduino_config.touchscreenRotate, + .i2c{.i2c_addr = (uint8_t)portduino_config.touchscreenI2CAddr}}); } } deviceScreen = &DeviceScreen::create(&displayConfig); diff --git a/src/input/LinuxInput.cpp b/src/input/LinuxInput.cpp index 90f06ecc9..1f80fd5d3 100644 --- a/src/input/LinuxInput.cpp +++ b/src/input/LinuxInput.cpp @@ -33,9 +33,9 @@ int32_t LinuxInput::runOnce() { if (firstTime) { - if (settingsStrings[keyboardDevice] == "") + if (portduino_config.keyboardDevice == "") return disable(); - fd = open(settingsStrings[keyboardDevice].c_str(), O_RDWR); + fd = open(portduino_config.keyboardDevice.c_str(), O_RDWR); if (fd < 0) return disable(); ret = ioctl(fd, EVIOCGRAB, (void *)1); diff --git a/src/input/TouchScreenImpl1.cpp b/src/input/TouchScreenImpl1.cpp index cea47faeb..c0e220941 100644 --- a/src/input/TouchScreenImpl1.cpp +++ b/src/input/TouchScreenImpl1.cpp @@ -18,7 +18,7 @@ TouchScreenImpl1::TouchScreenImpl1(uint16_t width, uint16_t height, bool (*getTo void TouchScreenImpl1::init() { #if ARCH_PORTDUINO - if (settingsMap[touchscreenModule]) { + if (portduino_config.touchscreenModule) { TouchScreenBase::init(true); inputBroker->registerSource(this); } else { diff --git a/src/input/TrackballInterruptBase.h b/src/input/TrackballInterruptBase.h index 38be22f20..76a99f33d 100644 --- a/src/input/TrackballInterruptBase.h +++ b/src/input/TrackballInterruptBase.h @@ -6,7 +6,7 @@ #ifndef TB_DIRECTION #if ARCH_PORTDUINO #include "PortduinoGlue.h" -#define TB_DIRECTION (PinStatus) settingsMap[tbDirection] +#define TB_DIRECTION (PinStatus) portduino_config.lora_usb_vid #else #define TB_DIRECTION RISING #endif diff --git a/src/main.cpp b/src/main.cpp index 73f68e95e..5b223a824 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -390,7 +390,7 @@ void setup() concurrency::hasBeenSetup = true; #if ARCH_PORTDUINO - SPISettings spiSettings(settingsMap[spiSpeed], MSBFIRST, SPI_MODE0); + SPISettings spiSettings(portduino_config.spiSpeed, MSBFIRST, SPI_MODE0); #else SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0); #endif @@ -535,9 +535,9 @@ void setup() #elif defined(I2C_SDA) && !defined(ARCH_RP2040) Wire.begin(I2C_SDA, I2C_SCL); #elif defined(ARCH_PORTDUINO) - if (settingsStrings[i2cdev] != "") { - LOG_INFO("Use %s as I2C device", settingsStrings[i2cdev].c_str()); - Wire.begin(settingsStrings[i2cdev].c_str()); + if (portduino_config.i2cdev != "") { + LOG_INFO("Use %s as I2C device", portduino_config.i2cdev.c_str()); + Wire.begin(portduino_config.i2cdev.c_str()); } else { LOG_INFO("No I2C device configured, Skip"); } @@ -583,7 +583,7 @@ void setup() #if defined(I2C_SDA) i2cScanner->scanPort(ScanI2C::I2CPort::WIRE); #elif defined(ARCH_PORTDUINO) - if (settingsStrings[i2cdev] != "") { + if (portduino_config.i2cdev != "") { LOG_INFO("Scan for i2c devices"); i2cScanner->scanPort(ScanI2C::I2CPort::WIRE); } @@ -855,7 +855,7 @@ void setup() SPI.begin(false); #endif // HW_SPI1_DEVICE #elif ARCH_PORTDUINO - if (settingsStrings[spidev] != "ch341") { + if (portduino_config.lora_spi_dev != "ch341") { SPI.begin(); } #elif !defined(ARCH_ESP32) // ARCH_RP2040 @@ -881,7 +881,7 @@ void setup() defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(ST7796_CS) screen = new graphics::Screen(screen_found, screen_model, screen_geometry); #elif defined(ARCH_PORTDUINO) - if ((screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) && + if ((screen_found.port != ScanI2C::I2CPort::NO_I2C || portduino_config.displayPanel) && config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { screen = new graphics::Screen(screen_found, screen_model, screen_geometry); } @@ -982,13 +982,13 @@ void setup() #endif #if defined(ARCH_PORTDUINO) - if (settingsMap.count(userButtonPin) != 0 && settingsMap[userButtonPin] != RADIOLIB_NC) { + if (portduino_config.userButtonPin.enabled) { - LOG_DEBUG("Use GPIO%02d for button", settingsMap[userButtonPin]); + LOG_DEBUG("Use GPIO%02d for button", portduino_config.userButtonPin.pin); UserButtonThread = new ButtonThread("UserButton"); if (screen) { ButtonConfig config; - config.pinNumber = (uint8_t)settingsMap[userButtonPin]; + config.pinNumber = (uint8_t)portduino_config.userButtonPin.pin; config.activeLow = true; config.activePullup = true; config.pullupSense = INPUT_PULLUP; @@ -1145,7 +1145,7 @@ void setup() if (screen) screen->setup(); #elif defined(ARCH_PORTDUINO) - if ((screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) && + if ((screen_found.port != ScanI2C::I2CPort::NO_I2C || portduino_config.displayPanel) && config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { screen->setup(); } @@ -1161,15 +1161,10 @@ void setup() #endif #ifdef ARCH_PORTDUINO - const struct { - configNames cfgName; - std::string strName; - } loraModules[] = {{use_rf95, "RF95"}, {use_sx1262, "sx1262"}, {use_sx1268, "sx1268"}, {use_sx1280, "sx1280"}, - {use_lr1110, "lr1110"}, {use_lr1120, "lr1120"}, {use_lr1121, "lr1121"}, {use_llcc68, "LLCC68"}}; // as one can't use a function pointer to the class constructor: - auto loraModuleInterface = [](configNames cfgName, LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, - RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy) { - switch (cfgName) { + auto loraModuleInterface = [](LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) { + switch (portduino_config.lora_module) { case use_rf95: return (RadioInterface *)new RF95Interface(hal, cs, irq, rst, busy); case use_sx1262: @@ -1186,31 +1181,34 @@ void setup() return (RadioInterface *)new LR1121Interface(hal, cs, irq, rst, busy); case use_llcc68: return (RadioInterface *)new LLCC68Interface(hal, cs, irq, rst, busy); + case use_simradio: + return (RadioInterface *)new SimRadio; default: assert(0); // shouldn't happen return (RadioInterface *)nullptr; } }; - for (auto &loraModule : loraModules) { - if (settingsMap[loraModule.cfgName] && !rIf) { - LOG_DEBUG("Activate %s radio on SPI port %s", loraModule.strName.c_str(), settingsStrings[spidev].c_str()); - if (settingsStrings[spidev] == "ch341") { - RadioLibHAL = ch341Hal; - } else { - RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); - } - rIf = loraModuleInterface(loraModule.cfgName, (LockingArduinoHal *)RadioLibHAL, settingsMap[cs_pin], - settingsMap[irq_pin], settingsMap[reset_pin], settingsMap[busy_pin]); - if (!rIf->init()) { - LOG_WARN("No %s radio", loraModule.strName.c_str()); - delete rIf; - rIf = NULL; - exit(EXIT_FAILURE); - } else { - LOG_INFO("%s init success", loraModule.strName.c_str()); - } - } + + LOG_DEBUG("Activate %s radio on SPI port %s", portduino_config.loraModules[portduino_config.lora_module].c_str(), + portduino_config.lora_spi_dev.c_str()); + if (portduino_config.lora_spi_dev == "ch341") { + RadioLibHAL = ch341Hal; + } else { + RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); } + rIf = + loraModuleInterface((LockingArduinoHal *)RadioLibHAL, portduino_config.lora_cs_pin.pin, portduino_config.lora_irq_pin.pin, + portduino_config.lora_reset_pin.pin, portduino_config.lora_busy_pin.pin); + + if (!rIf->init()) { + LOG_WARN("No %s radio", portduino_config.loraModules[portduino_config.lora_module].c_str()); + delete rIf; + rIf = NULL; + exit(EXIT_FAILURE); + } else { + LOG_INFO("%s init success", portduino_config.loraModules[portduino_config.lora_module].c_str()); + } + #elif defined(HW_SPI1_DEVICE) LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings); #else // HW_SPI1_DEVICE @@ -1232,20 +1230,6 @@ void setup() } #endif -#if defined(ARCH_PORTDUINO) - if (!rIf) { - rIf = new SimRadio; - if (!rIf->init()) { - LOG_WARN("No simulated radio"); - delete rIf; - rIf = NULL; - } else { - LOG_INFO("Use SIMULATED radio!"); - radioType = SIM_RADIO; - } - } -#endif - #if defined(RF95_IRQ) && RADIOLIB_EXCLUDE_SX127X != 1 if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) { rIf = new RF95Interface(RadioLibHAL, LORA_CS, RF95_IRQ, RF95_RESET, RF95_DIO1); @@ -1460,7 +1444,7 @@ void setup() #ifdef ARCH_PORTDUINO #if __has_include() - if (settingsMap[webserverport] != -1) { + if (portduino_config.webserverport != -1) { piwebServerThread = new PiWebServerThread(); std::atexit([] { delete piwebServerThread; }); } diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp index a0d992c42..f83522c8b 100644 --- a/src/mesh/LR11x0Interface.cpp +++ b/src/mesh/LR11x0Interface.cpp @@ -21,7 +21,7 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { // Particular boards might define a different max power based on what their hardware can do, default to max power output if not // specified (may be dangerous if using external PA and LR11x0 power config forgotten) #if ARCH_PORTDUINO -#define LR1110_MAX_POWER settingsMap[lr1110_max_power] +#define LR1110_MAX_POWER portduino_config.lr1110_max_power #endif #ifndef LR1110_MAX_POWER #define LR1110_MAX_POWER 22 @@ -30,7 +30,7 @@ static const Module::RfSwitchMode_t rfswitch_table[] = { // the 2.4G part maxes at 13dBm #if ARCH_PORTDUINO -#define LR1120_MAX_POWER settingsMap[lr1120_max_power] +#define LR1120_MAX_POWER portduino_config.lr1120_max_power #endif #ifndef LR1120_MAX_POWER #define LR1120_MAX_POWER 13 @@ -55,7 +55,7 @@ template bool LR11x0Interface::init() #endif #if ARCH_PORTDUINO - float tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000; + float tcxoVoltage = (float)portduino_config.dio3_tcxo_voltage / 1000; // FIXME: correct logic to default to not using TCXO if no voltage is specified for LR11x0_DIO3_TCXO_VOLTAGE #elif !defined(LR11X0_DIO3_TCXO_VOLTAGE) float tcxoVoltage = diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index c8eba1b2e..2ab6fda59 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -673,7 +673,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false) #endif #elif ARCH_PORTDUINO bool hasScreen = false; - if (settingsMap[displayPanel]) + if (portduino_config.displayPanel) hasScreen = true; else hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C; @@ -1334,8 +1334,8 @@ void NodeDB::loadFromDisk() } #if ARCH_PORTDUINO // set any config overrides - if (settingsMap[has_configDisplayMode]) { - config.display.displaymode = (_meshtastic_Config_DisplayConfig_DisplayMode)settingsMap[configDisplayMode]; + if (portduino_config.has_configDisplayMode) { + config.display.displaymode = (_meshtastic_Config_DisplayConfig_DisplayMode)portduino_config.configDisplayMode; } #endif diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index 97f21fc34..0f32f3427 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -10,7 +10,7 @@ #endif #if ARCH_PORTDUINO -#define RF95_MAX_POWER settingsMap[rf95_max_power] +#define RF95_MAX_POWER portduino_config.rf95_max_power #endif #ifndef RF95_MAX_POWER #define RF95_MAX_POWER 20 @@ -94,16 +94,16 @@ void RF95Interface::setTransmitEnable(bool txon) #ifdef RF95_TXEN digitalWrite(RF95_TXEN, txon ? 1 : 0); #elif ARCH_PORTDUINO - if (settingsMap[txen_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[txen_pin], txon ? 1 : 0); + if (portduino_config.lora_txen_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_txen_pin.pin, txon ? 1 : 0); } #endif #ifdef RF95_RXEN digitalWrite(RF95_RXEN, txon ? 0 : 1); #elif ARCH_PORTDUINO - if (settingsMap[rxen_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[rxen_pin], txon ? 0 : 1); + if (portduino_config.lora_rxen_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_rxen_pin.pin, txon ? 0 : 1); } #endif } @@ -164,13 +164,13 @@ bool RF95Interface::init() digitalWrite(RF95_RXEN, 1); #endif #if ARCH_PORTDUINO - if (settingsMap[txen_pin] != RADIOLIB_NC) { - pinMode(settingsMap[txen_pin], OUTPUT); - digitalWrite(settingsMap[txen_pin], 0); + if (portduino_config.lora_txen_pin.pin != RADIOLIB_NC) { + pinMode(portduino_config.lora_txen_pin.pin, OUTPUT); + digitalWrite(portduino_config.lora_txen_pin.pin, 0); } - if (settingsMap[rxen_pin] != RADIOLIB_NC) { - pinMode(settingsMap[rxen_pin], OUTPUT); - digitalWrite(settingsMap[rxen_pin], 0); + if (portduino_config.lora_rxen_pin.pin != RADIOLIB_NC) { + pinMode(portduino_config.lora_rxen_pin.pin, OUTPUT); + digitalWrite(portduino_config.lora_rxen_pin.pin, 0); } #endif setTransmitEnable(false); diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index 946b1982c..c18612101 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -417,7 +417,7 @@ void RadioLibInterface::handleReceiveInterrupt() int state = iface->readData((uint8_t *)&radioBuffer, length); #if ARCH_PORTDUINO - if (settingsMap[logoutputlevel] == level_trace) { + if (portduino_config.logoutputlevel == level_trace) { printBytes("Raw incoming packet: ", (uint8_t *)&radioBuffer, length); } #endif diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index c7e32c4a1..221e0275b 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -446,7 +446,7 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p) #if ENABLE_JSON_LOGGING LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str()); #elif ARCH_PORTDUINO - if (settingsStrings[traceFilename] != "" || settingsMap[logoutputlevel] == level_trace) { + if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) { LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str()); } #endif @@ -685,7 +685,7 @@ void Router::perhapsHandleReceived(meshtastic_MeshPacket *p) LOG_TRACE("%s", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str()); #elif ARCH_PORTDUINO // Even ignored packets get logged in the trace - if (settingsStrings[traceFilename] != "" || settingsMap[logoutputlevel] == level_trace) { + if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) { p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone LOG_TRACE("%s", MeshPacketSerializer::JsonSerializeEncrypted(p).c_str()); } diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index 729c1abc6..49dc562d4 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -12,7 +12,7 @@ // Particular boards might define a different max power based on what their hardware can do, default to max power output if not // specified (may be dangerous if using external PA and SX126x power config forgotten) #if ARCH_PORTDUINO -#define SX126X_MAX_POWER settingsMap[sx126x_max_power] +#define SX126X_MAX_POWER portduino_config.sx126x_max_power #endif #ifndef SX126X_MAX_POWER #define SX126X_MAX_POWER 22 @@ -53,10 +53,10 @@ template bool SX126xInterface::init() #endif #if ARCH_PORTDUINO - tcxoVoltage = (float)settingsMap[dio3_tcxo_voltage] / 1000; - if (settingsMap[sx126x_ant_sw_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[sx126x_ant_sw_pin], HIGH); - pinMode(settingsMap[sx126x_ant_sw_pin], OUTPUT); + tcxoVoltage = (float)portduino_config.dio3_tcxo_voltage / 1000; + if (portduino_config.lora_sx126x_ant_sw_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_sx126x_ant_sw_pin.pin, HIGH); + pinMode(portduino_config.lora_sx126x_ant_sw_pin.pin, OUTPUT); } #endif if (tcxoVoltage == 0.0) @@ -98,7 +98,7 @@ template bool SX126xInterface::init() bool dio2AsRfSwitch = true; #elif defined(ARCH_PORTDUINO) bool dio2AsRfSwitch = false; - if (settingsMap[dio2_as_rf_switch]) { + if (portduino_config.dio2_as_rf_switch) { dio2AsRfSwitch = true; } #else @@ -112,9 +112,9 @@ template bool SX126xInterface::init() // no effect #if ARCH_PORTDUINO if (res == RADIOLIB_ERR_NONE) { - LOG_DEBUG("Use MCU pin %i as RXEN and pin %i as TXEN to control RF switching", settingsMap[rxen_pin], - settingsMap[txen_pin]); - lora.setRfSwitchPins(settingsMap[rxen_pin], settingsMap[txen_pin]); + LOG_DEBUG("Use MCU pin %i as RXEN and pin %i as TXEN to control RF switching", portduino_config.lora_rxen_pin.pin, + portduino_config.lora_txen_pin.pin); + lora.setRfSwitchPins(portduino_config.lora_rxen_pin.pin, portduino_config.lora_txen_pin.pin); } #else #ifndef SX126X_RXEN diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp index 866426872..cbc98eeb1 100644 --- a/src/mesh/SX128xInterface.cpp +++ b/src/mesh/SX128xInterface.cpp @@ -11,7 +11,7 @@ // Particular boards might define a different max power based on what their hardware can do #if ARCH_PORTDUINO -#define SX128X_MAX_POWER settingsMap[sx128x_max_power] +#define SX128X_MAX_POWER portduino_config.sx128x_max_power #endif #ifndef SX128X_MAX_POWER #define SX128X_MAX_POWER 13 @@ -41,13 +41,13 @@ template bool SX128xInterface::init() #endif #if ARCH_PORTDUINO - if (settingsMap[rxen_pin] != RADIOLIB_NC) { - pinMode(settingsMap[rxen_pin], OUTPUT); - digitalWrite(settingsMap[rxen_pin], LOW); // Set low before becoming an output + if (portduino_config.lora_rxen_pin.pin != RADIOLIB_NC) { + pinMode(portduino_config.lora_rxen_pin.pin, OUTPUT); + digitalWrite(portduino_config.lora_rxen_pin.pin, LOW); // Set low before becoming an output } - if (settingsMap[txen_pin] != RADIOLIB_NC) { - pinMode(settingsMap[txen_pin], OUTPUT); - digitalWrite(settingsMap[txen_pin], LOW); // Set low before becoming an output + if (portduino_config.lora_txen_pin.pin != RADIOLIB_NC) { + pinMode(portduino_config.lora_txen_pin.pin, OUTPUT); + digitalWrite(portduino_config.lora_txen_pin.pin, LOW); // Set low before becoming an output } #else #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode @@ -93,8 +93,9 @@ template bool SX128xInterface::init() lora.setRfSwitchPins(SX128X_RXEN, SX128X_TXEN); } #elif ARCH_PORTDUINO - if (res == RADIOLIB_ERR_NONE && settingsMap[rxen_pin] != RADIOLIB_NC && settingsMap[txen_pin] != RADIOLIB_NC) { - lora.setRfSwitchPins(settingsMap[rxen_pin], settingsMap[txen_pin]); + if (res == RADIOLIB_ERR_NONE && portduino_config.lora_rxen_pin.pin != RADIOLIB_NC && + portduino_config.lora_txen_pin.pin != RADIOLIB_NC) { + lora.setRfSwitchPins(portduino_config.lora_rxen_pin.pin, portduino_config.lora_txen_pin.pin); } #endif @@ -174,11 +175,11 @@ template void SX128xInterface::setStandby() LOG_ERROR("SX128x standby %s%d", radioLibErr, err); assert(err == RADIOLIB_ERR_NONE); #if ARCH_PORTDUINO - if (settingsMap[rxen_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[rxen_pin], LOW); + if (portduino_config.lora_rxen_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_rxen_pin.pin, LOW); } - if (settingsMap[txen_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[txen_pin], LOW); + if (portduino_config.lora_txen_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_txen_pin.pin, LOW); } #else #if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn off RX and TX power @@ -210,11 +211,11 @@ template void SX128xInterface::addReceiveMetadata(meshtastic_Mes template void SX128xInterface::configHardwareForSend() { #if ARCH_PORTDUINO - if (settingsMap[txen_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[txen_pin], HIGH); + if (portduino_config.lora_txen_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_txen_pin.pin, HIGH); } - if (settingsMap[rxen_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[rxen_pin], LOW); + if (portduino_config.lora_rxen_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_rxen_pin.pin, LOW); } #else @@ -241,11 +242,11 @@ template void SX128xInterface::startReceive() setStandby(); #if ARCH_PORTDUINO - if (settingsMap[rxen_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[rxen_pin], HIGH); + if (portduino_config.lora_rxen_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_rxen_pin.pin, HIGH); } - if (settingsMap[txen_pin] != RADIOLIB_NC) { - digitalWrite(settingsMap[txen_pin], LOW); + if (portduino_config.lora_txen_pin.pin != RADIOLIB_NC) { + digitalWrite(portduino_config.lora_txen_pin.pin, LOW); } #else diff --git a/src/mesh/raspihttp/PiWebServer.cpp b/src/mesh/raspihttp/PiWebServer.cpp index 7d3542e83..3e9dbe8c2 100644 --- a/src/mesh/raspihttp/PiWebServer.cpp +++ b/src/mesh/raspihttp/PiWebServer.cpp @@ -65,8 +65,8 @@ mail: marchammermann@googlemail.com #define DEFAULT_REALM "default_realm" #define PREFIX "" -#define KEY_PATH settingsStrings[websslkeypath].c_str() -#define CERT_PATH settingsStrings[websslcertpath].c_str() +#define KEY_PATH portduino_config.webserver_ssl_key_path.c_str() +#define CERT_PATH portduino_config.webserver_ssl_cert_path.c_str() struct _file_config configWeb; @@ -458,8 +458,8 @@ PiWebServerThread::PiWebServerThread() } } - if (settingsMap[webserverport] != 0) { - webservport = settingsMap[webserverport]; + if (portduino_config.webserverport != 0) { + webservport = portduino_config.webserverport; LOG_INFO("Use webserver port from yaml config %i ", webservport); } else { LOG_INFO("Webserver port in yaml config set to 0, defaulting to port 9443"); @@ -490,7 +490,7 @@ PiWebServerThread::PiWebServerThread() u_map_put(&configWeb.mime_types, ".ico", "image/x-icon"); u_map_put(&configWeb.mime_types, ".svg", "image/svg+xml"); - webrootpath = settingsStrings[webserverrootpath]; + webrootpath = portduino_config.webserver_root_path; configWeb.files_path = (char *)webrootpath.c_str(); configWeb.url_prefix = ""; diff --git a/src/modules/Telemetry/HostMetrics.cpp b/src/modules/Telemetry/HostMetrics.cpp index 8f10b9228..dcde495a2 100644 --- a/src/modules/Telemetry/HostMetrics.cpp +++ b/src/modules/Telemetry/HostMetrics.cpp @@ -9,11 +9,11 @@ int32_t HostMetricsModule::runOnce() { #if ARCH_PORTDUINO - if (settingsMap[hostMetrics_interval] == 0) { + if (portduino_config.hostMetrics_interval == 0) { return disable(); } else { sendMetrics(); - return 60 * 1000 * settingsMap[hostMetrics_interval]; + return 60 * 1000 * portduino_config.hostMetrics_interval; } #else return disable(); @@ -110,8 +110,8 @@ meshtastic_Telemetry HostMetricsModule::getHostMetrics() proc_loadavg.close(); } } - if (settingsStrings[hostMetrics_user_command] != "") { - std::string userCommandResult = exec(settingsStrings[hostMetrics_user_command].c_str()); + if (portduino_config.hostMetrics_user_command != "") { + std::string userCommandResult = exec(portduino_config.hostMetrics_user_command.c_str()); if (userCommandResult.length() > 1) { strncpy(t.variant.host_metrics.user_string, userCommandResult.c_str(), sizeof(t.variant.host_metrics.user_string)); t.variant.host_metrics.user_string[sizeof(t.variant.host_metrics.user_string) - 1] = '\0'; @@ -135,7 +135,7 @@ bool HostMetricsModule::sendMetrics() p->to = NODENUM_BROADCAST; p->decoded.want_response = false; p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; - p->channel = settingsMap[hostMetrics_channel]; + p->channel = portduino_config.hostMetrics_channel; LOG_INFO("Send packet to mesh"); service->sendToMesh(p, RX_SRC_LOCAL, true); return true; diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index 929a45d09..b11d2547b 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -9,7 +9,6 @@ #include "api/ServerAPI.h" #include "linux/gpio/LinuxGPIOPin.h" #include "meshUtils.h" -#include "yaml-cpp/yaml.h" #include #include #include @@ -28,14 +27,13 @@ #include "platform/portduino/USBHal.h" -std::map settingsMap; -std::map settingsStrings; portduino_config_struct portduino_config; std::ofstream traceFile; Ch341Hal *ch341Hal = nullptr; char *configPath = nullptr; char *optionMac = nullptr; bool verboseEnabled = false; +bool yamlOnly = false; const char *argp_program_version = optstr(APP_VERSION); @@ -75,6 +73,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) case 'v': verboseEnabled = true; break; + case 'y': + yamlOnly = true; + break; case ARGP_KEY_ARG: return 0; default: @@ -90,6 +91,7 @@ void portduinoCustomInit() {"hwid", 'h', "HWID", 0, "The mac address to assign to this virtual machine"}, {"sim", 's', 0, 0, "Run in Simulated radio mode"}, {"verbose", 'v', 0, 0, "Set log level to full debug"}, + {"output-yaml", 'y', 0, 0, "Output config yaml and exit"}, {0}}; static void *childArguments; static char doc[] = "Meshtastic native build."; @@ -115,8 +117,8 @@ void getMacAddr(uint8_t *dmac) dmac[4] = hwId >> 8; dmac[5] = hwId & 0xff; } - } else if (settingsStrings[mac_address].length() > 11) { - MAC_from_string(settingsStrings[mac_address], dmac); + } else if (portduino_config.mac_address.length() > 11) { + MAC_from_string(portduino_config.mac_address, dmac); exit; } else { @@ -148,89 +150,46 @@ void getMacAddr(uint8_t *dmac) */ void portduinoSetup() { - printf("Set up Meshtastic on Portduino...\n"); int max_GPIO = 0; - const configNames GPIO_lines[] = {cs_pin, - irq_pin, - busy_pin, - reset_pin, - sx126x_ant_sw_pin, - txen_pin, - rxen_pin, - displayDC, - displayCS, - displayBacklight, - displayBacklightPWMChannel, - displayReset, - touchscreenCS, - touchscreenIRQ, - userButtonPin, - tbUpPin, - tbDownPin, - tbLeftPin, - tbRightPin, - tbPressPin}; - std::string gpioChipName = "gpiochip"; - settingsStrings[i2cdev] = ""; - settingsStrings[keyboardDevice] = ""; - settingsStrings[pointerDevice] = ""; - settingsStrings[webserverrootpath] = ""; - settingsStrings[spidev] = ""; - settingsStrings[displayspidev] = ""; - settingsMap[spiSpeed] = 2000000; - settingsMap[ascii_logs] = !isatty(1); - settingsMap[displayPanel] = no_screen; - settingsMap[touchscreenModule] = no_touchscreen; - settingsMap[tbUpPin] = RADIOLIB_NC; - settingsMap[tbDownPin] = RADIOLIB_NC; - settingsMap[tbLeftPin] = RADIOLIB_NC; - settingsMap[tbRightPin] = RADIOLIB_NC; - settingsMap[tbPressPin] = RADIOLIB_NC; - - YAML::Node yamlConfig; + portduino_config.displayPanel = no_screen; if (portduino_config.force_simradio == true) { - settingsMap[use_simradio] = true; + portduino_config.lora_module = use_simradio; } else if (configPath != nullptr) { if (loadConfig(configPath)) { - std::cout << "Using " << configPath << " as config file" << std::endl; + if (!yamlOnly) + std::cout << "Using " << configPath << " as config file" << std::endl; } else { std::cout << "Unable to use " << configPath << " as config file" << std::endl; exit(EXIT_FAILURE); } } else if (access("config.yaml", R_OK) == 0) { if (loadConfig("config.yaml")) { - std::cout << "Using local config.yaml as config file" << std::endl; + if (!yamlOnly) + std::cout << "Using local config.yaml as config file" << std::endl; } else { std::cout << "Unable to use local config.yaml as config file" << std::endl; exit(EXIT_FAILURE); } } else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0) { if (loadConfig("/etc/meshtasticd/config.yaml")) { - std::cout << "Using /etc/meshtasticd/config.yaml as config file" << std::endl; + if (!yamlOnly) + std::cout << "Using /etc/meshtasticd/config.yaml as config file" << std::endl; } else { std::cout << "Unable to use /etc/meshtasticd/config.yaml as config file" << std::endl; exit(EXIT_FAILURE); } } else { - std::cout << "No 'config.yaml' found..." << std::endl; - settingsMap[use_simradio] = true; + if (!yamlOnly) + std::cout << "No 'config.yaml' found..." << std::endl; + portduino_config.lora_module = use_simradio; } - if (settingsMap[use_simradio] == true) { - std::cout << "Running in simulated mode." << std::endl; - settingsMap[maxnodes] = 200; // Default to 200 nodes - settingsMap[logoutputlevel] = level_debug; // Default to debug - // Set the random seed equal to TCPPort to have a different seed per instance - randomSeed(TCPPort); - return; - } - - if (settingsStrings[config_directory] != "") { + if (portduino_config.config_directory != "") { std::string filetype = ".yaml"; for (const std::filesystem::directory_entry &entry : - std::filesystem::directory_iterator{settingsStrings[config_directory]}) { + std::filesystem::directory_iterator{portduino_config.config_directory}) { if (ends_with(entry.path().string(), ".yaml")) { std::cout << "Also using " << entry << " as additional config file" << std::endl; loadConfig(entry.path().c_str()); @@ -238,15 +197,28 @@ void portduinoSetup() } } + if (yamlOnly) { + std::cout << portduino_config.emit_yaml() << std::endl; + exit(EXIT_SUCCESS); + } + + if (portduino_config.lora_module == use_simradio) { + std::cout << "Running in simulated mode." << std::endl; + portduino_config.MaxNodes = 200; // Default to 200 nodes + // Set the random seed equal to TCPPort to have a different seed per instance + randomSeed(TCPPort); + return; + } + // If LoRa `Module: auto` (default in config.yaml), // attempt to auto config based on Product Strings - if (settingsMap[use_autoconf] == true) { + if (portduino_config.lora_module == use_autoconf) { char autoconf_product[96] = {0}; // Try CH341 try { std::cout << "autoconf: Looking for CH341 device..." << std::endl; - ch341Hal = - new Ch341Hal(0, settingsStrings[lora_usb_serial_num], settingsMap[lora_usb_vid], settingsMap[lora_usb_pid]); + ch341Hal = new Ch341Hal(0, portduino_config.lora_usb_serial_num, portduino_config.lora_usb_vid, + portduino_config.lora_usb_pid); ch341Hal->getProductString(autoconf_product, 95); delete ch341Hal; std::cout << "autoconf: Found CH341 device " << autoconf_product << std::endl; @@ -323,7 +295,7 @@ void portduinoSetup() if (mac_start != nullptr) { std::cout << "autoconf: Found mac data " << mac_start << std::endl; if (strlen(mac_start) == 12) - settingsStrings[mac_address] = std::string(mac_start); + portduino_config.mac_address = std::string(mac_start); } if (devID_start != nullptr) { std::cout << "autoconf: Found deviceid data " << devID_start << std::endl; @@ -354,7 +326,7 @@ void portduinoSetup() std::cerr << "autoconf: Unable to find config for " << autoconf_product << std::endl; exit(EXIT_FAILURE); } - if (loadConfig((settingsStrings[available_directory] + product_config).c_str())) { + if (loadConfig((portduino_config.available_directory + product_config).c_str())) { std::cout << "autoconf: Using " << product_config << " as config file for " << autoconf_product << std::endl; } else { std::cerr << "autoconf: Unable to use " << product_config << " as config file for " << autoconf_product @@ -363,15 +335,16 @@ void portduinoSetup() } } else { std::cerr << "autoconf: Could not locate any devices" << std::endl; + exit(EXIT_FAILURE); } } // if we're using a usermode driver, we need to initialize it here, to get a serial number back for mac address uint8_t dmac[6] = {0}; - if (settingsStrings[spidev] == "ch341") { + if (portduino_config.lora_spi_dev == "ch341") { try { - ch341Hal = - new Ch341Hal(0, settingsStrings[lora_usb_serial_num], settingsMap[lora_usb_vid], settingsMap[lora_usb_pid]); + ch341Hal = new Ch341Hal(0, portduino_config.lora_usb_serial_num, portduino_config.lora_usb_vid, + portduino_config.lora_usb_pid); } catch (std::exception &e) { std::cerr << e.what() << std::endl; std::cerr << "Could not initialize CH341 device!" << std::endl; @@ -383,7 +356,7 @@ void portduinoSetup() char product_string[96] = {0}; ch341Hal->getProductString(product_string, 95); std::cout << "CH341 Product " << product_string << std::endl; - if (strlen(serial) == 8 && settingsStrings[mac_address].length() < 12) { + if (strlen(serial) == 8 && portduino_config.mac_address.length() < 12) { uint8_t hash[32] = {0}; memcpy(hash, serial, 8); crypto->hash(hash, 8); @@ -395,7 +368,7 @@ void portduinoSetup() dmac[5] = hash[5]; char macBuf[13] = {0}; sprintf(macBuf, "%02X%02X%02X%02X%02X%02X", dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]); - settingsStrings[mac_address] = macBuf; + portduino_config.mac_address = macBuf; } } @@ -409,100 +382,38 @@ void portduinoSetup() // Rather important to set this, if not running simulated. randomSeed(time(NULL)); - std::string defaultGpioChipName = gpioChipName + std::to_string(settingsMap[default_gpiochip]); - - for (configNames i : GPIO_lines) { - if (settingsMap.count(i) && settingsMap[i] > max_GPIO) - max_GPIO = settingsMap[i]; + std::string defaultGpioChipName = gpioChipName + std::to_string(portduino_config.lora_default_gpiochip); + for (auto i : portduino_config.all_pins) { + if (i->enabled && i->pin > max_GPIO) + max_GPIO = i->pin; } gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need. // Need to bind all the configured GPIO pins so they're not simulated // TODO: If one of these fails, we should log and terminate - if (settingsMap.count(userButtonPin) > 0 && settingsMap[userButtonPin] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[userButtonPin], defaultGpioChipName, settingsMap[userButtonPin]) != ERRNO_OK) { - settingsMap[userButtonPin] = RADIOLIB_NC; - } - } - if (settingsMap.count(tbUpPin) > 0 && settingsMap[tbUpPin] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[tbUpPin], defaultGpioChipName, settingsMap[tbUpPin]) != ERRNO_OK) { - settingsMap[tbUpPin] = RADIOLIB_NC; - } - } - if (settingsMap.count(tbDownPin) > 0 && settingsMap[tbDownPin] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[tbDownPin], defaultGpioChipName, settingsMap[tbDownPin]) != ERRNO_OK) { - settingsMap[tbDownPin] = RADIOLIB_NC; - } - } - if (settingsMap.count(tbLeftPin) > 0 && settingsMap[tbLeftPin] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[tbLeftPin], defaultGpioChipName, settingsMap[tbLeftPin]) != ERRNO_OK) { - settingsMap[tbLeftPin] = RADIOLIB_NC; - } - } - if (settingsMap.count(tbRightPin) > 0 && settingsMap[tbRightPin] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[tbRightPin], defaultGpioChipName, settingsMap[tbRightPin]) != ERRNO_OK) { - settingsMap[tbRightPin] = RADIOLIB_NC; - } - } - if (settingsMap.count(tbPressPin) > 0 && settingsMap[tbPressPin] != RADIOLIB_NC) { - if (initGPIOPin(settingsMap[tbPressPin], defaultGpioChipName, settingsMap[tbPressPin]) != ERRNO_OK) { - settingsMap[tbPressPin] = RADIOLIB_NC; - } - } - if (settingsMap[displayPanel] != no_screen) { - if (settingsMap[displayCS] > 0) - initGPIOPin(settingsMap[displayCS], defaultGpioChipName, settingsMap[displayCS]); - if (settingsMap[displayDC] > 0) - initGPIOPin(settingsMap[displayDC], defaultGpioChipName, settingsMap[displayDC]); - if (settingsMap[displayBacklight] > 0) - initGPIOPin(settingsMap[displayBacklight], defaultGpioChipName, settingsMap[displayBacklight]); - if (settingsMap[displayReset] > 0) - initGPIOPin(settingsMap[displayReset], defaultGpioChipName, settingsMap[displayReset]); - } - if (settingsMap[touchscreenModule] != no_touchscreen) { - if (settingsMap[touchscreenCS] > 0) - initGPIOPin(settingsMap[touchscreenCS], defaultGpioChipName, settingsMap[touchscreenCS]); - if (settingsMap[touchscreenIRQ] > 0) - initGPIOPin(settingsMap[touchscreenIRQ], defaultGpioChipName, settingsMap[touchscreenIRQ]); + for (auto i : portduino_config.all_pins) { + if (i->enabled) + if (initGPIOPin(i->pin, gpioChipName + std::to_string(i->gpiochip), i->line) != ERRNO_OK) { + printf("Error setting pin number %d. It may not exist, or may already be in use.\n", i->line); + exit(EXIT_FAILURE); + } } // Only initialize the radio pins when dealing with real, kernel controlled SPI hardware - if (settingsStrings[spidev] != "" && settingsStrings[spidev] != "ch341") { - const struct { - configNames pin; - configNames gpiochip; - configNames line; - } pinMappings[] = {{cs_pin, cs_gpiochip, cs_line}, - {irq_pin, irq_gpiochip, irq_line}, - {busy_pin, busy_gpiochip, busy_line}, - {reset_pin, reset_gpiochip, reset_line}, - {rxen_pin, rxen_gpiochip, rxen_line}, - {txen_pin, txen_gpiochip, txen_line}, - {sx126x_ant_sw_pin, sx126x_ant_sw_gpiochip, sx126x_ant_sw_line}}; - for (auto &pinMap : pinMappings) { - auto setMapIter = settingsMap.find(pinMap.pin); - if (setMapIter != settingsMap.end() && setMapIter->second != RADIOLIB_NC) { - if (initGPIOPin(setMapIter->second, gpioChipName + std::to_string(settingsMap[pinMap.gpiochip]), - settingsMap[pinMap.line]) != ERRNO_OK) { - printf("Error setting pin number %d. It may not exist, or may already be in use.\n", - settingsMap[pinMap.line]); - exit(EXIT_FAILURE); - } - } - } - SPI.begin(settingsStrings[spidev].c_str()); + if (portduino_config.lora_spi_dev != "" && portduino_config.lora_spi_dev != "ch341") { + SPI.begin(portduino_config.lora_spi_dev.c_str()); } - if (settingsStrings[traceFilename] != "") { + if (portduino_config.traceFilename != "") { try { - traceFile.open(settingsStrings[traceFilename], std::ios::out | std::ios::app); + traceFile.open(portduino_config.traceFilename, std::ios::out | std::ios::app); } catch (std::ofstream::failure &e) { std::cout << "*** traceFile Exception " << e.what() << std::endl; exit(EXIT_FAILURE); } } - if (verboseEnabled && settingsMap[logoutputlevel] != level_trace) { - settingsMap[logoutputlevel] = level_debug; + if (verboseEnabled && portduino_config.logoutputlevel != level_trace) { + portduino_config.logoutputlevel = level_debug; } return; @@ -537,99 +448,78 @@ bool loadConfig(const char *configPath) yamlConfig = YAML::LoadFile(configPath); if (yamlConfig["Logging"]) { if (yamlConfig["Logging"]["LogLevel"].as("info") == "trace") { - settingsMap[logoutputlevel] = level_trace; + portduino_config.logoutputlevel = level_trace; } else if (yamlConfig["Logging"]["LogLevel"].as("info") == "debug") { - settingsMap[logoutputlevel] = level_debug; + portduino_config.logoutputlevel = level_debug; } else if (yamlConfig["Logging"]["LogLevel"].as("info") == "info") { - settingsMap[logoutputlevel] = level_info; + portduino_config.logoutputlevel = level_info; } else if (yamlConfig["Logging"]["LogLevel"].as("info") == "warn") { - settingsMap[logoutputlevel] = level_warn; + portduino_config.logoutputlevel = level_warn; } else if (yamlConfig["Logging"]["LogLevel"].as("info") == "error") { - settingsMap[logoutputlevel] = level_error; + portduino_config.logoutputlevel = level_error; } - settingsStrings[traceFilename] = yamlConfig["Logging"]["TraceFile"].as(""); + portduino_config.traceFilename = yamlConfig["Logging"]["TraceFile"].as(""); if (yamlConfig["Logging"]["AsciiLogs"]) { // Default is !isatty(1) but can be set explicitly in config.yaml - settingsMap[ascii_logs] = yamlConfig["Logging"]["AsciiLogs"].as(); + portduino_config.ascii_logs = yamlConfig["Logging"]["AsciiLogs"].as(); + portduino_config.ascii_logs_explicit = true; } } if (yamlConfig["Lora"]) { - const struct { - configNames cfgName; - std::string strName; - } loraModules[] = {{use_simradio, "sim"}, {use_autoconf, "auto"}, {use_rf95, "RF95"}, {use_sx1262, "sx1262"}, - {use_sx1268, "sx1268"}, {use_sx1280, "sx1280"}, {use_lr1110, "lr1110"}, {use_lr1120, "lr1120"}, - {use_lr1121, "lr1121"}, {use_llcc68, "LLCC68"}}; - for (auto &loraModule : loraModules) { - settingsMap[loraModule.cfgName] = false; - } + if (yamlConfig["Lora"]["Module"]) { - for (auto &loraModule : loraModules) { - if (yamlConfig["Lora"]["Module"].as("") == loraModule.strName) { - settingsMap[loraModule.cfgName] = true; + for (auto &loraModule : portduino_config.loraModules) { + if (yamlConfig["Lora"]["Module"].as("") == loraModule.second) { + portduino_config.lora_module = loraModule.first; break; } } } + if (yamlConfig["Lora"]["SX126X_MAX_POWER"]) + portduino_config.sx126x_max_power = yamlConfig["Lora"]["SX126X_MAX_POWER"].as(22); + if (yamlConfig["Lora"]["SX128X_MAX_POWER"]) + portduino_config.sx128x_max_power = yamlConfig["Lora"]["SX128X_MAX_POWER"].as(13); + if (yamlConfig["Lora"]["LR1110_MAX_POWER"]) + portduino_config.lr1110_max_power = yamlConfig["Lora"]["LR1110_MAX_POWER"].as(22); + if (yamlConfig["Lora"]["LR1120_MAX_POWER"]) + portduino_config.lr1120_max_power = yamlConfig["Lora"]["LR1120_MAX_POWER"].as(13); + if (yamlConfig["Lora"]["RF95_MAX_POWER"]) + portduino_config.rf95_max_power = yamlConfig["Lora"]["RF95_MAX_POWER"].as(20); - settingsMap[sx126x_max_power] = yamlConfig["Lora"]["SX126X_MAX_POWER"].as(22); - settingsMap[sx128x_max_power] = yamlConfig["Lora"]["SX128X_MAX_POWER"].as(13); - settingsMap[lr1110_max_power] = yamlConfig["Lora"]["LR1110_MAX_POWER"].as(22); - settingsMap[lr1120_max_power] = yamlConfig["Lora"]["LR1120_MAX_POWER"].as(13); - settingsMap[rf95_max_power] = yamlConfig["Lora"]["RF95_MAX_POWER"].as(20); + if (portduino_config.lora_module != use_autoconf && portduino_config.lora_module != use_simradio && + !portduino_config.force_simradio) { + portduino_config.dio2_as_rf_switch = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as(false); + portduino_config.dio3_tcxo_voltage = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as(0) * 1000; + if (portduino_config.dio3_tcxo_voltage == 0 && yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as(false)) { + portduino_config.dio3_tcxo_voltage = 1800; // default millivolts for "true" + } - settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as(false); - settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as(0) * 1000; - if (settingsMap[dio3_tcxo_voltage] == 0 && yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as(false)) { - settingsMap[dio3_tcxo_voltage] = 1800; // default millivolts for "true" - } - - // backwards API compatibility and to globally set gpiochip once - int defaultGpioChip = settingsMap[default_gpiochip] = yamlConfig["Lora"]["gpiochip"].as(0); - - const struct { - configNames pin; - configNames gpiochip; - configNames line; - std::string strName; - } pinMappings[] = { - {cs_pin, cs_gpiochip, cs_line, "CS"}, - {irq_pin, irq_gpiochip, irq_line, "IRQ"}, - {busy_pin, busy_gpiochip, busy_line, "Busy"}, - {reset_pin, reset_gpiochip, reset_line, "Reset"}, - {txen_pin, txen_gpiochip, txen_line, "TXen"}, - {rxen_pin, rxen_gpiochip, rxen_line, "RXen"}, - {sx126x_ant_sw_pin, sx126x_ant_sw_gpiochip, sx126x_ant_sw_line, "SX126X_ANT_SW"}, - }; - for (auto &pinMap : pinMappings) { - if (yamlConfig["Lora"][pinMap.strName].IsMap()) { - settingsMap[pinMap.pin] = yamlConfig["Lora"][pinMap.strName]["pin"].as(RADIOLIB_NC); - settingsMap[pinMap.line] = yamlConfig["Lora"][pinMap.strName]["line"].as(settingsMap[pinMap.pin]); - settingsMap[pinMap.gpiochip] = yamlConfig["Lora"][pinMap.strName]["gpiochip"].as(defaultGpioChip); - } else { // backwards API compatibility - settingsMap[pinMap.pin] = yamlConfig["Lora"][pinMap.strName].as(RADIOLIB_NC); - settingsMap[pinMap.line] = settingsMap[pinMap.pin]; - settingsMap[pinMap.gpiochip] = defaultGpioChip; + // backwards API compatibility and to globally set gpiochip once + portduino_config.lora_default_gpiochip = yamlConfig["Lora"]["gpiochip"].as(0); + for (auto this_pin : portduino_config.all_pins) { + if (this_pin->config_section == "Lora") { + readGPIOFromYaml(yamlConfig["Lora"][this_pin->config_name], *this_pin); + } } } - settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as(2000000); - settingsStrings[lora_usb_serial_num] = yamlConfig["Lora"]["USB_Serialnum"].as(""); - settingsMap[lora_usb_pid] = yamlConfig["Lora"]["USB_PID"].as(0x5512); - settingsMap[lora_usb_vid] = yamlConfig["Lora"]["USB_VID"].as(0x1A86); + portduino_config.spiSpeed = yamlConfig["Lora"]["spiSpeed"].as(2000000); + portduino_config.lora_usb_serial_num = yamlConfig["Lora"]["USB_Serialnum"].as(""); + portduino_config.lora_usb_pid = yamlConfig["Lora"]["USB_PID"].as(0x5512); + portduino_config.lora_usb_vid = yamlConfig["Lora"]["USB_VID"].as(0x1A86); - settingsStrings[spidev] = yamlConfig["Lora"]["spidev"].as("spidev0.0"); - if (settingsStrings[spidev] != "ch341") { - settingsStrings[spidev] = "/dev/" + settingsStrings[spidev]; - if (settingsStrings[spidev].length() == 14) { - int x = settingsStrings[spidev].at(11) - '0'; - int y = settingsStrings[spidev].at(13) - '0'; + portduino_config.lora_spi_dev = yamlConfig["Lora"]["spidev"].as("spidev0.0"); + if (portduino_config.lora_spi_dev != "ch341") { + portduino_config.lora_spi_dev = "/dev/" + portduino_config.lora_spi_dev; + if (portduino_config.lora_spi_dev.length() == 14) { + int x = portduino_config.lora_spi_dev.at(11) - '0'; + int y = portduino_config.lora_spi_dev.at(13) - '0'; // Pretty sure this is always true if (x >= 0 && x < 10 && y >= 0 && y < 10) { // I believe this bit of weirdness is specifically for the new GUI - settingsMap[spidev] = x + y << 4; - settingsMap[displayspidev] = settingsMap[spidev]; - settingsMap[touchscreenspidev] = settingsMap[spidev]; + portduino_config.lora_spi_dev_int = x + y << 4; + portduino_config.display_spi_dev_int = portduino_config.lora_spi_dev_int; + portduino_config.touchscreen_spi_dev_int = portduino_config.lora_spi_dev_int; } } } @@ -676,163 +566,152 @@ bool loadConfig(const char *configPath) } } } - if (yamlConfig["GPIO"]) { - settingsMap[userButtonPin] = yamlConfig["GPIO"]["User"].as(RADIOLIB_NC); - } + readGPIOFromYaml(yamlConfig["GPIO"]["User"], portduino_config.userButtonPin); if (yamlConfig["GPS"]) { std::string serialPath = yamlConfig["GPS"]["SerialPath"].as(""); if (serialPath != "") { Serial1.setPath(serialPath); - settingsMap[has_gps] = 1; + portduino_config.has_gps = 1; } } if (yamlConfig["I2C"]) { - settingsStrings[i2cdev] = yamlConfig["I2C"]["I2CDevice"].as(""); + portduino_config.i2cdev = yamlConfig["I2C"]["I2CDevice"].as(""); } if (yamlConfig["Display"]) { - if (yamlConfig["Display"]["Panel"].as("") == "ST7789") - settingsMap[displayPanel] = st7789; - else if (yamlConfig["Display"]["Panel"].as("") == "ST7735") - settingsMap[displayPanel] = st7735; - else if (yamlConfig["Display"]["Panel"].as("") == "ST7735S") - settingsMap[displayPanel] = st7735s; - else if (yamlConfig["Display"]["Panel"].as("") == "ST7796") - settingsMap[displayPanel] = st7796; - else if (yamlConfig["Display"]["Panel"].as("") == "ILI9341") - settingsMap[displayPanel] = ili9341; - else if (yamlConfig["Display"]["Panel"].as("") == "ILI9342") - settingsMap[displayPanel] = ili9342; - else if (yamlConfig["Display"]["Panel"].as("") == "ILI9486") - settingsMap[displayPanel] = ili9486; - else if (yamlConfig["Display"]["Panel"].as("") == "ILI9488") - settingsMap[displayPanel] = ili9488; - else if (yamlConfig["Display"]["Panel"].as("") == "HX8357D") - settingsMap[displayPanel] = hx8357d; - else if (yamlConfig["Display"]["Panel"].as("") == "X11") - settingsMap[displayPanel] = x11; - else if (yamlConfig["Display"]["Panel"].as("") == "FB") - settingsMap[displayPanel] = fb; - settingsMap[displayHeight] = yamlConfig["Display"]["Height"].as(0); - settingsMap[displayWidth] = yamlConfig["Display"]["Width"].as(0); - settingsMap[displayDC] = yamlConfig["Display"]["DC"].as(-1); - settingsMap[displayCS] = yamlConfig["Display"]["CS"].as(-1); - settingsMap[displayRGBOrder] = yamlConfig["Display"]["RGBOrder"].as(false); - settingsMap[displayBacklight] = yamlConfig["Display"]["Backlight"].as(-1); - settingsMap[displayBacklightInvert] = yamlConfig["Display"]["BacklightInvert"].as(false); - settingsMap[displayBacklightPWMChannel] = yamlConfig["Display"]["BacklightPWMChannel"].as(-1); - settingsMap[displayReset] = yamlConfig["Display"]["Reset"].as(-1); - settingsMap[displayOffsetX] = yamlConfig["Display"]["OffsetX"].as(0); - settingsMap[displayOffsetY] = yamlConfig["Display"]["OffsetY"].as(0); - settingsMap[displayRotate] = yamlConfig["Display"]["Rotate"].as(false); - settingsMap[displayOffsetRotate] = yamlConfig["Display"]["OffsetRotate"].as(1); - settingsMap[displayInvert] = yamlConfig["Display"]["Invert"].as(false); - settingsMap[displayBusFrequency] = yamlConfig["Display"]["BusFrequency"].as(40000000); + + for (auto &screen_name : portduino_config.screen_names) { + if (yamlConfig["Display"]["Panel"].as("") == screen_name.second) + portduino_config.displayPanel = screen_name.first; + } + portduino_config.displayHeight = yamlConfig["Display"]["Height"].as(0); + portduino_config.displayWidth = yamlConfig["Display"]["Width"].as(0); + + readGPIOFromYaml(yamlConfig["Display"]["DC"], portduino_config.displayDC, -1); + readGPIOFromYaml(yamlConfig["Display"]["CS"], portduino_config.displayCS, -1); + readGPIOFromYaml(yamlConfig["Display"]["Backlight"], portduino_config.displayBacklight, -1); + readGPIOFromYaml(yamlConfig["Display"]["BacklightPWMChannel"], portduino_config.displayBacklightPWMChannel, -1); + readGPIOFromYaml(yamlConfig["Display"]["Reset"], portduino_config.displayReset, -1); + + portduino_config.displayBacklightInvert = yamlConfig["Display"]["BacklightInvert"].as(false); + portduino_config.displayRGBOrder = yamlConfig["Display"]["RGBOrder"].as(false); + portduino_config.displayOffsetX = yamlConfig["Display"]["OffsetX"].as(0); + portduino_config.displayOffsetY = yamlConfig["Display"]["OffsetY"].as(0); + portduino_config.displayRotate = yamlConfig["Display"]["Rotate"].as(false); + portduino_config.displayOffsetRotate = yamlConfig["Display"]["OffsetRotate"].as(1); + portduino_config.displayInvert = yamlConfig["Display"]["Invert"].as(false); + portduino_config.displayBusFrequency = yamlConfig["Display"]["BusFrequency"].as(40000000); if (yamlConfig["Display"]["spidev"]) { - settingsStrings[displayspidev] = "/dev/" + yamlConfig["Display"]["spidev"].as("spidev0.1"); - if (settingsStrings[displayspidev].length() == 14) { - int x = settingsStrings[displayspidev].at(11) - '0'; - int y = settingsStrings[displayspidev].at(13) - '0'; + portduino_config.display_spi_dev = "/dev/" + yamlConfig["Display"]["spidev"].as("spidev0.1"); + if (portduino_config.display_spi_dev.length() == 14) { + int x = portduino_config.display_spi_dev.at(11) - '0'; + int y = portduino_config.display_spi_dev.at(13) - '0'; if (x >= 0 && x < 10 && y >= 0 && y < 10) { - settingsMap[displayspidev] = x + y << 4; - settingsMap[touchscreenspidev] = settingsMap[displayspidev]; + portduino_config.display_spi_dev_int = x + y << 4; + portduino_config.touchscreen_spi_dev_int = portduino_config.display_spi_dev_int; } } } } if (yamlConfig["Touchscreen"]) { if (yamlConfig["Touchscreen"]["Module"].as("") == "XPT2046") - settingsMap[touchscreenModule] = xpt2046; + portduino_config.touchscreenModule = xpt2046; else if (yamlConfig["Touchscreen"]["Module"].as("") == "STMPE610") - settingsMap[touchscreenModule] = stmpe610; + portduino_config.touchscreenModule = stmpe610; else if (yamlConfig["Touchscreen"]["Module"].as("") == "GT911") - settingsMap[touchscreenModule] = gt911; + portduino_config.touchscreenModule = gt911; else if (yamlConfig["Touchscreen"]["Module"].as("") == "FT5x06") - settingsMap[touchscreenModule] = ft5x06; - settingsMap[touchscreenCS] = yamlConfig["Touchscreen"]["CS"].as(-1); - settingsMap[touchscreenIRQ] = yamlConfig["Touchscreen"]["IRQ"].as(-1); - settingsMap[touchscreenBusFrequency] = yamlConfig["Touchscreen"]["BusFrequency"].as(1000000); - settingsMap[touchscreenRotate] = yamlConfig["Touchscreen"]["Rotate"].as(-1); - settingsMap[touchscreenI2CAddr] = yamlConfig["Touchscreen"]["I2CAddr"].as(-1); + portduino_config.touchscreenModule = ft5x06; + + readGPIOFromYaml(yamlConfig["Touchscreen"]["CS"], portduino_config.touchscreenCS, -1); + readGPIOFromYaml(yamlConfig["Touchscreen"]["IRQ"], portduino_config.touchscreenIRQ, -1); + + portduino_config.touchscreenBusFrequency = yamlConfig["Touchscreen"]["BusFrequency"].as(1000000); + portduino_config.touchscreenRotate = yamlConfig["Touchscreen"]["Rotate"].as(-1); + portduino_config.touchscreenI2CAddr = yamlConfig["Touchscreen"]["I2CAddr"].as(-1); if (yamlConfig["Touchscreen"]["spidev"]) { - settingsStrings[touchscreenspidev] = "/dev/" + yamlConfig["Touchscreen"]["spidev"].as(""); - if (settingsStrings[touchscreenspidev].length() == 14) { - int x = settingsStrings[touchscreenspidev].at(11) - '0'; - int y = settingsStrings[touchscreenspidev].at(13) - '0'; + portduino_config.touchscreen_spi_dev = "/dev/" + yamlConfig["Touchscreen"]["spidev"].as(""); + if (portduino_config.touchscreen_spi_dev.length() == 14) { + int x = portduino_config.touchscreen_spi_dev.at(11) - '0'; + int y = portduino_config.touchscreen_spi_dev.at(13) - '0'; if (x >= 0 && x < 10 && y >= 0 && y < 10) { - settingsMap[touchscreenspidev] = x + y << 4; + portduino_config.touchscreen_spi_dev_int = x + y << 4; } } } } if (yamlConfig["Input"]) { - settingsStrings[keyboardDevice] = (yamlConfig["Input"]["KeyboardDevice"]).as(""); - settingsStrings[pointerDevice] = (yamlConfig["Input"]["PointerDevice"]).as(""); - settingsMap[userButtonPin] = yamlConfig["Input"]["User"].as(RADIOLIB_NC); - settingsMap[tbUpPin] = yamlConfig["Input"]["TrackballUp"].as(RADIOLIB_NC); - settingsMap[tbDownPin] = yamlConfig["Input"]["TrackballDown"].as(RADIOLIB_NC); - settingsMap[tbLeftPin] = yamlConfig["Input"]["TrackballLeft"].as(RADIOLIB_NC); - settingsMap[tbRightPin] = yamlConfig["Input"]["TrackballRight"].as(RADIOLIB_NC); - settingsMap[tbPressPin] = yamlConfig["Input"]["TrackballPress"].as(RADIOLIB_NC); + portduino_config.keyboardDevice = (yamlConfig["Input"]["KeyboardDevice"]).as(""); + portduino_config.pointerDevice = (yamlConfig["Input"]["PointerDevice"]).as(""); + + readGPIOFromYaml(yamlConfig["Input"]["User"], portduino_config.userButtonPin); + readGPIOFromYaml(yamlConfig["Input"]["TrackballUp"], portduino_config.tbUpPin); + readGPIOFromYaml(yamlConfig["Input"]["TrackballDown"], portduino_config.tbDownPin); + readGPIOFromYaml(yamlConfig["Input"]["TrackballLeft"], portduino_config.tbLeftPin); + readGPIOFromYaml(yamlConfig["Input"]["TrackballRight"], portduino_config.tbRightPin); + readGPIOFromYaml(yamlConfig["Input"]["TrackballPress"], portduino_config.tbPressPin); + if (yamlConfig["Input"]["TrackballDirection"].as("RISING") == "RISING") { - settingsMap[tbDirection] = 4; + portduino_config.tbDirection = 4; } else if (yamlConfig["Input"]["TrackballDirection"].as("RISING") == "FALLING") { - settingsMap[tbDirection] = 3; + portduino_config.tbDirection = 3; } } if (yamlConfig["Webserver"]) { - settingsMap[webserverport] = (yamlConfig["Webserver"]["Port"]).as(-1); - settingsStrings[webserverrootpath] = + portduino_config.webserverport = (yamlConfig["Webserver"]["Port"]).as(-1); + portduino_config.webserver_root_path = (yamlConfig["Webserver"]["RootPath"]).as("/usr/share/meshtasticd/web"); - settingsStrings[websslkeypath] = + portduino_config.webserver_ssl_key_path = (yamlConfig["Webserver"]["SSLKey"]).as("/etc/meshtasticd/ssl/private_key.pem"); - settingsStrings[websslcertpath] = + portduino_config.webserver_ssl_cert_path = (yamlConfig["Webserver"]["SSLCert"]).as("/etc/meshtasticd/ssl/certificate.pem"); } if (yamlConfig["HostMetrics"]) { - settingsMap[hostMetrics_channel] = (yamlConfig["HostMetrics"]["Channel"]).as(0); - settingsMap[hostMetrics_interval] = (yamlConfig["HostMetrics"]["ReportInterval"]).as(0); - settingsStrings[hostMetrics_user_command] = (yamlConfig["HostMetrics"]["UserStringCommand"]).as(""); + portduino_config.hostMetrics_channel = (yamlConfig["HostMetrics"]["Channel"]).as(0); + portduino_config.hostMetrics_interval = (yamlConfig["HostMetrics"]["ReportInterval"]).as(0); + portduino_config.hostMetrics_user_command = (yamlConfig["HostMetrics"]["UserStringCommand"]).as(""); } if (yamlConfig["Config"]) { if (yamlConfig["Config"]["DisplayMode"]) { - settingsMap[has_configDisplayMode] = true; + portduino_config.has_configDisplayMode = true; if ((yamlConfig["Config"]["DisplayMode"]).as("") == "TWOCOLOR") { - settingsMap[configDisplayMode] = meshtastic_Config_DisplayConfig_DisplayMode_TWOCOLOR; + portduino_config.configDisplayMode = meshtastic_Config_DisplayConfig_DisplayMode_TWOCOLOR; } else if ((yamlConfig["Config"]["DisplayMode"]).as("") == "INVERTED") { - settingsMap[configDisplayMode] = meshtastic_Config_DisplayConfig_DisplayMode_INVERTED; + portduino_config.configDisplayMode = meshtastic_Config_DisplayConfig_DisplayMode_INVERTED; } else if ((yamlConfig["Config"]["DisplayMode"]).as("") == "COLOR") { - settingsMap[configDisplayMode] = meshtastic_Config_DisplayConfig_DisplayMode_COLOR; + portduino_config.configDisplayMode = meshtastic_Config_DisplayConfig_DisplayMode_COLOR; } else { - settingsMap[configDisplayMode] = meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT; + portduino_config.configDisplayMode = meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT; } } } if (yamlConfig["General"]) { - settingsMap[maxnodes] = (yamlConfig["General"]["MaxNodes"]).as(200); - settingsMap[maxtophone] = (yamlConfig["General"]["MaxMessageQueue"]).as(100); - settingsStrings[config_directory] = (yamlConfig["General"]["ConfigDirectory"]).as(""); - settingsStrings[available_directory] = + portduino_config.MaxNodes = (yamlConfig["General"]["MaxNodes"]).as(200); + portduino_config.maxtophone = (yamlConfig["General"]["MaxMessageQueue"]).as(100); + portduino_config.config_directory = (yamlConfig["General"]["ConfigDirectory"]).as(""); + portduino_config.available_directory = (yamlConfig["General"]["AvailableDirectory"]).as("/etc/meshtasticd/available.d/"); if ((yamlConfig["General"]["MACAddress"]).as("") != "" && (yamlConfig["General"]["MACAddressSource"]).as("") != "") { std::cout << "Cannot set both MACAddress and MACAddressSource!" << std::endl; exit(EXIT_FAILURE); } - settingsStrings[mac_address] = (yamlConfig["General"]["MACAddress"]).as(""); - if ((yamlConfig["General"]["MACAddressSource"]).as("") != "") { - std::ifstream infile("/sys/class/net/" + (yamlConfig["General"]["MACAddressSource"]).as("") + - "/address"); - std::getline(infile, settingsStrings[mac_address]); + portduino_config.mac_address = (yamlConfig["General"]["MACAddress"]).as(""); + if (portduino_config.mac_address != "") { + portduino_config.mac_address_explicit = true; + } else if ((yamlConfig["General"]["MACAddressSource"]).as("") != "") { + portduino_config.mac_address_source = (yamlConfig["General"]["MACAddressSource"]).as(""); + std::ifstream infile("/sys/class/net/" + portduino_config.mac_address_source + "/address"); + std::getline(infile, portduino_config.mac_address); } // https://stackoverflow.com/a/20326454 - settingsStrings[mac_address].erase( - std::remove(settingsStrings[mac_address].begin(), settingsStrings[mac_address].end(), ':'), - settingsStrings[mac_address].end()); + portduino_config.mac_address.erase( + std::remove(portduino_config.mac_address.begin(), portduino_config.mac_address.end(), ':'), + portduino_config.mac_address.end()); } } catch (YAML::Exception &e) { std::cout << "*** Exception " << e.what() << std::endl; @@ -851,12 +730,12 @@ bool MAC_from_string(std::string mac_str, uint8_t *dmac) { mac_str.erase(std::remove(mac_str.begin(), mac_str.end(), ':'), mac_str.end()); if (mac_str.length() == 12) { - dmac[0] = std::stoi(settingsStrings[mac_address].substr(0, 2), nullptr, 16); - dmac[1] = std::stoi(settingsStrings[mac_address].substr(2, 2), nullptr, 16); - dmac[2] = std::stoi(settingsStrings[mac_address].substr(4, 2), nullptr, 16); - dmac[3] = std::stoi(settingsStrings[mac_address].substr(6, 2), nullptr, 16); - dmac[4] = std::stoi(settingsStrings[mac_address].substr(8, 2), nullptr, 16); - dmac[5] = std::stoi(settingsStrings[mac_address].substr(10, 2), nullptr, 16); + dmac[0] = std::stoi(portduino_config.mac_address.substr(0, 2), nullptr, 16); + dmac[1] = std::stoi(portduino_config.mac_address.substr(2, 2), nullptr, 16); + dmac[2] = std::stoi(portduino_config.mac_address.substr(4, 2), nullptr, 16); + dmac[3] = std::stoi(portduino_config.mac_address.substr(6, 2), nullptr, 16); + dmac[4] = std::stoi(portduino_config.mac_address.substr(8, 2), nullptr, 16); + dmac[5] = std::stoi(portduino_config.mac_address.substr(10, 2), nullptr, 16); return true; } else { return false; @@ -875,4 +754,19 @@ std::string exec(const char *cmd) result += buffer.data(); } return result; +} + +void readGPIOFromYaml(YAML::Node sourceNode, pinMapping &destPin, int pinDefault) +{ + if (sourceNode.IsMap()) { + destPin.enabled = true; + destPin.pin = sourceNode["pin"].as(pinDefault); + destPin.line = sourceNode["line"].as(destPin.pin); + destPin.gpiochip = sourceNode["gpiochip"].as(portduino_config.lora_default_gpiochip); + } else if (sourceNode) { // backwards API compatibility + destPin.enabled = true; + destPin.pin = sourceNode.as(pinDefault); + destPin.line = destPin.pin; + destPin.gpiochip = portduino_config.lora_default_gpiochip; + } } \ No newline at end of file diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 8c36a1180..106900c48 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -6,6 +6,7 @@ #include "LR11x0Interface.h" #include "Module.h" #include "platform/portduino/USBHal.h" +#include "yaml-cpp/yaml.h" // Product strings for auto-configuration // {"PRODUCT_STRING", "CONFIG.YAML"} @@ -19,36 +20,10 @@ inline const std::unordered_map configProducts = { {"RAK6421-13300-S1", "lora-RAK6421-13300-slot1.yaml"}, {"RAK6421-13300-S2", "lora-RAK6421-13300-slot2.yaml"}}; -enum configNames { - default_gpiochip, - cs_pin, - cs_line, - cs_gpiochip, - irq_pin, - irq_line, - irq_gpiochip, - busy_pin, - busy_line, - busy_gpiochip, - reset_pin, - reset_line, - reset_gpiochip, - txen_pin, - txen_line, - txen_gpiochip, - rxen_pin, - rxen_line, - rxen_gpiochip, - sx126x_ant_sw_pin, - sx126x_ant_sw_line, - sx126x_ant_sw_gpiochip, - sx126x_max_power, - sx128x_max_power, - lr1110_max_power, - lr1120_max_power, - rf95_max_power, - dio2_as_rf_switch, - dio3_tcxo_voltage, +enum screen_modules { no_screen, x11, fb, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9486, ili9488, hx8357d }; +enum touchscreen_modules { no_touchscreen, xpt2046, stmpe610, gt911, ft5x06 }; +enum portduino_log_level { level_error, level_warn, level_info, level_debug, level_trace }; +enum lora_module_enum { use_simradio, use_autoconf, use_rf95, @@ -58,72 +33,18 @@ enum configNames { use_lr1110, use_lr1120, use_lr1121, - use_llcc68, - lora_usb_serial_num, - lora_usb_pid, - lora_usb_vid, - userButtonPin, - tbUpPin, - tbDownPin, - tbLeftPin, - tbRightPin, - tbPressPin, - tbDirection, - spidev, - spiSpeed, - i2cdev, - has_gps, - touchscreenModule, - touchscreenCS, - touchscreenIRQ, - touchscreenI2CAddr, - touchscreenBusFrequency, - touchscreenRotate, - touchscreenspidev, - displayspidev, - displayBusFrequency, - displayPanel, - displayWidth, - displayHeight, - displayCS, - displayDC, - displayRGBOrder, - displayBacklight, - displayBacklightPWMChannel, - displayBacklightInvert, - displayReset, - displayRotate, - displayOffsetRotate, - displayOffsetX, - displayOffsetY, - displayInvert, - keyboardDevice, - pointerDevice, - logoutputlevel, - traceFilename, - webserver, - webserverport, - webserverrootpath, - websslkeypath, - websslcertpath, - maxtophone, - maxnodes, - ascii_logs, - config_directory, - available_directory, - mac_address, - hostMetrics_interval, - hostMetrics_channel, - hostMetrics_user_command, - configDisplayMode, - has_configDisplayMode + use_llcc68 +}; + +struct pinMapping { + std::string config_section; + std::string config_name; + int pin = RADIOLIB_NC; + int gpiochip; + int line; + bool enabled = false; }; -enum { no_screen, x11, fb, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9486, ili9488, hx8357d }; -enum { no_touchscreen, xpt2046, stmpe610, gt911, ft5x06 }; -enum { level_error, level_warn, level_info, level_debug, level_trace }; -extern std::map settingsMap; -extern std::map settingsStrings; extern std::ofstream traceFile; extern Ch341Hal *ch341Hal; int initGPIOPin(int pinNum, std::string gpioChipname, int line); @@ -131,13 +52,422 @@ bool loadConfig(const char *configPath); static bool ends_with(std::string_view str, std::string_view suffix); void getMacAddr(uint8_t *dmac); bool MAC_from_string(std::string mac_str, uint8_t *dmac); +void readGPIOFromYaml(YAML::Node sourceNode, pinMapping &destPin, int pinDefault = RADIOLIB_NC); std::string exec(const char *cmd); extern struct portduino_config_struct { + // Lora + std::map loraModules = { + {use_simradio, "sim"}, {use_autoconf, "auto"}, {use_rf95, "RF95"}, {use_sx1262, "sx1262"}, {use_sx1268, "sx1268"}, + {use_sx1280, "sx1280"}, {use_lr1110, "lr1110"}, {use_lr1120, "lr1120"}, {use_lr1121, "lr1121"}, {use_llcc68, "LLCC68"}}; + + std::map screen_names = {{x11, "X11"}, {fb, "FB"}, {st7789, "ST7789"}, + {st7735, "ST7735"}, {st7735s, "ST7735S"}, {st7796, "ST7796"}, + {ili9341, "ILI9341"}, {ili9342, "ILI9342"}, {ili9486, "ILI9486"}, + {ili9488, "ILI9488"}, {hx8357d, "HX8357D"}}; + + lora_module_enum lora_module; bool has_rfswitch_table = false; uint32_t rfswitch_dio_pins[5] = {RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; Module::RfSwitchMode_t rfswitch_table[8]; bool force_simradio = false; bool has_device_id = false; uint8_t device_id[16] = {0}; + std::string lora_spi_dev = ""; + std::string lora_usb_serial_num = ""; + int lora_spi_dev_int = 0; + int lora_default_gpiochip = 0; + int sx126x_max_power = 22; + int sx128x_max_power = 13; + int lr1110_max_power = 22; + int lr1120_max_power = 13; + int rf95_max_power = 20; + bool dio2_as_rf_switch = false; + int dio3_tcxo_voltage = 0; + int lora_usb_pid = 0x5512; + int lora_usb_vid = 0x1A86; + int spiSpeed = 2000000; + pinMapping lora_cs_pin = {"Lora", "CS"}; + pinMapping lora_irq_pin = {"Lora", "IRQ"}; + pinMapping lora_busy_pin = {"Lora", "Busy"}; + pinMapping lora_reset_pin = {"Lora", "Reset"}; + pinMapping lora_txen_pin = {"Lora", "TXen"}; + pinMapping lora_rxen_pin = {"Lora", "RXen"}; + pinMapping lora_sx126x_ant_sw_pin = {"Lora", "SX126X_ANT_SW"}; + + // GPS + bool has_gps = false; + + // I2C + std::string i2cdev = ""; + + // Display + std::string display_spi_dev = ""; + int display_spi_dev_int = 0; + int displayBusFrequency = 40000000; + screen_modules displayPanel = no_screen; + int displayWidth = 0; + int displayHeight = 0; + bool displayRGBOrder = false; + bool displayBacklightInvert = false; + bool displayRotate = false; + int displayOffsetRotate = 1; + bool displayInvert = false; + int displayOffsetX = 0; + int displayOffsetY = 0; + pinMapping displayDC = {"Display", "DC"}; + pinMapping displayCS = {"Display", "CS"}; + pinMapping displayBacklight = {"Display", "Backlight"}; + pinMapping displayBacklightPWMChannel = {"Display", "BacklightPWMChannel"}; + pinMapping displayReset = {"Display", "Reset"}; + + // Touchscreen + std::string touchscreen_spi_dev = ""; + int touchscreen_spi_dev_int = 0; + touchscreen_modules touchscreenModule = no_touchscreen; + int touchscreenI2CAddr = -1; + int touchscreenBusFrequency = 1000000; + int touchscreenRotate = -1; + pinMapping touchscreenCS = {"Touchscreen", "CS"}; + pinMapping touchscreenIRQ = {"Touchscreen", "IRQ"}; + + // Input + std::string keyboardDevice = ""; + std::string pointerDevice = ""; + int tbDirection; + pinMapping userButtonPin = {"Input", "User"}; + pinMapping tbUpPin = {"Input", "TrackballUp"}; + pinMapping tbDownPin = {"Input", "TrackballDown"}; + pinMapping tbLeftPin = {"Input", "TrackballLwft"}; + pinMapping tbRightPin = {"Input", "TrackballRight"}; + pinMapping tbPressPin = {"Input", "TrackballPress"}; + + // Logging + portduino_log_level logoutputlevel = level_debug; + std::string traceFilename; + bool ascii_logs = !isatty(1); + bool ascii_logs_explicit = false; + + // Webserver + std::string webserver_root_path = ""; + std::string webserver_ssl_key_path = "/etc/meshtasticd/ssl/private_key.pem"; + std::string webserver_ssl_cert_path = "/etc/meshtasticd/ssl/certificate.pem"; + int webserverport = -1; + + // HostMetrics + std::string hostMetrics_user_command = ""; + int hostMetrics_interval = 0; + int hostMetrics_channel = 0; + + // config + int configDisplayMode = 0; + bool has_configDisplayMode = false; + + // General + std::string mac_address = ""; + bool mac_address_explicit = false; + std::string mac_address_source = ""; + std::string config_directory = ""; + std::string available_directory = "/etc/meshtasticd/available.d/"; + int maxtophone = 100; + int MaxNodes = 200; + + pinMapping *all_pins[20] = {&lora_cs_pin, + &lora_irq_pin, + &lora_busy_pin, + &lora_reset_pin, + &lora_txen_pin, + &lora_rxen_pin, + &lora_sx126x_ant_sw_pin, + &displayDC, + &displayCS, + &displayBacklight, + &displayBacklightPWMChannel, + &displayReset, + &touchscreenCS, + &touchscreenIRQ, + &userButtonPin, + &tbUpPin, + &tbDownPin, + &tbLeftPin, + &tbRightPin, + &tbPressPin}; + + std::string emit_yaml() + { + YAML::Emitter out; + out << YAML::BeginMap; + + // Lora + out << YAML::Key << "Lora" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "Module" << YAML::Value << loraModules[lora_module]; + + for (auto lora_pin : all_pins) { + if (lora_pin->config_section == "Lora" && lora_pin->enabled) { + out << YAML::Key << lora_pin->config_name << YAML::Value << YAML::BeginMap; + out << YAML::Key << "pin" << YAML::Value << lora_pin->pin; + out << YAML::Key << "line" << YAML::Value << lora_pin->line; + out << YAML::Key << "gpiochip" << YAML::Value << lora_pin->gpiochip; + out << YAML::EndMap; // User + } + } + + if (sx126x_max_power != 22) + out << YAML::Key << "SX126X_MAX_POWER" << YAML::Value << sx126x_max_power; + if (sx128x_max_power != 13) + out << YAML::Key << "SX128X_MAX_POWER" << YAML::Value << sx128x_max_power; + if (lr1110_max_power != 22) + out << YAML::Key << "LR1110_MAX_POWER" << YAML::Value << lr1110_max_power; + if (lr1120_max_power != 13) + out << YAML::Key << "LR1120_MAX_POWER" << YAML::Value << lr1120_max_power; + if (rf95_max_power != 20) + out << YAML::Key << "RF95_MAX_POWER" << YAML::Value << rf95_max_power; + out << YAML::Key << "DIO2_AS_RF_SWITCH" << YAML::Value << dio2_as_rf_switch; + if (dio3_tcxo_voltage != 0) + out << YAML::Key << "DIO3_TCXO_VOLTAGE" << YAML::Value << dio3_tcxo_voltage; + if (lora_usb_pid != 0x5512) + out << YAML::Key << "USB_PID" << YAML::Value << YAML::Hex << lora_usb_pid; + if (lora_usb_vid != 0x1A86) + out << YAML::Key << "USB_VID" << YAML::Value << YAML::Hex << lora_usb_vid; + if (lora_spi_dev != "") + out << YAML::Key << "spidev" << YAML::Value << lora_spi_dev; + if (lora_usb_serial_num != "") + out << YAML::Key << "USB_Serialnum" << YAML::Value << lora_usb_serial_num; + out << YAML::Key << "spiSpeed" << YAML::Value << spiSpeed; + if (rfswitch_dio_pins[0] != RADIOLIB_NC) { + out << YAML::Key << "rfswitch_table" << YAML::Value << YAML::BeginMap; + + out << YAML::Key << "pins"; + out << YAML::Value << YAML::Flow << YAML::BeginSeq; + + for (int i = 0; i < 5; i++) { + // set up the pin array first + if (rfswitch_dio_pins[i] == RADIOLIB_LR11X0_DIO5) + out << "DIO5"; + if (rfswitch_dio_pins[i] == RADIOLIB_LR11X0_DIO6) + out << "DIO6"; + if (rfswitch_dio_pins[i] == RADIOLIB_LR11X0_DIO7) + out << "DIO7"; + if (rfswitch_dio_pins[i] == RADIOLIB_LR11X0_DIO8) + out << "DIO8"; + if (rfswitch_dio_pins[i] == RADIOLIB_LR11X0_DIO10) + out << "DIO10"; + } + out << YAML::EndSeq; + + for (int i = 0; i < 7; i++) { + switch (i) { + case 0: + out << YAML::Key << "MODE_STBY"; + break; + case 1: + out << YAML::Key << "MODE_RX"; + break; + case 2: + out << YAML::Key << "MODE_TX"; + break; + case 3: + out << YAML::Key << "MODE_TX_HP"; + break; + case 4: + out << YAML::Key << "MODE_TX_HF"; + break; + case 5: + out << YAML::Key << "MODE_GNSS"; + break; + case 6: + out << YAML::Key << "MODE_WIFI"; + break; + } + + out << YAML::Value << YAML::Flow << YAML::BeginSeq; + for (int j = 0; j < 5; j++) { + if (rfswitch_table[i].values[j] == HIGH) { + out << "HIGH"; + } else { + out << "LOW"; + } + } + out << YAML::EndSeq; + } + out << YAML::EndMap; // rfswitch_table + } + out << YAML::EndMap; // Lora + + if (i2cdev != "") { + out << YAML::Key << "I2C" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "I2CDevice" << YAML::Value << i2cdev; + out << YAML::EndMap; // I2C + } + + // Display + if (displayPanel != no_screen) { + out << YAML::Key << "Display" << YAML::Value << YAML::BeginMap; + for (auto &screen_name : screen_names) { + if (displayPanel == screen_name.first) + out << YAML::Key << "Module" << YAML::Value << screen_name.second; + } + for (auto display_pin : all_pins) { + if (display_pin->config_section == "Display" && display_pin->enabled) { + out << YAML::Key << display_pin->config_name << YAML::Value << YAML::BeginMap; + out << YAML::Key << "pin" << YAML::Value << display_pin->pin; + out << YAML::Key << "line" << YAML::Value << display_pin->line; + out << YAML::Key << "gpiochip" << YAML::Value << display_pin->gpiochip; + out << YAML::EndMap; + } + } + out << YAML::Key << "spidev" << YAML::Value << display_spi_dev; + out << YAML::Key << "BusFrequency" << YAML::Value << displayBusFrequency; + if (displayWidth) + out << YAML::Key << "Width" << YAML::Value << displayWidth; + if (displayHeight) + out << YAML::Key << "Height" << YAML::Value << displayHeight; + if (displayRGBOrder) + out << YAML::Key << "RGBOrder" << YAML::Value << true; + if (displayBacklightInvert) + out << YAML::Key << "BacklightInvert" << YAML::Value << true; + if (displayRotate) + out << YAML::Key << "Rotate" << YAML::Value << true; + if (displayInvert) + out << YAML::Key << "Invert" << YAML::Value << true; + if (displayOffsetX) + out << YAML::Key << "OffsetX" << YAML::Value << displayOffsetX; + if (displayOffsetY) + out << YAML::Key << "OffsetY" << YAML::Value << displayOffsetY; + + out << YAML::Key << "OffsetRotate" << YAML::Value << displayOffsetRotate; + + out << YAML::EndMap; // Display + } + + // Touchscreen + if (touchscreen_spi_dev != "") { + out << YAML::Key << "Touchscreen" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "spidev" << YAML::Value << touchscreen_spi_dev; + out << YAML::Key << "BusFrequency" << YAML::Value << touchscreenBusFrequency; + switch (touchscreenModule) { + case xpt2046: + out << YAML::Key << "Module" << YAML::Value << "XPT2046"; + case stmpe610: + out << YAML::Key << "Module" << YAML::Value << "STMPE610"; + case gt911: + out << YAML::Key << "Module" << YAML::Value << "GT911"; + case ft5x06: + out << YAML::Key << "Module" << YAML::Value << "FT5x06"; + } + for (auto touchscreen_pin : all_pins) { + if (touchscreen_pin->config_section == "Touchscreen" && touchscreen_pin->enabled) { + out << YAML::Key << touchscreen_pin->config_name << YAML::Value << YAML::BeginMap; + out << YAML::Key << "pin" << YAML::Value << touchscreen_pin->pin; + out << YAML::Key << "line" << YAML::Value << touchscreen_pin->line; + out << YAML::Key << "gpiochip" << YAML::Value << touchscreen_pin->gpiochip; + out << YAML::EndMap; + } + } + if (touchscreenRotate != -1) + out << YAML::Key << "Rotate" << YAML::Value << touchscreenRotate; + if (touchscreenI2CAddr != -1) + out << YAML::Key << "I2CAddr" << YAML::Value << touchscreenI2CAddr; + out << YAML::EndMap; // Touchscreen + } + + // Input + out << YAML::Key << "Input" << YAML::Value << YAML::BeginMap; + if (keyboardDevice != "") + out << YAML::Key << "KeyboardDevice" << YAML::Value << keyboardDevice; + if (pointerDevice != "") + out << YAML::Key << "PointerDevice" << YAML::Value << pointerDevice; + + for (auto input_pin : all_pins) { + if (input_pin->config_section == "Input" && input_pin->enabled) { + out << YAML::Key << input_pin->config_name << YAML::Value << YAML::BeginMap; + out << YAML::Key << "pin" << YAML::Value << input_pin->pin; + out << YAML::Key << "line" << YAML::Value << input_pin->line; + out << YAML::Key << "gpiochip" << YAML::Value << input_pin->gpiochip; + out << YAML::EndMap; + } + } + if (tbDirection == 3) + out << YAML::Key << "TrackballDirection" << YAML::Value << "FALLING"; + + out << YAML::EndMap; // Input + + out << YAML::Key << "Logging" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "LogLevel" << YAML::Value; + switch (logoutputlevel) { + case level_error: + out << "error"; + break; + case level_warn: + out << "warn"; + break; + case level_info: + out << "info"; + break; + case level_debug: + out << "debug"; + break; + case level_trace: + out << "trace"; + break; + } + if (traceFilename != "") + out << YAML::Key << "TraceFile" << YAML::Value << traceFilename; + if (ascii_logs_explicit) { + out << YAML::Key << "AsciiLogs" << YAML::Value << ascii_logs; + } + out << YAML::EndMap; // Logging + + // Webserver + if (webserver_root_path != "") { + out << YAML::Key << "Webserver" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "RootPath" << YAML::Value << webserver_root_path; + out << YAML::Key << "SSLKey" << YAML::Value << webserver_ssl_key_path; + out << YAML::Key << "SSLCert" << YAML::Value << webserver_ssl_cert_path; + out << YAML::Key << "Port" << YAML::Value << webserverport; + out << YAML::EndMap; // Webserver + } + + // HostMetrics + if (hostMetrics_user_command != "") { + out << YAML::Key << "HostMetrics" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "UserStringCommand" << YAML::Value << hostMetrics_user_command; + out << YAML::Key << "ReportInterval" << YAML::Value << hostMetrics_interval; + out << YAML::Key << "Channel" << YAML::Value << hostMetrics_channel; + + out << YAML::EndMap; // HostMetrics + } + + // config + if (has_configDisplayMode) { + out << YAML::Key << "Config" << YAML::Value << YAML::BeginMap; + switch (configDisplayMode) { + case meshtastic_Config_DisplayConfig_DisplayMode_TWOCOLOR: + out << YAML::Key << "DisplayMode" << YAML::Value << "TWOCOLOR"; + case meshtastic_Config_DisplayConfig_DisplayMode_INVERTED: + out << YAML::Key << "DisplayMode" << YAML::Value << "INVERTED"; + case meshtastic_Config_DisplayConfig_DisplayMode_COLOR: + out << YAML::Key << "DisplayMode" << YAML::Value << "COLOR"; + case meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT: + out << YAML::Key << "DisplayMode" << YAML::Value << "DEFAULT"; + } + + out << YAML::EndMap; // Config + } + + // General + out << YAML::Key << "General" << YAML::Value << YAML::BeginMap; + if (config_directory != "") + out << YAML::Key << "ConfigDirectory" << YAML::Value << config_directory; + if (mac_address_explicit) + out << YAML::Key << "MACAddress" << YAML::Value << mac_address; + if (mac_address_source != "") + out << YAML::Key << "MACAddressSource" << YAML::Value << mac_address_source; + if (available_directory != "") + out << YAML::Key << "AvailableDirectory" << YAML::Value << available_directory; + out << YAML::Key << "MaxMessageQueue" << YAML::Value << maxtophone; + out << YAML::Key << "MaxNodes" << YAML::Value << MaxNodes; + out << YAML::EndMap; // General + return out.c_str(); + } } portduino_config; \ No newline at end of file diff --git a/src/platform/portduino/architecture.h b/src/platform/portduino/architecture.h index 07d0aeee0..e10519d21 100644 --- a/src/platform/portduino/architecture.h +++ b/src/platform/portduino/architecture.h @@ -28,9 +28,9 @@ #endif #ifndef HAS_TRACKBALL #define HAS_TRACKBALL 1 -#define TB_DOWN (uint8_t) settingsMap[tbDownPin] -#define TB_UP (uint8_t) settingsMap[tbUpPin] -#define TB_LEFT (uint8_t) settingsMap[tbLeftPin] -#define TB_RIGHT (uint8_t) settingsMap[tbRightPin] -#define TB_PRESS (uint8_t) settingsMap[tbPressPin] +#define TB_DOWN (uint8_t) portduino_config.tbDownPin.pin +#define TB_UP (uint8_t) portduino_config.tbUpPin.pin +#define TB_LEFT (uint8_t) portduino_config.tbLeftPin.pin +#define TB_RIGHT (uint8_t) portduino_config.tbRightPin.pin +#define TB_PRESS (uint8_t) portduino_config.tbPressPin.pin #endif \ No newline at end of file diff --git a/variants/native/portduino-buildroot/variant.h b/variants/native/portduino-buildroot/variant.h index b7b39d6e8..a453c3b71 100644 --- a/variants/native/portduino-buildroot/variant.h +++ b/variants/native/portduino-buildroot/variant.h @@ -1,5 +1,5 @@ #define HAS_SCREEN 1 #define CANNED_MESSAGE_MODULE_ENABLE 1 #define HAS_GPS 1 -#define MAX_RX_TOPHONE settingsMap[maxtophone] -#define MAX_NUM_NODES settingsMap[maxnodes] \ No newline at end of file +#define MAX_RX_TOPHONE portduino_config.maxtophone +#define MAX_NUM_NODES portduino_config.MaxNodes \ No newline at end of file diff --git a/variants/native/portduino/variant.h b/variants/native/portduino/variant.h index a7ca865be..af05fcf8d 100644 --- a/variants/native/portduino/variant.h +++ b/variants/native/portduino/variant.h @@ -3,8 +3,8 @@ #endif #define CANNED_MESSAGE_MODULE_ENABLE 1 #define HAS_GPS 1 -#define MAX_RX_TOPHONE settingsMap[maxtophone] -#define MAX_NUM_NODES settingsMap[maxnodes] +#define MAX_RX_TOPHONE portduino_config.maxtophone +#define MAX_NUM_NODES portduino_config.MaxNodes // RAK12002 RTC Module -#define RV3028_RTC (uint8_t)0b1010010 \ No newline at end of file +#define RV3028_RTC (uint8_t)0b1010010