diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index dc065d041..2ddebdf1d 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -8,15 +8,15 @@ plugins: uri: https://github.com/trunk-io/plugins lint: enabled: - - checkov@3.2.446 - - renovate@41.10.0 - - prettier@3.6.1 + - checkov@3.2.447 + - renovate@41.17.2 + - prettier@3.6.2 - trufflehog@3.89.2 - yamllint@1.37.1 - bandit@1.8.5 - - trivy@0.63.0 + - trivy@0.64.0 - taplo@0.9.3 - - ruff@0.12.0 + - ruff@0.12.1 - isort@6.0.1 - markdownlint@0.45.0 - oxipng@9.1.5 diff --git a/arch/stm32/stm32.ini b/arch/stm32/stm32.ini index e7a340f92..1a0890b8a 100644 --- a/arch/stm32/stm32.ini +++ b/arch/stm32/stm32.ini @@ -16,14 +16,17 @@ build_flags = ${arduino_base.build_flags} -flto -Isrc/platform/stm32wl -g - -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR - -DMESHTASTIC_EXCLUDE_INPUTBROKER - -DMESHTASTIC_EXCLUDE_I2C - -DMESHTASTIC_EXCLUDE_POWERMON - -DMESHTASTIC_EXCLUDE_SCREEN - -DMESHTASTIC_EXCLUDE_MQTT - -DMESHTASTIC_EXCLUDE_BLUETOOTH - -DMESHTASTIC_EXCLUDE_GPS + -DMESHTASTIC_EXCLUDE_AUDIO=1 + -DMESHTASTIC_EXCLUDE_ATAK=1 ; ATAK is quite big, disable it for big flash savings. + -DMESHTASTIC_EXCLUDE_INPUTBROKER=1 + -DMESHTASTIC_EXCLUDE_POWERMON=1 + -DMESHTASTIC_EXCLUDE_SCREEN=1 + -DMESHTASTIC_EXCLUDE_MQTT=1 + -DMESHTASTIC_EXCLUDE_BLUETOOTH=1 + -DMESHTASTIC_EXCLUDE_GPS=1 + -DMESHTASTIC_EXCLUDE_WIFI=1 + -DMESHTASTIC_EXCLUDE_TZ=1 ; Exclude TZ to save some flash space. + -DPIO_FRAMEWORK_ARDUINO_NANOLIB_FLOAT_PRINTF ; This is REQUIRED for at least traceroute debug prints - without it the length ends up uninitialized. ;-DDEBUG_MUTE -fmerge-all-constants -ffunction-sections @@ -39,9 +42,9 @@ debug_tool = stlink lib_deps = ${env.lib_deps} ${radiolib_base.lib_deps} + # renovate: datasource=git-refs depName=caveman99-stm32-Crypto packageName=https://github.com/caveman99/Crypto gitBranch=main https://github.com/caveman99/Crypto/archive/eae9c768054118a9399690f8af202853d1ae8516.zip lib_ignore = mathertel/OneButton@2.6.1 - Wire diff --git a/boards/wiscore_rak3312.json b/boards/wiscore_rak3312.json new file mode 100644 index 000000000..192e1c03c --- /dev/null +++ b/boards/wiscore_rak3312.json @@ -0,0 +1,41 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld", + "memory_type": "qio_opi", + "partitions": "default_16MB.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DRAK3312", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "hwids": [["0x303A", "0x1001"]], + "mcu": "esp32s3", + "variant": "rak3312" + }, + "connectivity": ["wifi", "bluetooth"], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": ["arduino", "espidf"], + "name": "WisCore RAK3312 Board", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://www.rakwireless.com/en-us", + "vendor": "rakwireless" +} diff --git a/protobufs b/protobufs index 86c738e80..5ef7aec95 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 86c738e8061ec09625ee52bc61ba862414384ce6 +Subproject commit 5ef7aec9597c6f841152e63b84d9dd7608cdef81 diff --git a/src/Power.cpp b/src/Power.cpp index fb5db416e..9c67977bd 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -103,7 +103,7 @@ NullSensor ina3221Sensor; #endif -#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_STM32WL) +#if !MESHTASTIC_EXCLUDE_I2C #include "modules/Telemetry/Sensor/MAX17048Sensor.h" #include extern std::pair nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1]; @@ -278,7 +278,7 @@ class AnalogBatteryLevel : public HasBatteryLevel } #endif -#if HAS_TELEMETRY && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR +#if HAS_TELEMETRY && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR if (hasINA()) { return getINAVoltage(); } @@ -456,8 +456,7 @@ class AnalogBatteryLevel : public HasBatteryLevel #ifdef EXT_CHRG_DETECT return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value; #else -#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL) && \ - !defined(DISABLE_INA_CHARGING_DETECTION) +#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(DISABLE_INA_CHARGING_DETECTION) if (hasINA()) { // get current flow from INA sensor - negative value means power flowing into the battery // default assuming BATTERY+ <--> INA_VIN+ <--> SHUNT RESISTOR <--> INA_VIN- <--> LOAD @@ -503,7 +502,7 @@ class AnalogBatteryLevel : public HasBatteryLevel } #endif -#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL) +#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR uint16_t getINAVoltage() { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) { @@ -1161,7 +1160,7 @@ bool Power::axpChipInit() #endif } -#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) +#if !MESHTASTIC_EXCLUDE_I2C && __has_include() /** * Wrapper class for an I2C MAX17048 Lipo battery sensor. diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index af964eab5..219a593e0 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -244,11 +244,15 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t) */ int32_t getTZOffset() { +#if MESHTASTIC_EXCLUDE_TZ + return 0; +#else time_t now = getTime(false); struct tm *gmt; gmt = gmtime(&now); gmt->tm_isdst = -1; return (int32_t)difftime(now, mktime(gmt)); +#endif } /** diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index 1c327117e..9736cf9d1 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -327,7 +327,11 @@ void menuHandler::positionBaseMenu() } screen->showOverlayBanner("Position Action", 30000, optionsArrayPtr, options, [](int selected) -> void { if (selected == 1) { +#if MESHTASTIC_EXCLUDE_GPS + menuQueue = menu_none; +#else menuQueue = gps_toggle_menu; +#endif } else if (selected == 2) { menuQueue = compass_point_north_menu; } else if (selected == 3) { @@ -390,6 +394,7 @@ void menuHandler::compassNorthMenu() }); } +#if !MESHTASTIC_EXCLUDE_GPS void menuHandler::GPSToggleMenu() { static const char *optionsArray[] = {"Back", "Enabled", "Disabled"}; @@ -412,6 +417,7 @@ void menuHandler::GPSToggleMenu() }, config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED ? 1 : 2); // set inital selection } +#endif void menuHandler::BuzzerModeMenu() { @@ -461,9 +467,11 @@ void menuHandler::handleMenuSwitch() case position_base_menu: positionBaseMenu(); break; +#if !MESHTASTIC_EXCLUDE_GPS case gps_toggle_menu: GPSToggleMenu(); break; +#endif case compass_point_north_menu: compassNorthMenu(); break; diff --git a/src/graphics/draw/MenuHandler.h b/src/graphics/draw/MenuHandler.h index a5bea5176..5a5ee8bf6 100644 --- a/src/graphics/draw/MenuHandler.h +++ b/src/graphics/draw/MenuHandler.h @@ -13,7 +13,9 @@ class menuHandler clock_face_picker, clock_menu, position_base_menu, +#if !MESHTASTIC_EXCLUDE_GPS gps_toggle_menu, +#endif compass_point_north_menu, reset_node_db_menu }; diff --git a/src/graphics/draw/UIRenderer.cpp b/src/graphics/draw/UIRenderer.cpp index 1738a8246..9c3a9eabb 100644 --- a/src/graphics/draw/UIRenderer.cpp +++ b/src/graphics/draw/UIRenderer.cpp @@ -44,22 +44,20 @@ std::string sanitizeString(const std::string &input) return output; } -#if !MESHTASTIC_EXCLUDE_GPS - // External variables extern graphics::Screen *screen; namespace graphics { +NodeNum UIRenderer::currentFavoriteNodeNum = 0; +#if !MESHTASTIC_EXCLUDE_GPS // GeoCoord object for coordinate conversions extern GeoCoord geoCoord; // Threshold values for the GPS lock accuracy bar display extern uint32_t dopThresholds[5]; -NodeNum UIRenderer::currentFavoriteNodeNum = 0; - // Draw GPS status summary void UIRenderer::drawGps(OLEDDisplay *display, int16_t x, int16_t y, const meshtastic::GPSStatus *gps) { @@ -188,6 +186,7 @@ void UIRenderer::drawGpsCoordinates(OLEDDisplay *display, int16_t x, int16_t y, } } } +#endif // !MESHTASTIC_EXCLUDE_GPS // Draw nodes status void UIRenderer::drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const meshtastic::NodeStatus *nodeStatus, int node_offset, @@ -1242,5 +1241,4 @@ std::string UIRenderer::drawTimeDelta(uint32_t days, uint32_t hours, uint32_t mi } // namespace graphics -#endif // !MESHTASTIC_EXCLUDE_GPS #endif // HAS_SCREEN \ No newline at end of file diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h index f42b9dc2c..c84ee09e0 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h +++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h @@ -33,6 +33,7 @@ enum MenuAction { LAYOUT, TOGGLE_BATTERY_ICON, TOGGLE_NOTIFICATIONS, + TOGGLE_INVERT_COLOR, TOGGLE_12H_CLOCK, }; diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp index 69965972f..27d1825d5 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp +++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp @@ -205,6 +205,15 @@ void InkHUD::MenuApplet::execute(MenuItem item) settings->optionalFeatures.notifications = !settings->optionalFeatures.notifications; break; + case TOGGLE_INVERT_COLOR: + if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) + config.display.displaymode = meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT; + else + config.display.displaymode = meshtastic_Config_DisplayConfig_DisplayMode_INVERTED; + + nodeDB->saveToDisk(SEGMENT_CONFIG); + break; + case SET_RECENTS: // Set value of settings.recentlyActiveSeconds // Uses menu cursor to read RECENTS_OPTIONS_MINUTES array (defined at top of this file) @@ -316,6 +325,10 @@ void InkHUD::MenuApplet::showPage(MenuPage page) &settings->optionalFeatures.notifications)); items.push_back(MenuItem("Battery Icon", MenuAction::TOGGLE_BATTERY_ICON, MenuPage::OPTIONS, &settings->optionalFeatures.batteryIcon)); + + invertedColors = (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED); + items.push_back(MenuItem("Invert Color", MenuAction::TOGGLE_INVERT_COLOR, MenuPage::OPTIONS, &invertedColors)); + items.push_back( MenuItem("12-Hour Clock", MenuAction::TOGGLE_12H_CLOCK, MenuPage::OPTIONS, &config.display.use_12h_clock)); items.push_back(MenuItem("Exit", MenuPage::EXIT)); diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.h b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.h index 4c974672a..8f9280e6f 100644 --- a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.h +++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.h @@ -91,6 +91,8 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread } cm; Applet *borrowedTileOwner = nullptr; // Which applet we have temporarily replaced while displaying menu + + bool invertedColors = false; // Helper to display current state of config.display.displaymode in InkHUD options }; } // namespace NicheGraphics::InkHUD diff --git a/src/graphics/niche/InkHUD/Renderer.cpp b/src/graphics/niche/InkHUD/Renderer.cpp index c058c4126..072e9dbd6 100644 --- a/src/graphics/niche/InkHUD/Renderer.cpp +++ b/src/graphics/niche/InkHUD/Renderer.cpp @@ -224,6 +224,13 @@ void InkHUD::Renderer::render(bool async) renderPlaceholders(); renderSystemApplets(); + // Invert Buffer if set by user + if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { + for (size_t i = 0; i < imageBufferWidth * imageBufferHeight; ++i) { + imageBuffer[i] = ~imageBuffer[i]; + } + } + // Tell display to begin process of drawing new image LOG_INFO("Updating display"); driver->update(imageBuffer, updateType); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index bd4911a9b..79047cbd8 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -771,7 +771,7 @@ void NodeDB::installDefaultModuleConfig() moduleConfig.external_notification.alert_message_buzzer = true; moduleConfig.external_notification.nag_timeout = 60; #endif -#if defined(RAK4630) || defined(RAK11310) +#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) // Default to RAK led pin 2 (blue) moduleConfig.external_notification.enabled = true; moduleConfig.external_notification.output = PIN_LED2; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 91a4d0632..4db05b4d4 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -12,6 +12,12 @@ #include #include +// Calculate 2^n without calling pow() +uint32_t pow_of_2(uint32_t n) +{ + return 1 << n; +} + #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, wide_lora) \ { \ meshtastic_Config_LoRaConfig_RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, \ @@ -246,7 +252,7 @@ uint32_t RadioInterface::getRetransmissionMsec(const meshtastic_MeshPacket *p) float channelUtil = airTime->channelUtilizationPercent(); uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax); // Assuming we pick max. of CWsize and there will be a client with SNR at half the range - return 2 * packetAirtime + (pow(2, CWsize) + 2 * CWmax + pow(2, int((CWmax + CWmin) / 2))) * slotTimeMsec + + return 2 * packetAirtime + (pow_of_2(CWsize) + 2 * CWmax + pow_of_2(int((CWmax + CWmin) / 2))) * slotTimeMsec + PROCESSING_TIME_MSEC; } @@ -259,7 +265,7 @@ uint32_t RadioInterface::getTxDelayMsec() float channelUtil = airTime->channelUtilizationPercent(); uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax); // LOG_DEBUG("Current channel utilization is %f so setting CWsize to %d", channelUtil, CWsize); - return random(0, pow(2, CWsize)) * slotTimeMsec; + return random(0, pow_of_2(CWsize)) * slotTimeMsec; } /** The CW size to use when calculating SNR_based delays */ @@ -279,7 +285,7 @@ uint32_t RadioInterface::getTxDelayMsecWeightedWorst(float snr) { uint8_t CWsize = getCWsize(snr); // offset the maximum delay for routers: (2 * CWmax * slotTimeMsec) - return (2 * CWmax * slotTimeMsec) + pow(2, CWsize) * slotTimeMsec; + return (2 * CWmax * slotTimeMsec) + pow_of_2(CWsize) * slotTimeMsec; } /** The delay to use when we want to flood a message */ @@ -296,7 +302,7 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr) LOG_DEBUG("rx_snr found in packet. Router: setting tx delay:%d", delay); } else { // offset the maximum delay for routers: (2 * CWmax * slotTimeMsec) - delay = (2 * CWmax * slotTimeMsec) + random(0, pow(2, CWsize)) * slotTimeMsec; + delay = (2 * CWmax * slotTimeMsec) + random(0, pow_of_2(CWsize)) * slotTimeMsec; LOG_DEBUG("rx_snr found in packet. Setting tx delay:%d", delay); } @@ -596,7 +602,7 @@ void RadioInterface::applyModemConfig() uint32_t RadioInterface::computeSlotTimeMsec() { float sumPropagationTurnaroundMACTime = 0.2 + 0.4 + 7; // in milliseconds - float symbolTime = pow(2, sf) / bw; // in milliseconds + float symbolTime = pow_of_2(sf) / bw; // in milliseconds if (myRegion->wideLora) { // CAD duration derived from AN1200.22 of SX1280 diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index 90b0d9d10..072a99a24 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -281,6 +281,12 @@ typedef struct _meshtastic_AirQualityMetrics { /* CO2 concentration in ppm */ bool has_co2; uint32_t co2; + /* CO2 sensor temperature in degC */ + bool has_co2_temperature; + float co2_temperature; + /* CO2 sensor relative humidity in % */ + bool has_co2_humidity; + float co2_humidity; } meshtastic_AirQualityMetrics; /* Local device mesh statistics */ @@ -409,7 +415,7 @@ extern "C" { #define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} +#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_HealthMetrics_init_default {false, 0, false, 0, false, 0} #define meshtastic_HostMetrics_init_default {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""} @@ -418,7 +424,7 @@ extern "C" { #define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} -#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} +#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0} #define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_HealthMetrics_init_zero {false, 0, false, 0, false, 0} #define meshtastic_HostMetrics_init_zero {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""} @@ -482,6 +488,8 @@ extern "C" { #define meshtastic_AirQualityMetrics_particles_50um_tag 11 #define meshtastic_AirQualityMetrics_particles_100um_tag 12 #define meshtastic_AirQualityMetrics_co2_tag 13 +#define meshtastic_AirQualityMetrics_co2_temperature_tag 14 +#define meshtastic_AirQualityMetrics_co2_humidity_tag 15 #define meshtastic_LocalStats_uptime_seconds_tag 1 #define meshtastic_LocalStats_channel_utilization_tag 2 #define meshtastic_LocalStats_air_util_tx_tag 3 @@ -587,7 +595,9 @@ X(a, STATIC, OPTIONAL, UINT32, particles_10um, 9) \ X(a, STATIC, OPTIONAL, UINT32, particles_25um, 10) \ X(a, STATIC, OPTIONAL, UINT32, particles_50um, 11) \ X(a, STATIC, OPTIONAL, UINT32, particles_100um, 12) \ -X(a, STATIC, OPTIONAL, UINT32, co2, 13) +X(a, STATIC, OPTIONAL, UINT32, co2, 13) \ +X(a, STATIC, OPTIONAL, FLOAT, co2_temperature, 14) \ +X(a, STATIC, OPTIONAL, FLOAT, co2_humidity, 15) #define meshtastic_AirQualityMetrics_CALLBACK NULL #define meshtastic_AirQualityMetrics_DEFAULT NULL @@ -676,7 +686,7 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size -#define meshtastic_AirQualityMetrics_size 78 +#define meshtastic_AirQualityMetrics_size 88 #define meshtastic_DeviceMetrics_size 27 #define meshtastic_EnvironmentMetrics_size 113 #define meshtastic_HealthMetrics_size 11 diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 24be97ad7..7a56c258b 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -87,16 +87,18 @@ static void onNetworkConnected() // start mdns if (!MDNS.begin("Meshtastic")) { - LOG_ERROR("Error setting up MDNS responder!"); + LOG_ERROR("Error setting up mDNS responder!"); } else { LOG_INFO("mDNS Host: Meshtastic.local"); MDNS.addService("meshtastic", "tcp", SERVER_API_DEFAULT_PORT); +// ESPmDNS (ESP32) and SimpleMDNS (RP2040) have slightly different APIs for adding TXT records #ifdef ARCH_ESP32 - MDNS.addService("http", "tcp", 80); - MDNS.addService("https", "tcp", 443); + MDNS.addServiceTxt("meshtastic", "tcp", "shortname", String(owner.short_name)); + MDNS.addServiceTxt("meshtastic", "tcp", "id", String(owner.id)); // ESP32 prints obtained IP address in WiFiEvent #elif defined(ARCH_RP2040) - // ARCH_RP2040 does not support HTTPS + MDNS.addServiceTxt("meshtastic", "shortname", owner.short_name); + MDNS.addServiceTxt("meshtastic", "id", owner.id); LOG_INFO("Obtained IP address: %s", WiFi.localIP().toString().c_str()); #endif } diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index 783c08b9f..403f36a04 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -213,11 +213,14 @@ void setupModules() #if HAS_TELEMETRY new DeviceTelemetryModule(); #endif +// TODO: How to improve this? #if HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR new EnvironmentTelemetryModule(); +#if __has_include("Adafruit_PM25AQI.h") if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) { new AirQualityTelemetryModule(); } +#endif #if !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX30102].first > 0 || nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MLX90614].first > 0) { diff --git a/src/modules/Telemetry/Sensor/MAX17048Sensor.cpp b/src/modules/Telemetry/Sensor/MAX17048Sensor.cpp index 6ab96aa57..1a6792d3a 100644 --- a/src/modules/Telemetry/Sensor/MAX17048Sensor.cpp +++ b/src/modules/Telemetry/Sensor/MAX17048Sensor.cpp @@ -1,6 +1,6 @@ #include "MAX17048Sensor.h" -#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_STM32WL) && __has_include() +#if !MESHTASTIC_EXCLUDE_I2C && __has_include() MAX17048Singleton *MAX17048Singleton::GetInstance() { diff --git a/src/modules/Telemetry/Sensor/MAX17048Sensor.h b/src/modules/Telemetry/Sensor/MAX17048Sensor.h index 6f61421dc..d27169406 100644 --- a/src/modules/Telemetry/Sensor/MAX17048Sensor.h +++ b/src/modules/Telemetry/Sensor/MAX17048Sensor.h @@ -5,7 +5,7 @@ #include "configuration.h" -#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_STM32WL) && __has_include() +#if !MESHTASTIC_EXCLUDE_I2C && __has_include() // Samples to store in a buffer to determine if the battery is charging or discharging #define MAX17048_CHARGING_SAMPLES 3 diff --git a/src/modules/Telemetry/Sensor/nullSensor.cpp b/src/modules/Telemetry/Sensor/nullSensor.cpp index 9522c7fcc..c84b9d27f 100644 --- a/src/modules/Telemetry/Sensor/nullSensor.cpp +++ b/src/modules/Telemetry/Sensor/nullSensor.cpp @@ -20,4 +20,15 @@ bool NullSensor::getMetrics(meshtastic_Telemetry *measurement) { return false; } + +uint16_t NullSensor::getBusVoltageMv() +{ + return 0; +} + +int16_t NullSensor::getCurrentMa() +{ + return 0; +} + #endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/nullSensor.h b/src/modules/Telemetry/Sensor/nullSensor.h index 94dbcc7f8..a400acf97 100644 --- a/src/modules/Telemetry/Sensor/nullSensor.h +++ b/src/modules/Telemetry/Sensor/nullSensor.h @@ -4,9 +4,12 @@ #pragma once #include "../mesh/generated/meshtastic/telemetry.pb.h" -#include "TelemetrySensor.h" -class NullSensor : public TelemetrySensor +#include "CurrentSensor.h" +#include "TelemetrySensor.h" +#include "VoltageSensor.h" + +class NullSensor : public TelemetrySensor, VoltageSensor, CurrentSensor { protected: @@ -17,6 +20,9 @@ class NullSensor : public TelemetrySensor virtual int32_t runOnce() override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override; int32_t runTrigger() { return 0; } + + virtual uint16_t getBusVoltageMv() override; + virtual int16_t getCurrentMa() override; }; #endif \ No newline at end of file diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 3763bce1e..baefbc4eb 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -184,6 +184,8 @@ #define HW_VENDOR meshtastic_HardwareModel_HELTEC_SENSOR_HUB #elif defined(ELECROW_PANEL) #define HW_VENDOR meshtastic_HardwareModel_CROWPANEL +#elif defined(RAK3312) +#define HW_VENDOR meshtastic_HardwareModel_RAK3312 #elif defined(LINK_32) #define HW_VENDOR meshtastic_HardwareModel_LINK_32 #endif diff --git a/src/platform/stm32wl/architecture.h b/src/platform/stm32wl/architecture.h index 325a192a4..ac2bbe5d1 100644 --- a/src/platform/stm32wl/architecture.h +++ b/src/platform/stm32wl/architecture.h @@ -12,6 +12,9 @@ #ifndef HAS_TELEMETRY #define HAS_TELEMETRY 1 #endif +#ifndef HAS_WIRE +#define HAS_WIRE 1 +#endif // // set HW_VENDOR @@ -28,4 +31,4 @@ #define SX126X_CS 1000 #define SX126X_DIO1 1001 #define SX126X_RESET 1003 -#define SX126X_BUSY 1004 \ No newline at end of file +#define SX126X_BUSY 1004 diff --git a/src/power.h b/src/power.h index e7193dd07..c71f96c10 100644 --- a/src/power.h +++ b/src/power.h @@ -30,6 +30,10 @@ #define OCV_ARRAY 4300, 4240, 4120, 4000, 3888, 3800, 3740, 3698, 3655, 3580, 3400 #elif defined(HELTEC_MESH_POCKET_BATTERY_10000) #define OCV_ARRAY 4100, 4060, 3960, 3840, 3729, 3625, 3550, 3500, 3420, 3345, 3100 +#elif defined(SEEED_WIO_TRACKER_L1) +#define OCV_ARRAY 4200, 3876, 3826, 3763, 3713, 3660, 3573, 3485, 3422, 3359, 3300 +#elif defined(SEEED_SOLAR_NODE) +#define OCV_ARRAY 4200, 3986, 3922, 3812, 3734, 3645, 3527, 3420, 3281, 3087, 2786 #else // LiIon #define OCV_ARRAY 4190, 4050, 3990, 3890, 3800, 3720, 3630, 3530, 3420, 3300, 3100 #endif @@ -77,7 +81,7 @@ extern NullSensor ina3221Sensor; #endif -#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL) +#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #if __has_include() #include "modules/Telemetry/Sensor/MAX17048Sensor.h" extern MAX17048Sensor max17048Sensor; diff --git a/variants/diy/hydra/variant.h b/variants/diy/hydra/variant.h index 4c809502e..0d64c1b5e 100644 --- a/variants/diy/hydra/variant.h +++ b/variants/diy/hydra/variant.h @@ -36,8 +36,12 @@ #define SX126X_TXEN 13 // Schematic connects EBYTE module's TXEN pin to MCU #define SX126X_RXEN 14 // Schematic connects EBYTE module's RXEN pin to MCU -#define LORA_CS SX126X_CS // Compatibility with variant file configuration structure -#define LORA_SCK SX126X_SCK // Compatibility with variant file configuration structure -#define LORA_MOSI SX126X_MOSI // Compatibility with variant file configuration structure -#define LORA_MISO SX126X_MISO // Compatibility with variant file configuration structure -#define LORA_DIO1 SX126X_DIO1 // Compatibility with variant file configuration structure +#define LORA_CS SX126X_CS // Compatibility with variant file configuration structure +#define LORA_SCK SX126X_SCK // Compatibility with variant file configuration structure +#define LORA_MOSI SX126X_MOSI // Compatibility with variant file configuration structure +#define LORA_MISO SX126X_MISO // Compatibility with variant file configuration structure +#define LORA_DIO1 SX126X_DIO1 // Compatibility with variant file configuration structure +#define LORA_TXEN SX126X_TXEN // Compatibility with variant file configuration structure +#define LORA_RXEN SX126X_RXEN // Compatibility with variant file configuration structure +#define LORA_RESET SX126X_RESET // Compatibility with variant file configuration structure +#define LORA_DIO2 SX126X_BUSY // Compatibility with variant file configuration structure \ No newline at end of file diff --git a/variants/rak3172/platformio.ini b/variants/rak3172/platformio.ini index 456697aef..99610b17c 100644 --- a/variants/rak3172/platformio.ini +++ b/variants/rak3172/platformio.ini @@ -5,6 +5,8 @@ board_upload.maximum_size = 233472 ; reserve the last 28KB for filesystem build_flags = ${stm32_base.build_flags} -Ivariants/rak3172 + -DPIN_WIRE_SDA=PA11 + -DPIN_WIRE_SCL=PA12 -DHAL_DAC_MODULE_ONLY -DHAL_RNG_MODULE_ENABLED -DRADIOLIB_EXCLUDE_SX128X=1 @@ -18,6 +20,5 @@ build_flags = -DMESHTASTIC_EXCLUDE_SCREEN=1 -DMESHTASTIC_EXCLUDE_MQTT=1 -DMESHTASTIC_EXCLUDE_POWERMON=1 - ;-DPIO_FRAMEWORK_ARDUINO_NANOLIB_FLOAT_PRINTF ;-DCFG_DEBUG upload_port = stlink diff --git a/variants/rak3312/pins_arduino.h b/variants/rak3312/pins_arduino.h new file mode 100644 index 000000000..15a26e991 --- /dev/null +++ b/variants/rak3312/pins_arduino.h @@ -0,0 +1,28 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include "variant.h" +#include + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +// The default Wire will be mapped to PMU and RTC +static const uint8_t SDA = 9; +static const uint8_t SCL = 40; + +// Default SPI will be mapped to Radio +static const uint8_t SS = 12; +static const uint8_t MOSI = 11; +static const uint8_t MISO = 10; +static const uint8_t SCK = 13; + +#define SPI_MOSI (11) +#define SPI_SCK (13) +#define SPI_MISO (10) +#define SPI_CS (12) + +// LEDs +#define LED_BUILTIN LED_GREEN + +#endif /* Pins_Arduino_h */ diff --git a/variants/rak3312/platformio.ini b/variants/rak3312/platformio.ini new file mode 100644 index 000000000..d2877b3f7 --- /dev/null +++ b/variants/rak3312/platformio.ini @@ -0,0 +1,8 @@ +[env:rak3312] +extends = esp32s3_base +board = wiscore_rak3312 +board_check = true +upload_protocol = esptool + +build_flags = + ${esp32_base.build_flags} -D RAK3312 -I variants/rak3312 diff --git a/variants/rak3312/variant.h b/variants/rak3312/variant.h new file mode 100644 index 000000000..dfdf4de71 --- /dev/null +++ b/variants/rak3312/variant.h @@ -0,0 +1,44 @@ +#define I2C_SDA 9 +#define I2C_SCL 40 + +#define USE_SX1262 + +#define LORA_SCK 5 +#define LORA_MISO 3 +#define LORA_MOSI 6 +#define LORA_CS 7 +#define LORA_RESET 8 + +#ifdef USE_SX1262 +#define SX126X_CS LORA_CS +#define SX126X_DIO1 47 +#define SX126X_BUSY 48 +#define SX126X_RESET LORA_RESET +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 +#endif + +#define SX126X_POWER_EN (4) + +#define PIN_POWER_EN PIN_3V3_EN +#define PIN_3V3_EN (14) + +#define LED_GREEN 46 +#define LED_BLUE 45 + +#define PIN_LED1 LED_GREEN +#define PIN_LED2 LED_BLUE + +#define LED_CONN LED_BLUE +#define LED_PIN LED_GREEN +#define ledOff(pin) pinMode(pin, INPUT) + +#define LED_STATE_ON 1 // State when LED is litted + +#define HAS_GPS 1 +#define GPS_TX_PIN 43 +#define GPS_RX_PIN 44 + +#define BATTERY_PIN 1 +#define ADC_CHANNEL ADC1_GPIO1_CHANNEL +#define ADC_MULTIPLIER 1.667 \ No newline at end of file diff --git a/variants/seeed_wio_tracker_L1_eink/nicheGraphics.h b/variants/seeed_wio_tracker_L1_eink/nicheGraphics.h index 7854de4b5..12ec4479a 100644 --- a/variants/seeed_wio_tracker_L1_eink/nicheGraphics.h +++ b/variants/seeed_wio_tracker_L1_eink/nicheGraphics.h @@ -66,7 +66,6 @@ void setupNicheGraphics() inkhud->persistence->settings.optionalFeatures.batteryIcon = true; // Device definitely has a battery inkhud->persistence->settings.optionalMenuItems.backlight = true; // Until proves capacitive button works by touching it inkhud->persistence->settings.userTiles.count = 1; // One tile only by default, keep things simple for new users - inkhud->persistence->settings.optionalMenuItems.nextTile = false; // Behavior handled by aux button instead // Setup backlight controller // Note: AUX button attached further down diff --git a/variants/wio-e5/platformio.ini b/variants/wio-e5/platformio.ini index e746ae2f0..1ef7abd78 100644 --- a/variants/wio-e5/platformio.ini +++ b/variants/wio-e5/platformio.ini @@ -8,20 +8,17 @@ build_flags = -DSERIAL_UART_INSTANCE=1 -DPIN_SERIAL_RX=PB7 -DPIN_SERIAL_TX=PB6 + -DPIN_WIRE_SDA=PA15 + -DPIN_WIRE_SCL=PB15 -DHAL_DAC_MODULE_ONLY -DHAL_RNG_MODULE_ENABLED -DRADIOLIB_EXCLUDE_SX128X=1 -DRADIOLIB_EXCLUDE_SX127X=1 -DRADIOLIB_EXCLUDE_LR11X0=1 - -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR=1 - -DMESHTASTIC_EXCLUDE_I2C=1 - -DMESHTASTIC_EXCLUDE_WIFI=1 - -DMESHTASTIC_EXCLUDE_BLUETOOTH=1 - -DMESHTASTIC_EXCLUDE_GPS=1 - -DMESHTASTIC_EXCLUDE_SCREEN=1 - -DMESHTASTIC_EXCLUDE_MQTT=1 - -DMESHTASTIC_EXCLUDE_POWERMON=1 - ;-DPIO_FRAMEWORK_ARDUINO_NANOLIB_FLOAT_PRINTF - ;-DCFG_DEBUG + -DHAS_SENSOR -upload_port = stlink \ No newline at end of file +upload_port = stlink + +lib_deps = + ${stm32_base.lib_deps} + # Add your custom sensor here! \ No newline at end of file