diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index a6fb39b29..6194bfe69 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -23,9 +23,9 @@ jobs: matrix: include: - board: rak11200 - - board: tlora-v2-1-1.6 + - board: tlora-v2-1-1_6 - board: tbeam - - board: heltec-v2.1 + - board: heltec-v2_1 - board: meshtastic-diy-v1 - board: rak4631 - board: t-echo @@ -57,13 +57,13 @@ jobs: - board: tlora-v2 - board: tlora-v1 - board: tlora_v1_3 - - board: tlora-v2-1-1.6 - - board: tlora-v2-1-1.8 + - board: tlora-v2-1-1_6 + - board: tlora-v2-1-1_8 - board: tbeam - board: heltec-v1 - - board: heltec-v2.0 - - board: heltec-v2.1 - - board: tbeam0.7 + - board: heltec-v2_0 + - board: heltec-v2_1 + - board: tbeam0_7 - board: meshtastic-diy-v1 - board: meshtastic-dr-dev - board: nano-g1 diff --git a/.trunk/.gitignore b/.trunk/.gitignore index cf2f25470..8130ba6d1 100644 --- a/.trunk/.gitignore +++ b/.trunk/.gitignore @@ -5,3 +5,4 @@ plugins user_trunk.yaml user.yaml +shims diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 519a9181e..cdf662e1f 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,36 +1,37 @@ version: 0.1 cli: - version: 1.7.0 + version: 1.9.1 plugins: sources: - id: trunk - ref: v0.0.14 + ref: v0.0.17 uri: https://github.com/trunk-io/plugins lint: enabled: - - ruff@0.0.260 - - yamllint@1.30.0 + - taplo@0.7.0 + - ruff@0.0.265 + - yamllint@1.31.0 - isort@5.12.0 - - markdownlint@0.33.0 + - markdownlint@0.34.0 - oxipng@8.0.0 - svgo@3.0.2 - - actionlint@1.6.23 + - actionlint@1.6.24 - flake8@6.0.0 - hadolint@2.12.0 - shfmt@3.5.0 - shellcheck@0.9.0 - black@23.3.0 - git-diff-check - - gitleaks@8.16.2 + - gitleaks@8.16.3 - clang-format@14.0.0 - - prettier@2.8.7 + - prettier@2.8.8 disabled: - taplo@0.7.0 - shellcheck@0.9.0 - shfmt@3.5.0 - oxipng@8.0.0 - actionlint@1.6.22 - - markdownlint@0.33.0 + - markdownlint@0.34.0 - hadolint@2.12.0 - svgo@3.0.2 runtimes: diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index fb83ec2d4..45409ad7b 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -2,11 +2,14 @@ [esp32_base] extends = arduino_base platform = platformio/espressif32@^6.1.0 + build_src_filter = ${arduino_base.build_src_filter} - - - - + upload_speed = 921600 debug_init_break = tbreak setup monitor_filters = esp32_exception_decoder + board_build.filesystem = littlefs # Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging. @@ -34,6 +37,7 @@ lib_deps = ${environmental_base.lib_deps} https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 h2zero/NimBLE-Arduino@^1.4.0 + jgromes/RadioLib@^6.0.0 https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f diff --git a/arch/esp32/esp32c3.ini b/arch/esp32/esp32c3.ini index 5ebb789ad..619fdb28a 100644 --- a/arch/esp32/esp32c3.ini +++ b/arch/esp32/esp32c3.ini @@ -1,44 +1,5 @@ [esp32c3_base] -extends = arduino_base -platform = platformio/espressif32@^6.1.0 -build_src_filter = - ${arduino_base.build_src_filter} - - - - -upload_speed = 961200 +extends = esp32_base + monitor_speed = 115200 -debug_init_break = tbreak setup monitor_filters = esp32_c3_exception_decoder -board_build.filesystem = littlefs - -# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging. -# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h -# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h -build_flags = - ${arduino_base.build_flags} - -Wall - -Wextra - -Isrc/platform/esp32 - -std=c++11 - -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG - -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL - -DCONFIG_BT_NIMBLE_ENABLED - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 - -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 - -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING - ;-DDEBUG_HEAP - -lib_deps = - ${arduino_base.lib_deps} - ${networking_base.lib_deps} - ${environmental_base.lib_deps} - https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 - h2zero/NimBLE-Arduino@^1.4.0 - https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 - https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f -lib_ignore = - segger_rtt - ESP32 BLE Arduino - -; customize the partition table -; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables -board_build.partitions = partition-table.csv \ No newline at end of file diff --git a/arch/esp32/esp32s2.ini b/arch/esp32/esp32s2.ini index 6e75c08c9..3bde3465a 100644 --- a/arch/esp32/esp32s2.ini +++ b/arch/esp32/esp32s2.ini @@ -1,47 +1,16 @@ [esp32s2_base] -extends = arduino_base -platform = platformio/espressif32@^6.1.0 +extends = esp32_base + build_src_filter = - ${arduino_base.build_src_filter} - - - - - -upload_speed = 961200 + ${esp32_base.build_src_filter} - + monitor_speed = 115200 -debug_init_break = tbreak setup -monitor_filters = esp32_exception_decoder -board_build.filesystem = littlefs -# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging. -# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h -# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h build_flags = - ${arduino_base.build_flags} - -Wall - -Wextra - -Isrc/platform/esp32 - -std=c++11 - -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG - -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL - -DAXP_DEBUG_PORT=Serial - -DCONFIG_BT_NIMBLE_ENABLED - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 - -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 - -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING + ${esp32_base.build_flags} -DHAS_BLUETOOTH=0 - ;-DDEBUG_HEAP -lib_deps = - ${arduino_base.lib_deps} - ${networking_base.lib_deps} - ${environmental_base.lib_deps} - https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 - https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 - https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f - lib_ignore = - segger_rtt - ESP32 BLE Arduino - -; customize the partition table -; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables -board_build.partitions = partition-table.csv + ${esp32_base.lib_ignore} + NimBLE-Arduino diff --git a/arch/esp32/esp32s3.ini b/arch/esp32/esp32s3.ini index bb0214f46..6a1bdd3fd 100644 --- a/arch/esp32/esp32s3.ini +++ b/arch/esp32/esp32s3.ini @@ -1,47 +1,5 @@ [esp32s3_base] -extends = arduino_base -platform = platformio/espressif32@^6.1.0 -build_src_filter = - ${arduino_base.build_src_filter} - - - - -upload_speed = 961200 +extends = esp32_base + monitor_speed = 115200 -debug_init_break = tbreak setup -monitor_filters = esp32_exception_decoder -board_build.filesystem = littlefs - -# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging. -# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h -# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h -build_flags = - ${arduino_base.build_flags} - -Wall - -Wextra - -Isrc/platform/esp32 - -std=c++11 - -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG - -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL - -DAXP_DEBUG_PORT=Serial - -DCONFIG_BT_NIMBLE_ENABLED - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 - -DCONFIG_BT_NIMBLE_MAX_CCCDS=20 - -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING - ;-DDEBUG_HEAP - -lib_deps = - ${arduino_base.lib_deps} - ${networking_base.lib_deps} - ${environmental_base.lib_deps} - https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 - h2zero/NimBLE-Arduino@^1.4.0 - https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6 - https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f - -lib_ignore = - segger_rtt - ESP32 BLE Arduino - -; customize the partition table -; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables -board_build.partitions = partition-table.csv diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini index c2287d7e5..3f1a77d08 100644 --- a/arch/nrf52/nrf52.ini +++ b/arch/nrf52/nrf52.ini @@ -1,18 +1,20 @@ [nrf52_base] ; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files platform = platformio/nordicnrf52@^9.5.0 - extends = arduino_base + build_type = debug ; I'm debugging with ICE a lot now build_flags = ${arduino_base.build_flags} -Wno-unused-variable -Isrc/platform/nrf52 + build_src_filter = ${arduino_base.build_src_filter} - - - - - - - - - + +lib_deps= + ${arduino_base.lib_deps} + jgromes/RadioLib@^6.0.0 + lib_ignore = BluetoothOTA - -; Note: By default no lora device is created for this build - it uses a simulated interface -[env:feather_nrf52832] -extends = nrf52_base -board = adafruit_feather_nrf52832 + diff --git a/arch/nrf52/nrf52832.ini b/arch/nrf52/nrf52832.ini new file mode 100644 index 000000000..ce94283b1 --- /dev/null +++ b/arch/nrf52/nrf52832.ini @@ -0,0 +1,7 @@ +[nrf52832_base] +extends = nrf52_base + +build_flags = ${nrf52_base.build_flags} + +lib_deps = + ${nrf52_base.lib_deps} diff --git a/arch/nrf52/nrf52840.ini b/arch/nrf52/nrf52840.ini index 14cc1d1e1..cf08fd02e 100644 --- a/arch/nrf52/nrf52840.ini +++ b/arch/nrf52/nrf52840.ini @@ -1,14 +1,9 @@ [nrf52840_base] extends = nrf52_base + build_flags = ${nrf52_base.build_flags} + lib_deps = - ${arduino_base.lib_deps} + ${nrf52_base.lib_deps} ${environmental_base.lib_deps} https://github.com/Kongduino/Adafruit_nRFCrypto.git#e31a8825ea3300b163a0a3c1ddd5de34e10e1371 - -; Note: By default no lora device is created for this build - it uses a simulated interface -[env:nrf52840dk] -extends = nrf52840_base -board = nrf52840_dk - - diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index 100f3538d..7e3557475 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -2,6 +2,7 @@ [portduino_base] platform = https://github.com/meshtastic/platform-native.git#096b3c3e9c5c8e19d4c3b6cd803fffef2a9be4c5 framework = arduino + build_src_filter = ${env.build_src_filter} - @@ -16,8 +17,14 @@ build_src_filter = - - +<../variants/portduino> + lib_deps = ${env.lib_deps} ${networking_base.lib_deps} rweather/Crypto@^0.4.0 -build_flags = ${arduino_base.build_flags} -fPIC -Isrc/platform/portduino + jgromes/RadioLib@^6.0.0 + +build_flags = + ${arduino_base.build_flags} + -fPIC + -Isrc/platform/portduino diff --git a/arch/rp2040/rp2040.ini b/arch/rp2040/rp2040.ini index c41f92892..6f5449ae6 100644 --- a/arch/rp2040/rp2040.ini +++ b/arch/rp2040/rp2040.ini @@ -2,6 +2,7 @@ [rp2040_base] platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9f8c10e50b5acd18e7bfd32638199c655be73a5b extends = arduino_base + board_build.core = earlephilhower board_build.filesystem_size = 0.5m build_flags = @@ -11,9 +12,12 @@ build_flags = # -D _POSIX_THREADS build_src_filter = ${arduino_base.build_src_filter} - - - - - - - - - + lib_ignore = BluetoothOTA + lib_deps = ${arduino_base.lib_deps} ${environmental_base.lib_deps} + jgromes/RadioLib@^6.0.0 https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b diff --git a/arch/stm32/stm32wl5e.ini b/arch/stm32/stm32wl5e.ini index a38fb65e8..4d5cee56d 100644 --- a/arch/stm32/stm32wl5e.ini +++ b/arch/stm32/stm32wl5e.ini @@ -2,17 +2,19 @@ platform = platformio/ststm32@^15.4.1 board = generic_wl5e framework = arduino + build_type = debug build_flags = ${arduino_base.build_flags} -Isrc/platform/stm32wl -g - -DHAL_SUBGHZ_MODULE_ENABLED -# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support -# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK + build_src_filter = ${arduino_base.build_src_filter} - - - - - - - - - - - - - - + lib_deps = ${env.lib_deps} + jgromes/RadioLib@^6.0.0 https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b + lib_ignore = mathertel/OneButton@^2.0.3 diff --git a/bpi_picow_esp32_s3.json b/boards/bpi_picow_esp32_s3.json similarity index 100% rename from bpi_picow_esp32_s3.json rename to boards/bpi_picow_esp32_s3.json diff --git a/platformio.ini b/platformio.ini index 508f3615b..2040b75ce 100644 --- a/platformio.ini +++ b/platformio.ini @@ -66,9 +66,6 @@ lib_deps = https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3 nanopb/Nanopb@^0.4.7 erriez/ErriezCRC32@^1.0.1 - ; temp: do this till > 5.7.0 release to keep (some) SX1262 and SX1280 working - resolves -705 error during init - https://github.com/jgromes/RadioLib.git#45c5859338590b7eede23cb2f95284c3fb0cf08e - ; jgromes/RadioLib@^5.7.0 ; Used for the code analysis in PIO Home / Inspect check_tool = cppcheck @@ -105,7 +102,8 @@ lib_deps = adafruit/Adafruit Unified Sensor@^1.1.9 adafruit/Adafruit BMP280 Library@^2.6.6 adafruit/Adafruit BME280 Library@^2.2.2 - https://github.com/meshtastic/BSEC-Arduino-library.git#452f9a7ffa8b53e1debe2c454fe375dfad98b507 + boschsensortec/BSEC2 Software Library@^1.3.2200 + boschsensortec/BME68x Sensor Library@^1.1.40407 adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit INA260 Library@^1.5.0 adafruit/Adafruit INA219@^1.2.0 diff --git a/src/configuration.h b/src/configuration.h index 58e41877d..e1420c8db 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -124,6 +124,11 @@ along with this program. If not, see . #define MPU6050_ADDR 0x68 #define LIS3DH_ADR 0x18 +// ----------------------------------------------------------------------------- +// LED +// ----------------------------------------------------------------------------- +#define NCP5623_ADDR 0x38 + // ----------------------------------------------------------------------------- // Security // ----------------------------------------------------------------------------- diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 01b300c10..a56ce86fe 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -33,6 +33,7 @@ class ScanI2C PMSA0031, MPU6050, LIS3DH, + NCP5623, } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index fb568b552..b7f16734f 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -213,6 +213,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port) break; SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n") + SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n"); #ifdef HAS_PMU SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n") diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp index 6ab2c85bf..ac11d78f8 100644 --- a/src/gps/NMEAWPL.cpp +++ b/src/gps/NMEAWPL.cpp @@ -1,5 +1,7 @@ #include "NMEAWPL.h" #include "GeoCoord.h" +#include "RTC.h" +#include /* ------------------------------------------- * 1 2 3 4 5 6 @@ -56,12 +58,18 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos) { GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude); - uint32_t len = - snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000, - pos.time % 1000, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, - geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), - (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type, - pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); + tm *t = localtime((time_t *)&pos.timestamp); + if (getRTCQuality() > 0) { // use the device clock if we got time from somewhere. If not, use the GPS timestamp. + uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice); + t = localtime((time_t *)&rtc_sec); + } + + uint32_t len = snprintf( + buf, bufsz, "$GNGGA,%02d%02d%02d.%02d,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", t->tm_hour, + t->tm_min, t->tm_sec, pos.timestamp_millis_adjust, geoCoord.getDMSLatDeg(), + (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(), + (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_quality, + pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0); uint32_t chk = 0; for (uint32_t i = 1; i < len; i++) { diff --git a/src/main.cpp b/src/main.cpp index 7af41116c..324422a69 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -100,6 +100,8 @@ uint8_t kb_model; ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE; // The I2C address of the Accelerometer (if found) ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE; +// The I2C address of the RGB LED (if found) +ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE); #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) ATECCX08A atecc; @@ -159,6 +161,7 @@ static OSThread *buttonThread; uint32_t ButtonThread::longPressTime = 0; #endif static OSThread *accelerometerThread; +SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0); RadioInterface *rIf = NULL; @@ -234,8 +237,6 @@ void setup() fsInit(); - router = new ReliableRouter(); - #ifdef I2C_SDA1 Wire1.begin(I2C_SDA1, I2C_SCL1); #endif @@ -346,6 +347,8 @@ void setup() * nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field * "found". */ + // Only one supported RGB LED currently + rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623); #if !defined(ARCH_PORTDUINO) auto acc_info = i2cScanner->firstAccelerometer(); @@ -413,6 +416,8 @@ void setup() // If we're taking on the repeater role, use flood router if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) router = new FloodingRouter(); + else + router = new ReliableRouter(); #if HAS_BUTTON // Buttons. Moved here cause we need NodeDB to be initialized @@ -503,6 +508,10 @@ void setup() digitalWrite(SX126X_ANT_SW, 1); #endif + // Init LockingHAL first, to use it for radio init + + LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings); + // radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init) #if !HAS_RADIO && defined(ARCH_PORTDUINO) @@ -520,7 +529,7 @@ void setup() #if defined(RF95_IRQ) if (!rIf) { - rIf = new RF95Interface(RF95_NSS, RF95_IRQ, RF95_RESET, RF95_DIO1, SPI); + rIf = new RF95Interface(RadioLibHAL, RF95_NSS, RF95_IRQ, RF95_RESET, RF95_DIO1); if (!rIf->init()) { LOG_WARN("Failed to find RF95 radio\n"); delete rIf; @@ -533,7 +542,7 @@ void setup() #if defined(USE_SX1262) if (!rIf) { - rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI); + rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { LOG_WARN("Failed to find SX1262 radio\n"); delete rIf; @@ -546,7 +555,7 @@ void setup() #if defined(USE_SX1268) if (!rIf) { - rIf = new SX1268Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI); + rIf = new SX1268Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { LOG_WARN("Failed to find SX1268 radio\n"); delete rIf; @@ -559,7 +568,7 @@ void setup() #if defined(USE_LLCC68) if (!rIf) { - rIf = new LLCC68Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI); + rIf = new LLCC68Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY); if (!rIf->init()) { LOG_WARN("Failed to find LLCC68 radio\n"); delete rIf; @@ -572,7 +581,7 @@ void setup() #if defined(USE_SX1280) if (!rIf) { - rIf = new SX1280Interface(SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY, SPI); + rIf = new SX1280Interface(RadioLibHAL, SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY); if (!rIf->init()) { LOG_WARN("Failed to find SX1280 radio\n"); delete rIf; diff --git a/src/main.h b/src/main.h index 645ba2ee2..0d23dd10c 100644 --- a/src/main.h +++ b/src/main.h @@ -8,6 +8,7 @@ #include "memGet.h" #include "mesh/generated/meshtastic/config.pb.h" #include "mesh/generated/meshtastic/telemetry.pb.h" +#include #include #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #include @@ -26,6 +27,7 @@ extern ScanI2C::DeviceAddress cardkb_found; extern uint8_t kb_model; extern ScanI2C::DeviceAddress rtc_found; extern ScanI2C::DeviceAddress accelerometer_found; +extern ScanI2C::FoundDevice rgb_found; extern bool eink_found; extern bool pmu_found; @@ -65,3 +67,6 @@ extern bool runASAP; void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(), clearBonds(); meshtastic_DeviceMetadata getDeviceMetadata(); + +// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that +extern SPISettings spiSettings; diff --git a/src/mesh/LLCC68Interface.cpp b/src/mesh/LLCC68Interface.cpp index 05c3c241d..8109765a6 100644 --- a/src/mesh/LLCC68Interface.cpp +++ b/src/mesh/LLCC68Interface.cpp @@ -2,8 +2,8 @@ #include "configuration.h" #include "error.h" -LLCC68Interface::LLCC68Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi) - : SX126xInterface(cs, irq, rst, busy, spi) +LLCC68Interface::LLCC68Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : SX126xInterface(hal, cs, irq, rst, busy) { } \ No newline at end of file diff --git a/src/mesh/LLCC68Interface.h b/src/mesh/LLCC68Interface.h index 7de5e97f9..7e0fa1439 100644 --- a/src/mesh/LLCC68Interface.h +++ b/src/mesh/LLCC68Interface.h @@ -6,12 +6,13 @@ * Our adapter for LLCC68 radios * https://www.semtech.com/products/wireless-rf/lora-core/llcc68 * ⚠️⚠️⚠️ - * Be aware that LLCC68 does not support Spreading Factor 12 (SF12) and will not work on the default "Long Slow" channel. + * Be aware that LLCC68 does not support Spreading Factor 12 (SF12) and will not work on the "LongSlow" and "VLongSlow" channels. * You must change the channel if you get `Critical Error #3` with this module. * ⚠️⚠️⚠️ */ class LLCC68Interface : public SX126xInterface { public: - LLCC68Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi); + LLCC68Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); }; \ No newline at end of file diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index f57aaa055..cf9cd9477 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -11,9 +11,9 @@ #define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level -RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi) - : RadioLibInterface(cs, irq, rst, busy, spi) +RF95Interface::RF95Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : RadioLibInterface(hal, cs, irq, rst, busy) { LOG_WARN("RF95Interface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy); } diff --git a/src/mesh/RF95Interface.h b/src/mesh/RF95Interface.h index 96c3f2476..a50cf93a2 100644 --- a/src/mesh/RF95Interface.h +++ b/src/mesh/RF95Interface.h @@ -12,7 +12,8 @@ class RF95Interface : public RadioLibInterface RadioLibRF95 *lora = NULL; // Either a RFM95 or RFM96 depending on what was stuffed on this board public: - RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi); + RF95Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); // TODO: Verify that this irq flag works with RFM95 / SX1276 radios the way it used to bool isIRQPending() override { return lora->getIRQFlags() & RADIOLIB_SX127X_MASK_IRQ_FLAG_VALID_HEADER; } @@ -39,7 +40,7 @@ class RF95Interface : public RadioLibInterface /** * Enable a particular ISR callback glue function */ - virtual void enableInterrupt(void (*callback)()) { lora->setDio0Action(callback); } + virtual void enableInterrupt(void (*callback)()) { lora->setDio0Action(callback, RISING); } /** can we detect a LoRa preamble on the current channel? */ virtual bool isChannelActive() override; diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index c624bc168..8fd715718 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -9,26 +9,23 @@ #include #include -// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that -static SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0); - -void LockingModule::SPIbeginTransaction() +void LockingArduinoHal::spiBeginTransaction() { spiLock->lock(); - Module::SPIbeginTransaction(); + ArduinoHal::spiBeginTransaction(); } -void LockingModule::SPIendTransaction() +void LockingArduinoHal::spiEndTransaction() { spiLock->unlock(); - Module::SPIendTransaction(); + ArduinoHal::spiEndTransaction(); } -RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi, PhysicalLayer *_iface) - : NotifiedWorkerThread("RadioIf"), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface) +RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy, PhysicalLayer *_iface) + : NotifiedWorkerThread("RadioIf"), module(hal, cs, irq, rst, busy), iface(_iface) { instance = this; #if defined(ARCH_STM32WL) && defined(USE_SX1262) diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index c5cc85df7..6635089e5 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -13,35 +13,18 @@ #define INTERRUPT_ATTR #endif +#define RADIOLIB_PIN_TYPE uint32_t + /** - * A wrapper for the RadioLib Module class, that adds mutex for SPI bus access + * We need to override the RadioLib ArduinoHal class to add mutex protection for SPI bus access */ -class LockingModule : public Module +class LockingArduinoHal : public ArduinoHal { public: - /*! - \brief Extended SPI-based module constructor. + LockingArduinoHal(SPIClass &spi, SPISettings spiSettings) : ArduinoHal(spi, spiSettings){}; - \param cs Arduino pin to be used as chip select. - - \param irq Arduino pin to be used as interrupt/GPIO. - - \param rst Arduino pin to be used as hardware reset for the module. - - \param gpio Arduino pin to be used as additional interrupt/GPIO. - - \param spi SPI interface to be used, can also use software SPI implementations. - - \param spiSettings SPI interface settings. - */ - LockingModule(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE gpio, SPIClass &spi, - SPISettings spiSettings) - : Module(cs, irq, rst, gpio, spi, spiSettings) - { - } - - void SPIbeginTransaction() override; - void SPIendTransaction() override; + void spiBeginTransaction() override; + void spiEndTransaction() override; }; class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread @@ -73,7 +56,7 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified float currentLimit = 100; // 100mA OCP - Should be acceptable for RFM95/SX127x chipset. - LockingModule module; // The HW interface to the radio + Module module; // The HW interface to the radio /** * provides lowest common denominator RadioLib API @@ -99,8 +82,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified virtual void enableInterrupt(void (*)()) = 0; public: - RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi, - PhysicalLayer *iface = NULL); + RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy, PhysicalLayer *iface = NULL); virtual ErrorCode send(meshtastic_MeshPacket *p) override; diff --git a/src/mesh/RadioLibRF95.cpp b/src/mesh/RadioLibRF95.cpp index ad4b75a1f..0fa6c7fe8 100644 --- a/src/mesh/RadioLibRF95.cpp +++ b/src/mesh/RadioLibRF95.cpp @@ -79,5 +79,5 @@ bool RadioLibRF95::isReceiving() uint8_t RadioLibRF95::readReg(uint8_t addr) { - return _mod->SPIreadRegister(addr); + return mod->SPIreadRegister(addr); } \ No newline at end of file diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp index 3bd402ed1..e96e72b71 100644 --- a/src/mesh/SX1262Interface.cpp +++ b/src/mesh/SX1262Interface.cpp @@ -2,8 +2,8 @@ #include "configuration.h" #include "error.h" -SX1262Interface::SX1262Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi) - : SX126xInterface(cs, irq, rst, busy, spi) +SX1262Interface::SX1262Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : SX126xInterface(hal, cs, irq, rst, busy) { } \ No newline at end of file diff --git a/src/mesh/SX1262Interface.h b/src/mesh/SX1262Interface.h index 0f029ada9..31a12ae90 100644 --- a/src/mesh/SX1262Interface.h +++ b/src/mesh/SX1262Interface.h @@ -8,5 +8,6 @@ class SX1262Interface : public SX126xInterface { public: - SX1262Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi); + SX1262Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); }; \ No newline at end of file diff --git a/src/mesh/SX1268Interface.cpp b/src/mesh/SX1268Interface.cpp index 62cdfefe0..ea299fce5 100644 --- a/src/mesh/SX1268Interface.cpp +++ b/src/mesh/SX1268Interface.cpp @@ -2,9 +2,9 @@ #include "configuration.h" #include "error.h" -SX1268Interface::SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi) - : SX126xInterface(cs, irq, rst, busy, spi) +SX1268Interface::SX1268Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : SX126xInterface(hal, cs, irq, rst, busy) { } diff --git a/src/mesh/SX1268Interface.h b/src/mesh/SX1268Interface.h index f40fcf37b..c8bcf20a7 100644 --- a/src/mesh/SX1268Interface.h +++ b/src/mesh/SX1268Interface.h @@ -10,5 +10,6 @@ class SX1268Interface : public SX126xInterface public: virtual float getFreq() override; - SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi); + SX1268Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); }; diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp index acf84d1b6..c26b773f7 100644 --- a/src/mesh/SX126xInterface.cpp +++ b/src/mesh/SX126xInterface.cpp @@ -9,9 +9,9 @@ #endif template -SX126xInterface::SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi) - : RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module) +SX126xInterface::SX126xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : RadioLibInterface(hal, cs, irq, rst, busy, &lora), lora(&module) { LOG_WARN("SX126xInterface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy); } diff --git a/src/mesh/SX126xInterface.h b/src/mesh/SX126xInterface.h index f7ed270d4..f2c861743 100644 --- a/src/mesh/SX126xInterface.h +++ b/src/mesh/SX126xInterface.h @@ -9,7 +9,8 @@ template class SX126xInterface : public RadioLibInterface { public: - SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi); + SX126xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); /// Initialise the Driver transport hardware and software. /// Make sure the Driver is properly configured before calling init(). diff --git a/src/mesh/SX1280Interface.cpp b/src/mesh/SX1280Interface.cpp index e19e3e573..3287f141f 100644 --- a/src/mesh/SX1280Interface.cpp +++ b/src/mesh/SX1280Interface.cpp @@ -2,8 +2,8 @@ #include "configuration.h" #include "error.h" -SX1280Interface::SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi) - : SX128xInterface(cs, irq, rst, busy, spi) +SX1280Interface::SX1280Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : SX128xInterface(hal, cs, irq, rst, busy) { } diff --git a/src/mesh/SX1280Interface.h b/src/mesh/SX1280Interface.h index 0c905cd12..8f2c4ec2e 100644 --- a/src/mesh/SX1280Interface.h +++ b/src/mesh/SX1280Interface.h @@ -9,5 +9,6 @@ class SX1280Interface : public SX128xInterface { public: - SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi); + SX1280Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); }; diff --git a/src/mesh/SX128xInterface.cpp b/src/mesh/SX128xInterface.cpp index e271cb718..691d5dff0 100644 --- a/src/mesh/SX128xInterface.cpp +++ b/src/mesh/SX128xInterface.cpp @@ -9,9 +9,9 @@ #endif template -SX128xInterface::SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi) - : RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module) +SX128xInterface::SX128xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : RadioLibInterface(hal, cs, irq, rst, busy, &lora), lora(&module) { LOG_WARN("SX128xInterface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy); } diff --git a/src/mesh/SX128xInterface.h b/src/mesh/SX128xInterface.h index 434d4b1d9..3aaf31b1c 100644 --- a/src/mesh/SX128xInterface.h +++ b/src/mesh/SX128xInterface.h @@ -9,7 +9,8 @@ template class SX128xInterface : public RadioLibInterface { public: - SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi); + SX128xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); /// Initialise the Driver transport hardware and software. /// Make sure the Driver is properly configured before calling init(). diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index 3c931f3e2..7dbf78a08 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -8,6 +8,17 @@ #include "mesh/generated/meshtastic/rtttl.pb.h" #include +#include "main.h" + +#ifdef RAK4630 +#include +NCP5623 rgb; + +uint8_t red = 0; +uint8_t green = 0; +uint8_t blue = 0; +#endif + #ifndef PIN_BUZZER #define PIN_BUZZER false #endif @@ -73,6 +84,15 @@ int32_t ExternalNotificationModule::runOnce() millis()) { getExternal(2) ? setExternalOff(2) : setExternalOn(2); } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + green = (green + 50) % 255; + red = abs(red - green) % 255; + blue = abs(blue / red) % 255; + + rgb.setColor(red, green, blue); + } +#endif } // now let the PWM buzzer play @@ -84,6 +104,7 @@ int32_t ExternalNotificationModule::runOnce() rtttl::begin(config.device.buzzer_gpio, rtttlConfig.ringtone); } } + return 25; } } @@ -106,6 +127,11 @@ void ExternalNotificationModule::setExternalOn(uint8_t index) digitalWrite(output, (moduleConfig.external_notification.active ? true : false)); break; } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + rgb.setColor(red, green, blue); + } +#endif } void ExternalNotificationModule::setExternalOff(uint8_t index) @@ -126,6 +152,15 @@ void ExternalNotificationModule::setExternalOff(uint8_t index) digitalWrite(output, (moduleConfig.external_notification.active ? false : true)); break; } + +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + red = 0; + green = 0; + blue = 0; + rgb.setColor(red, green, blue); + } +#endif } bool ExternalNotificationModule::getExternal(uint8_t index) @@ -200,6 +235,12 @@ ExternalNotificationModule::ExternalNotificationModule() LOG_INFO("Using Pin %i in PWM mode\n", config.device.buzzer_gpio); } } +#ifdef RAK4630 + if (rgb_found.type == ScanI2C::NCP5623) { + rgb.begin(); + rgb.setCurrent(10); + } +#endif } else { LOG_INFO("External Notification Module Disabled\n"); disable(); @@ -300,7 +341,6 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms; } } - setIntervalFromNow(0); // run once so we know if we should do something } diff --git a/src/modules/RemoteHardwareModule.cpp b/src/modules/RemoteHardwareModule.cpp index fb455af44..c3232d266 100644 --- a/src/modules/RemoteHardwareModule.cpp +++ b/src/modules/RemoteHardwareModule.cpp @@ -18,7 +18,7 @@ static void pinModes(uint64_t mask, uint8_t mode) { for (uint64_t i = 0; i < NUM_GPIOS; i++) { - if (mask & (1 << i)) { + if (mask & (1ULL << i)) { pinMode(i, mode); } } @@ -29,13 +29,10 @@ static uint64_t digitalReads(uint64_t mask) { uint64_t res = 0; - // The Arduino docs show to run pinMode(). But, when testing, found it is best not to. - // If the line below is uncommented, read will flip the pin to the default of the second - // argument in pinModes(), which will make the read turn the PIN "on". - // pinModes(mask, INPUT_PULLUP); + pinModes(mask, INPUT_PULLUP); for (uint64_t i = 0; i < NUM_GPIOS; i++) { - uint64_t m = 1 << i; + uint64_t m = 1ULL << i; if (mask & m) { if (digitalRead(i)) { res |= m; @@ -64,7 +61,7 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r screen->print("Write GPIOs\n"); for (uint8_t i = 0; i < NUM_GPIOS; i++) { - uint64_t mask = 1 << i; + uint64_t mask = 1ULL << i; if (p.gpio_mask & mask) { digitalWrite(i, (p.gpio_value & mask) ? 1 : 0); } diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp index df86da1bd..43e4c0386 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp +++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp @@ -13,8 +13,8 @@ int32_t BME680Sensor::runOnce() return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; } bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire); - if (bme680.bsecStatus == BSEC_OK) { - bme680.setConfig(bsec_config_iaq); + if (bme680.status == BSEC_OK) { + bme680.setConfig(Default_H2S_NonH2S_config); loadState(); bme680.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP); status = 1; @@ -30,10 +30,12 @@ void BME680Sensor::setup() {} bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) { bme680.run(); - measurement->variant.environment_metrics.temperature = bme680.temperature; - measurement->variant.environment_metrics.relative_humidity = bme680.humidity; - measurement->variant.environment_metrics.barometric_pressure = bme680.pressure / 100.0F; - measurement->variant.environment_metrics.gas_resistance = bme680.gasResistance / 1000.0; + + measurement->variant.environment_metrics.temperature = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE).signal; + measurement->variant.environment_metrics.relative_humidity = + bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY).signal; + measurement->variant.environment_metrics.barometric_pressure = bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal / 100.0F; + measurement->variant.environment_metrics.gas_resistance = bme680.getData(BSEC_OUTPUT_RAW_GAS).signal / 1000.0; // Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms) updateState(); return true; @@ -62,12 +64,13 @@ void BME680Sensor::updateState() bool update = false; if (stateUpdateCounter == 0) { /* First state update when IAQ accuracy is >= 3 */ - if (bme680.iaqAccuracy >= 3) { - LOG_DEBUG("%s state update IAQ accuracy %u >= 3\n", sensorName, bme680.iaqAccuracy); + accuracy = bme680.getData(BSEC_OUTPUT_IAQ).accuracy; + if (accuracy >= 3) { + LOG_DEBUG("%s state update IAQ accuracy %u >= 3\n", sensorName, accuracy); update = true; stateUpdateCounter++; } else { - LOG_DEBUG("%s not updated, IAQ accuracy is %u >= 3\n", sensorName, bme680.iaqAccuracy); + LOG_DEBUG("%s not updated, IAQ accuracy is %u >= 3\n", sensorName, accuracy); } } else { /* Update every STATE_SAVE_PERIOD minutes */ diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h index 74aff835a..6b45a76f4 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.h +++ b/src/modules/Telemetry/Sensor/BME680Sensor.h @@ -1,22 +1,21 @@ #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" -#include +#include #define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis() -const uint8_t bsec_config_iaq[] = { -#include -}; +#include "config/Default_H2S_NonH2S/Default_H2S_NonH2S.h" class BME680Sensor : virtual public TelemetrySensor { private: - Bsec bme680; + Bsec2 bme680; protected: virtual void setup() override; const char *bsecConfigFileName = "/prefs/bsec.dat"; uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0}; + uint8_t accuracy = 0; uint16_t stateUpdateCounter = 0; bsec_virtual_sensor_t sensorList[13] = {BSEC_OUTPUT_IAQ, BSEC_OUTPUT_STATIC_IAQ, diff --git a/src/sleep.cpp b/src/sleep.cpp index c25e3473e..e612b0032 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -309,8 +309,13 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r // assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK); #endif #ifdef BUTTON_PIN +#if SOC_PM_SUPPORT_EXT_WAKEUP esp_sleep_enable_ext0_wakeup((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN), LOW); // when user presses, this button goes low +#else + esp_sleep_enable_gpio_wakeup(); + gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); +#endif #endif #if defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC) gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL); // SX126x/SX128x interrupt, active high diff --git a/variants/Dongle_nRF52840-pca10059-v1/platformio.ini b/variants/Dongle_nRF52840-pca10059-v1/platformio.ini index ea14d1a21..a937bfa98 100644 --- a/variants/Dongle_nRF52840-pca10059-v1/platformio.ini +++ b/variants/Dongle_nRF52840-pca10059-v1/platformio.ini @@ -3,6 +3,7 @@ extends = nrf52840_base board = nordic_pca10059 board_level = extra build_flags = ${nrf52840_base.build_flags} -Ivariants/Dongle_nRF52840-pca10059-v1 -D NORDIC_PCA10059 + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/Dongle_nRF52840-pca10059-v1> lib_deps = ${nrf52840_base.lib_deps} diff --git a/variants/MakePython_nRF52840_eink/platformio.ini b/variants/MakePython_nRF52840_eink/platformio.ini index 9ed5a8594..2b08ec9a1 100644 --- a/variants/MakePython_nRF52840_eink/platformio.ini +++ b/variants/MakePython_nRF52840_eink/platformio.ini @@ -3,6 +3,7 @@ board_level = extra extends = nrf52840_base board = nordic_pca10059 build_flags = ${nrf52840_base.build_flags} -Ivariants/MakePython_nRF52840_eink -D PRIVATE_HW + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" -D PIN_EINK_EN build_src_filter = ${nrf52_base.build_src_filter} +<../variants/MakePython_nRF52840_eink> lib_deps = diff --git a/variants/MakePython_nRF52840_oled/platformio.ini b/variants/MakePython_nRF52840_oled/platformio.ini index 9332bd786..e0ddb1377 100644 --- a/variants/MakePython_nRF52840_oled/platformio.ini +++ b/variants/MakePython_nRF52840_oled/platformio.ini @@ -3,6 +3,7 @@ board_level = extra extends = nrf52840_base board = nordic_pca10059 build_flags = ${nrf52840_base.build_flags} -Ivariants/MakePython_nRF52840_oled -D PRIVATE_HW + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/MakePython_nRF52840_oled> lib_deps = ${nrf52840_base.lib_deps} diff --git a/variants/ai-c3/platformio.ini b/variants/ai-c3/platformio.ini index 76ecd9f0f..2869ca580 100644 --- a/variants/ai-c3/platformio.ini +++ b/variants/ai-c3/platformio.ini @@ -2,7 +2,7 @@ extends = esp32c3_base board = esp32-c3-devkitm-1 board_level = extra -build_flags = - ${esp32_base.build_flags} +build_flags = ${esp32c3_base.build_flags} -D PRIVATE_HW -I variants/ai-c3 + diff --git a/variants/ai-c3/variant.h b/variants/ai-c3/variant.h index 05f0abb51..352d189f1 100644 --- a/variants/ai-c3/variant.h +++ b/variants/ai-c3/variant.h @@ -1,26 +1,30 @@ -// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep +#define SDA 0 +#define SCL 1 +#define I2C_SDA SDA +#define I2C_SCL SCL -#define I2C_SDA 8 -#define I2C_SCL 9 - -#define BUTTON_PIN 0 +#define BUTTON_PIN 9 // BOOT button +#define LED_PIN 30 // RGB LED #define USE_RF95 -#undef RF95_SCK #define RF95_SCK 4 -#undef RF95_MISO #define RF95_MISO 5 -#undef RF95_MOSI #define RF95_MOSI 6 -#undef RF95_NSS #define RF95_NSS 7 -#define LORA_DIO0 10 // a No connect on the SX1262 module -#define LORA_DIO1 3 // a No connect on the SX1262 module +#define LORA_DIO0 10 +#define LORA_DIO1 3 #define LORA_RESET 2 +// WaveShare Core1262-868M +// https://www.waveshare.com/wiki/Core1262-868M +#define USE_SX1262 +#define SX126X_CS RF95_NSS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY 10 +#define SX126X_RESET LORA_RESET +#define SX126X_E22 // use DIO2 as RF switch + +#define HAS_GPS 0 #undef GPS_RX_PIN #undef GPS_TX_PIN - -#define HAS_SCREEN 0 -#define HAS_GPS 0 diff --git a/variants/diy/platformio.ini b/variants/diy/platformio.ini index d50d0c4f3..612035717 100644 --- a/variants/diy/platformio.ini +++ b/variants/diy/platformio.ini @@ -11,7 +11,7 @@ build_flags = -I variants/diy/v1 ; Meshtastic DIY v1.1 new schematic based on ESP32-WROOM-32 & SX1262/SX1268 modules -[env:meshtastic-diy-v1.1] +[env:meshtastic-diy-v1_1] extends = esp32_base board = esp32doit-devkit-v1 board_level = extra diff --git a/variants/feather_diy/platformio.ini b/variants/feather_diy/platformio.ini index 9b4806343..924f9098d 100644 --- a/variants/feather_diy/platformio.ini +++ b/variants/feather_diy/platformio.ini @@ -4,6 +4,7 @@ extends = nrf52840_base board = adafruit_feather_nrf52840 board_level = extra build_flags = ${nrf52840_base.build_flags} -Ivariants/feather_diy -Dfeather_diy + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/feather_diy> lib_deps = ${nrf52840_base.lib_deps} diff --git a/variants/heltec_v2.1/platformio.ini b/variants/heltec_v2.1/platformio.ini index 792a1bb94..29f544f7a 100644 --- a/variants/heltec_v2.1/platformio.ini +++ b/variants/heltec_v2.1/platformio.ini @@ -1,4 +1,4 @@ -[env:heltec-v2.1] +[env:heltec-v2_1] ;build_type = debug ; to make it possible to step through our jtag debugger extends = esp32_base board = heltec_wifi_lora_32_V2 diff --git a/variants/heltec_v2/platformio.ini b/variants/heltec_v2/platformio.ini index 8a60942a9..3289f4e68 100644 --- a/variants/heltec_v2/platformio.ini +++ b/variants/heltec_v2/platformio.ini @@ -1,4 +1,4 @@ -[env:heltec-v2.0] +[env:heltec-v2_0] ;build_type = debug ; to make it possible to step through our jtag debugger extends = esp32_base board = heltec_wifi_lora_32_V2 diff --git a/variants/heltec_wsl_v3/variant.h b/variants/heltec_wsl_v3/variant.h index bd7a03a99..66415741b 100644 --- a/variants/heltec_wsl_v3/variant.h +++ b/variants/heltec_wsl_v3/variant.h @@ -1,3 +1,6 @@ +#define I2C_SCL 47 +#define I2C_SDA 48 + #define LED_PIN LED #define HAS_SCREEN 0 diff --git a/variants/lora_relay_v1/platformio.ini b/variants/lora_relay_v1/platformio.ini index 8df7bd1d6..77402aadc 100644 --- a/variants/lora_relay_v1/platformio.ini +++ b/variants/lora_relay_v1/platformio.ini @@ -15,6 +15,7 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v1 -DTFT_DC=ST7735_RS -DTFT_RST=ST7735_RESET -DSPI_FREQUENCY=27000000 + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_relay_v1> lib_deps = ${nrf52840_base.lib_deps} diff --git a/variants/lora_relay_v2/platformio.ini b/variants/lora_relay_v2/platformio.ini index 1be8ced1f..4439d8a46 100644 --- a/variants/lora_relay_v2/platformio.ini +++ b/variants/lora_relay_v2/platformio.ini @@ -17,6 +17,7 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v2 -DSPI_FREQUENCY=27000000 -DTFT_WR=ST7735_SDA -DTFT_SCLK=ST7735_SCK + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/lora_relay_v2> lib_deps = ${nrf52840_base.lib_deps} diff --git a/variants/pca10056-rc-clock/platformio.ini b/variants/pca10056-rc-clock/platformio.ini index d965753d3..0467b1417 100644 --- a/variants/pca10056-rc-clock/platformio.ini +++ b/variants/pca10056-rc-clock/platformio.ini @@ -5,4 +5,5 @@ extends = nrf52840_base board = nrf52840_dk_modified # add our variants files to the include and src paths build_flags = ${nrf52_base.build_flags} -Ivariants/pca10056-rc-clock + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/pca10056-rc-clock> \ No newline at end of file diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index a0928605f..34eed88dd 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -3,12 +3,14 @@ extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631 + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> + + + lib_deps = ${nrf52840_base.lib_deps} ${networking_base.lib_deps} melopero/Melopero RV3028@^1.1.0 https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink \ No newline at end of file diff --git a/variants/rak4631_epaper/platformio.ini b/variants/rak4631_epaper/platformio.ini index fd266c07f..0871eee45 100644 --- a/variants/rak4631_epaper/platformio.ini +++ b/variants/rak4631_epaper/platformio.ini @@ -3,11 +3,13 @@ extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631_epaper -D RAK_4631 + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631_epaper> lib_deps = ${nrf52840_base.lib_deps} zinggjm/GxEPD2@^1.4.9 melopero/Melopero RV3028@^1.1.0 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink \ No newline at end of file diff --git a/variants/rak4631_epaper_onrxtx/platformio.ini b/variants/rak4631_epaper_onrxtx/platformio.ini index 920380011..08c55d129 100644 --- a/variants/rak4631_epaper_onrxtx/platformio.ini +++ b/variants/rak4631_epaper_onrxtx/platformio.ini @@ -4,12 +4,14 @@ board_level = extra extends = nrf52840_base board = wiscore_rak4631 build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631_epaper -D RAK_4631 + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" -D PIN_EINK_EN=34 build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631_epaper_onrxtx> lib_deps = ${nrf52840_base.lib_deps} zinggjm/GxEPD2@^1.5.1 melopero/Melopero RV3028@^1.1.0 + rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink diff --git a/variants/t-echo/platformio.ini b/variants/t-echo/platformio.ini index 201c14657..2f043108c 100644 --- a/variants/t-echo/platformio.ini +++ b/variants/t-echo/platformio.ini @@ -8,7 +8,8 @@ debug_tool = jlink # define build flags for the TFT_eSPI library - NOTE: WE NOT LONGER USE TFT_eSPI, it was for an earlier version of the TTGO eink screens # -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30 # add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling. -build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo +build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo + -L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard" build_src_filter = ${nrf52_base.build_src_filter} +<../variants/t-echo> lib_deps = ${nrf52840_base.lib_deps} diff --git a/variants/tbeam_v07/platformio.ini b/variants/tbeam_v07/platformio.ini index 22258b64c..5428b0e2a 100644 --- a/variants/tbeam_v07/platformio.ini +++ b/variants/tbeam_v07/platformio.ini @@ -1,5 +1,5 @@ ; The original TBEAM board without the AXP power chip and a few other changes -[env:tbeam0.7] +[env:tbeam0_7] extends = esp32_base board = ttgo-t-beam board_level = extra diff --git a/variants/tlora_v2_1_16/platformio.ini b/variants/tlora_v2_1_16/platformio.ini index 84ffc1ea8..da2a32ce4 100644 --- a/variants/tlora_v2_1_16/platformio.ini +++ b/variants/tlora_v2_1_16/platformio.ini @@ -1,4 +1,4 @@ -[env:tlora-v2-1-1.6] +[env:tlora-v2-1-1_6] extends = esp32_base board = ttgo-lora32-v21 build_flags = diff --git a/variants/tlora_v2_1_18/platformio.ini b/variants/tlora_v2_1_18/platformio.ini index 01741ca13..36d6a3157 100644 --- a/variants/tlora_v2_1_18/platformio.ini +++ b/variants/tlora_v2_1_18/platformio.ini @@ -1,4 +1,4 @@ -[env:tlora-v2-1-1.8] +[env:tlora-v2-1-1_8] extends = esp32_base board = ttgo-lora32-v21 diff --git a/version.properties b/version.properties index 3c943e966..0e33ac38b 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 1 -build = 11 +build = 12