mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-13 00:35:16 +00:00
Merge remote-tracking branch 'remotes/origin/master' into apollo
# Conflicts: # arch/nrf52/nrf52.ini # arch/portduino/portduino.ini # arch/rp2040/rp2040.ini # arch/stm32/stm32wl5e.ini
This commit is contained in:
commit
dcae45d287
1
.github/workflows/main_matrix.yml
vendored
1
.github/workflows/main_matrix.yml
vendored
@ -123,6 +123,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- board: pico
|
- board: pico
|
||||||
|
- board: picow
|
||||||
- board: rak11310
|
- board: rak11310
|
||||||
uses: ./.github/workflows/build_rpi2040.yml
|
uses: ./.github/workflows/build_rpi2040.yml
|
||||||
with:
|
with:
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
version: 0.1
|
version: 0.1
|
||||||
cli:
|
cli:
|
||||||
version: 1.17.1
|
version: 1.17.2
|
||||||
plugins:
|
plugins:
|
||||||
sources:
|
sources:
|
||||||
- id: trunk
|
- id: trunk
|
||||||
ref: v1.2.6
|
ref: v1.3.0
|
||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- bandit@1.7.5
|
- bandit@1.7.5
|
||||||
- checkov@3.0.16
|
- checkov@3.1.9
|
||||||
- terrascan@1.18.3
|
- terrascan@1.18.5
|
||||||
- trivy@0.46.1
|
- trivy@0.47.0
|
||||||
- trufflehog@3.62.1
|
- trufflehog@3.63.2-rc0
|
||||||
- taplo@0.8.1
|
- taplo@0.8.1
|
||||||
- ruff@0.1.3
|
- ruff@0.1.6
|
||||||
- yamllint@1.32.0
|
- yamllint@1.33.0
|
||||||
- isort@5.12.0
|
- isort@5.12.0
|
||||||
- markdownlint@0.37.0
|
- markdownlint@0.37.0
|
||||||
- oxipng@9.0.0
|
- oxipng@9.0.0
|
||||||
- svgo@3.0.2
|
- svgo@3.0.5
|
||||||
- actionlint@1.6.26
|
- actionlint@1.6.26
|
||||||
- flake8@6.1.0
|
- flake8@6.1.0
|
||||||
- hadolint@2.12.0
|
- hadolint@2.12.0
|
||||||
@ -27,9 +27,9 @@ lint:
|
|||||||
- shellcheck@0.9.0
|
- shellcheck@0.9.0
|
||||||
- black@23.9.1
|
- black@23.9.1
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.18.0
|
- gitleaks@8.18.1
|
||||||
- clang-format@16.0.3
|
- clang-format@16.0.3
|
||||||
- prettier@3.0.3
|
- prettier@3.1.0
|
||||||
runtimes:
|
runtimes:
|
||||||
enabled:
|
enabled:
|
||||||
- python@3.10.8
|
- python@3.10.8
|
||||||
|
@ -1,15 +1,30 @@
|
|||||||
[apollo3_base]
|
[apollo3_base]
|
||||||
platform = https://github.com/nigelb/platform-apollo3blue.git#e24b0b1970aab9e7b20d759e5e86ce6b2647d1e1
|
platform = https://github.com/nigelb/platform-apollo3blue.git#2e8a9895cf82f2836c483885e6f89b3f83d3ade4
|
||||||
platform_packages=framework-arduinoapollo3@https://github.com/sparkfun/Arduino_Apollo3#v2.2.1
|
platform_packages=framework-arduinoapollo3@https://github.com/sparkfun/Arduino_Apollo3#v2.2.2rc2
|
||||||
framework = arduino
|
framework = arduino
|
||||||
build_type = debug
|
build_type = debug
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
-Isrc/platform/apollo3 -g
|
-Isrc/platform/apollo3 -g
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<graphics> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040> -<platform/stm32wl>
|
${arduino_base.build_src_filter}
|
||||||
|
-<platform/nrf52>
|
||||||
|
-<platform/esp32/>
|
||||||
|
-<platform/rp2040>
|
||||||
|
-<platform/portduino>
|
||||||
|
-<platform/stm32wl>
|
||||||
|
-<nimble/>
|
||||||
|
-<mesh/api/>
|
||||||
|
-<mesh/http/>
|
||||||
|
-<modules/esp32>
|
||||||
|
-<mesh/eth/>
|
||||||
|
-<mqtt/>
|
||||||
|
-<graphics>
|
||||||
|
-<input>
|
||||||
|
-<buzz>
|
||||||
|
-<modules/Telemetry>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
jgromes/RadioLib@^6.1.0
|
jgromes/RadioLib@^6.3.0
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
mathertel/OneButton@^2.0.3
|
mathertel/OneButton
|
||||||
|
@ -4,7 +4,12 @@ extends = arduino_base
|
|||||||
platform = platformio/espressif32@6.3.2 # This is a temporary fix to the S3-based devices bluetooth issues until we can determine what within ESP-IDF changed and can develop a suitable patch.
|
platform = platformio/espressif32@6.3.2 # This is a temporary fix to the S3-based devices bluetooth issues until we can determine what within ESP-IDF changed and can develop a suitable patch.
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<platform/apollo3> -<mesh/eth/>
|
${arduino_base.build_src_filter}
|
||||||
|
-<platform/nrf52/>
|
||||||
|
-<platform/stm32wl>
|
||||||
|
-<platform/rp2040>
|
||||||
|
-<platform/apollo3>
|
||||||
|
-<mesh/eth/>
|
||||||
|
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
debug_init_break = tbreak setup
|
debug_init_break = tbreak setup
|
||||||
|
@ -11,7 +11,17 @@ build_flags =
|
|||||||
-Isrc/platform/nrf52
|
-Isrc/platform/nrf52
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2040> -<platform/apollo3> -<mesh/eth/>
|
${arduino_base.build_src_filter}
|
||||||
|
-<platform/esp32/>
|
||||||
|
-<platform/stm32wl>
|
||||||
|
-<nimble/>
|
||||||
|
-<mesh/wifi/>
|
||||||
|
-<mesh/api/>
|
||||||
|
-<mesh/http/>
|
||||||
|
-<modules/esp32>
|
||||||
|
-<platform/rp2040>
|
||||||
|
-<mesh/eth/>
|
||||||
|
-<platform/apollo3>
|
||||||
|
|
||||||
lib_deps=
|
lib_deps=
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
|
@ -11,6 +11,7 @@ build_src_filter =
|
|||||||
-<platform/stm32wl/>
|
-<platform/stm32wl/>
|
||||||
-<platform/rp2040>
|
-<platform/rp2040>
|
||||||
-<platform/apollo3>
|
-<platform/apollo3>
|
||||||
|
-<mesh/wifi/>
|
||||||
-<mesh/http/>
|
-<mesh/http/>
|
||||||
-<mesh/eth/>
|
-<mesh/eth/>
|
||||||
-<modules/esp32>
|
-<modules/esp32>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
; Common settings for rp2040 Processor based targets
|
; Common settings for rp2040 Processor based targets
|
||||||
[rp2040_base]
|
[rp2040_base]
|
||||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#0c33219f53faa035e188925ea1324f472e8b93d2
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#612de5399d68b359053f1307ed223d400aea975c
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.2.2
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#d2461a14ad5aa920e44508d236c2f459e3befbf8
|
||||||
|
|
||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
@ -12,7 +12,16 @@ build_flags =
|
|||||||
-D__PLAT_RP2040__
|
-D__PLAT_RP2040__
|
||||||
# -D _POSIX_THREADS
|
# -D _POSIX_THREADS
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/nrf52/> -<platform/apollo3> -<platform/stm32wl> -<mesh/eth/>
|
${arduino_base.build_src_filter}
|
||||||
|
-<platform/esp32/>
|
||||||
|
-<nimble/>
|
||||||
|
-<modules/esp32>
|
||||||
|
-<platform/nrf52/>
|
||||||
|
-<platform/stm32wl>
|
||||||
|
-<mesh/eth/>
|
||||||
|
-<mesh/wifi/>
|
||||||
|
-<mesh/http/>
|
||||||
|
-<platform/apollo3>
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
|
@ -13,7 +13,21 @@ build_flags =
|
|||||||
-DVECT_TAB_OFFSET=0x08000000
|
-DVECT_TAB_OFFSET=0x08000000
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/apollo3> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
|
${arduino_base.build_src_filter}
|
||||||
|
-<platform/esp32/>
|
||||||
|
-<nimble/>
|
||||||
|
-<mesh/api/>
|
||||||
|
-<mesh/wifi/>
|
||||||
|
-<mesh/http/>
|
||||||
|
-<modules/esp32>
|
||||||
|
-<mesh/eth/>
|
||||||
|
-<input>
|
||||||
|
-<buzz>
|
||||||
|
-<modules/Telemetry>
|
||||||
|
-<platform/nrf52>
|
||||||
|
-<platform/portduino>
|
||||||
|
-<platform/rp2040>
|
||||||
|
-<platform/apollo3>
|
||||||
|
|
||||||
board_upload.offset_address = 0x08000000
|
board_upload.offset_address = 0x08000000
|
||||||
upload_protocol = stlink
|
upload_protocol = stlink
|
||||||
@ -26,4 +40,4 @@ lib_deps =
|
|||||||
https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1
|
https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
https://github.com/mathertel/OneButton#2.1.0
|
mathertel/OneButton
|
@ -69,7 +69,7 @@ monitor_speed = 115200
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
|
https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
|
||||||
https://github.com/mathertel/OneButton#2.1.0 ; OneButton library for non-blocking button debounce
|
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
|
||||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git#076e8d2c8fb702d9be5b08c55b93ff76f8af7e61
|
https://github.com/meshtastic/TinyGPSPlus.git#076e8d2c8fb702d9be5b08c55b93ff76f8af7e61
|
||||||
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||||
|
@ -435,7 +435,7 @@ void Power::shutdown()
|
|||||||
ledOff(PIN_LED2);
|
ledOff(PIN_LED2);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PIN_LED3
|
#ifdef PIN_LED3
|
||||||
ledOff(PIN_LED2);
|
ledOff(PIN_LED3);
|
||||||
#endif
|
#endif
|
||||||
doDeepSleep(DELAY_FOREVER, false);
|
doDeepSleep(DELAY_FOREVER, false);
|
||||||
#endif
|
#endif
|
||||||
@ -897,4 +897,4 @@ bool Power::axpChipInit()
|
|||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -495,14 +495,14 @@ void GPS::setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime)
|
|||||||
#ifdef PIN_GPS_STANDBY // Specifically the standby pin for L76K and clones
|
#ifdef PIN_GPS_STANDBY // Specifically the standby pin for L76K and clones
|
||||||
if (on) {
|
if (on) {
|
||||||
LOG_INFO("Waking GPS");
|
LOG_INFO("Waking GPS");
|
||||||
digitalWrite(PIN_GPS_STANDBY, 1);
|
|
||||||
pinMode(PIN_GPS_STANDBY, OUTPUT);
|
pinMode(PIN_GPS_STANDBY, OUTPUT);
|
||||||
|
digitalWrite(PIN_GPS_STANDBY, 1);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("GPS entering sleep");
|
LOG_INFO("GPS entering sleep");
|
||||||
// notifyGPSSleep.notifyObservers(NULL);
|
// notifyGPSSleep.notifyObservers(NULL);
|
||||||
digitalWrite(PIN_GPS_STANDBY, 0);
|
|
||||||
pinMode(PIN_GPS_STANDBY, OUTPUT);
|
pinMode(PIN_GPS_STANDBY, OUTPUT);
|
||||||
|
digitalWrite(PIN_GPS_STANDBY, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -920,8 +920,8 @@ GPS *GPS::createGps()
|
|||||||
|
|
||||||
if (_en_gpio != 0) {
|
if (_en_gpio != 0) {
|
||||||
LOG_DEBUG("Setting %d to output.\n", _en_gpio);
|
LOG_DEBUG("Setting %d to output.\n", _en_gpio);
|
||||||
digitalWrite(_en_gpio, !GPS_EN_ACTIVE);
|
|
||||||
pinMode(_en_gpio, OUTPUT);
|
pinMode(_en_gpio, OUTPUT);
|
||||||
|
digitalWrite(_en_gpio, !GPS_EN_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PIN_GPS_PPS
|
#ifdef PIN_GPS_PPS
|
||||||
@ -941,8 +941,8 @@ GPS *GPS::createGps()
|
|||||||
new_gps->setGPSPower(true, false, 0);
|
new_gps->setGPSPower(true, false, 0);
|
||||||
|
|
||||||
#ifdef PIN_GPS_RESET
|
#ifdef PIN_GPS_RESET
|
||||||
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms
|
|
||||||
pinMode(PIN_GPS_RESET, OUTPUT);
|
pinMode(PIN_GPS_RESET, OUTPUT);
|
||||||
|
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms
|
||||||
delay(10);
|
delay(10);
|
||||||
digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE);
|
digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE);
|
||||||
#endif
|
#endif
|
||||||
@ -987,8 +987,8 @@ bool GPS::factoryReset()
|
|||||||
{
|
{
|
||||||
#ifdef PIN_GPS_REINIT
|
#ifdef PIN_GPS_REINIT
|
||||||
// The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
|
// The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
|
||||||
digitalWrite(PIN_GPS_REINIT, 0);
|
|
||||||
pinMode(PIN_GPS_REINIT, OUTPUT);
|
pinMode(PIN_GPS_REINIT, OUTPUT);
|
||||||
|
digitalWrite(PIN_GPS_REINIT, 0);
|
||||||
delay(150); // The L76K datasheet calls for at least 100MS delay
|
delay(150); // The L76K datasheet calls for at least 100MS delay
|
||||||
digitalWrite(PIN_GPS_REINIT, 1);
|
digitalWrite(PIN_GPS_REINIT, 1);
|
||||||
#endif
|
#endif
|
||||||
@ -1268,4 +1268,4 @@ int32_t GPS::disable()
|
|||||||
setAwake(false);
|
setAwake(false);
|
||||||
|
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
|
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
|
||||||
|
|
||||||
#elif defined(HELTEC_WIRELESS_PAPER)
|
#elif defined(HELTEC_WIRELESS_PAPER)
|
||||||
//#define TECHO_DISPLAY_MODEL GxEPD2_213_T5D
|
// #define TECHO_DISPLAY_MODEL GxEPD2_213_T5D
|
||||||
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
|
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -193,14 +193,14 @@ bool EInkDisplay::connect()
|
|||||||
LOG_INFO("Doing EInk init\n");
|
LOG_INFO("Doing EInk init\n");
|
||||||
|
|
||||||
#ifdef PIN_EINK_PWR_ON
|
#ifdef PIN_EINK_PWR_ON
|
||||||
digitalWrite(PIN_EINK_PWR_ON, HIGH); // If we need to assert a pin to power external peripherals
|
|
||||||
pinMode(PIN_EINK_PWR_ON, OUTPUT);
|
pinMode(PIN_EINK_PWR_ON, OUTPUT);
|
||||||
|
digitalWrite(PIN_EINK_PWR_ON, HIGH); // If we need to assert a pin to power external peripherals
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PIN_EINK_EN
|
#ifdef PIN_EINK_EN
|
||||||
// backlight power, HIGH is backlight on, LOW is off
|
// backlight power, HIGH is backlight on, LOW is off
|
||||||
digitalWrite(PIN_EINK_EN, LOW);
|
|
||||||
pinMode(PIN_EINK_EN, OUTPUT);
|
pinMode(PIN_EINK_EN, OUTPUT);
|
||||||
|
digitalWrite(PIN_EINK_EN, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TTGO_T_ECHO)
|
#if defined(TTGO_T_ECHO)
|
||||||
|
@ -45,7 +45,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#include "modules/esp32/StoreForwardModule.h"
|
#include "modules/esp32/StoreForwardModule.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1618,12 +1618,19 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
|||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
|
||||||
} else if (WiFi.status() == WL_IDLE_STATUS) {
|
} else if (WiFi.status() == WL_IDLE_STATUS) {
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Idle ... Reconnecting");
|
||||||
} else {
|
}
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
else {
|
||||||
// Codes:
|
// Codes:
|
||||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
|
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
|
||||||
WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(getWifiDisconnectReason())));
|
WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(getWifiDisconnectReason())));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
else {
|
||||||
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Unkown status: " + String(WiFi.status()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
||||||
|
|
||||||
|
@ -478,8 +478,8 @@ bool TFTDisplay::connect()
|
|||||||
LOG_INFO("Doing TFT init\n");
|
LOG_INFO("Doing TFT init\n");
|
||||||
|
|
||||||
#ifdef TFT_BL
|
#ifdef TFT_BL
|
||||||
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
|
||||||
pinMode(TFT_BL, OUTPUT);
|
pinMode(TFT_BL, OUTPUT);
|
||||||
|
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
||||||
// pinMode(PIN_3V3_EN, OUTPUT);
|
// pinMode(PIN_3V3_EN, OUTPUT);
|
||||||
// digitalWrite(PIN_3V3_EN, HIGH);
|
// digitalWrite(PIN_3V3_EN, HIGH);
|
||||||
LOG_INFO("Power to TFT Backlight\n");
|
LOG_INFO("Power to TFT Backlight\n");
|
||||||
@ -487,11 +487,11 @@ bool TFTDisplay::connect()
|
|||||||
|
|
||||||
#ifdef ST7735_BACKLIGHT_EN_V03
|
#ifdef ST7735_BACKLIGHT_EN_V03
|
||||||
if (heltec_version == 3) {
|
if (heltec_version == 3) {
|
||||||
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
|
|
||||||
pinMode(ST7735_BACKLIGHT_EN_V03, OUTPUT);
|
pinMode(ST7735_BACKLIGHT_EN_V03, OUTPUT);
|
||||||
|
digitalWrite(ST7735_BACKLIGHT_EN_V03, TFT_BACKLIGHT_ON);
|
||||||
} else {
|
} else {
|
||||||
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
|
|
||||||
pinMode(ST7735_BACKLIGHT_EN_V05, OUTPUT);
|
pinMode(ST7735_BACKLIGHT_EN_V05, OUTPUT);
|
||||||
|
digitalWrite(ST7735_BACKLIGHT_EN_V05, TFT_BACKLIGHT_ON);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -515,4 +515,4 @@ bool TFTDisplay::connect()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
11
src/main.cpp
11
src/main.cpp
@ -32,9 +32,6 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
// #include <driver/rtc_io.h>
|
// #include <driver/rtc_io.h>
|
||||||
|
|
||||||
#include "mesh/eth/ethClient.h"
|
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#include "mesh/http/WebServer.h"
|
#include "mesh/http/WebServer.h"
|
||||||
#include "nimble/NimbleBluetooth.h"
|
#include "nimble/NimbleBluetooth.h"
|
||||||
@ -48,10 +45,12 @@ NRF52Bluetooth *nrf52Bluetooth;
|
|||||||
|
|
||||||
#if HAS_WIFI
|
#if HAS_WIFI
|
||||||
#include "mesh/api/WiFiServerAPI.h"
|
#include "mesh/api/WiFiServerAPI.h"
|
||||||
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_ETHERNET
|
#if HAS_ETHERNET
|
||||||
#include "mesh/api/ethServerAPI.h"
|
#include "mesh/api/ethServerAPI.h"
|
||||||
|
#include "mesh/eth/ethClient.h"
|
||||||
#endif
|
#endif
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
|
|
||||||
@ -838,11 +837,15 @@ void setup()
|
|||||||
|
|
||||||
#ifndef ARCH_PORTDUINO
|
#ifndef ARCH_PORTDUINO
|
||||||
// Initialize Wifi
|
// Initialize Wifi
|
||||||
|
#if HAS_WIFI
|
||||||
initWifi();
|
initWifi();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_ETHERNET
|
||||||
// Initialize Ethernet
|
// Initialize Ethernet
|
||||||
initEthernet();
|
initEthernet();
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
// Start web server thread.
|
// Start web server thread.
|
||||||
@ -941,4 +944,4 @@ void loop()
|
|||||||
mainDelay.delay(delayMsec);
|
mainDelay.delay(delayMsec);
|
||||||
}
|
}
|
||||||
// if (didWake) LOG_DEBUG("wake!\n");
|
// if (didWake) LOG_DEBUG("wake!\n");
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,9 @@ meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
|
|||||||
|
|
||||||
position.time = getValidTime(RTCQualityFromNet);
|
position.time = getValidTime(RTCQualityFromNet);
|
||||||
|
|
||||||
updateBatteryLevel(powerStatus->getBatteryChargePercent());
|
if (powerStatus->getHasBattery() == 1) {
|
||||||
|
updateBatteryLevel(powerStatus->getBatteryChargePercent());
|
||||||
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include <pb_encode.h>
|
#include <pb_encode.h>
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#include "modules/esp32/StoreForwardModule.h"
|
#include "modules/esp32/StoreForwardModule.h"
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
#include <nvs_flash.h>
|
#include <nvs_flash.h>
|
||||||
@ -248,6 +248,12 @@ void NodeDB::installDefaultModuleConfig()
|
|||||||
#ifdef T_WATCH_S3
|
#ifdef T_WATCH_S3
|
||||||
// Don't worry about the other settings, we'll use the DRV2056 behavior for notifications
|
// Don't worry about the other settings, we'll use the DRV2056 behavior for notifications
|
||||||
moduleConfig.external_notification.enabled = true;
|
moduleConfig.external_notification.enabled = true;
|
||||||
|
#endif
|
||||||
|
#ifdef NANO_G2_ULTRA
|
||||||
|
moduleConfig.external_notification.enabled = true;
|
||||||
|
moduleConfig.external_notification.alert_message = true;
|
||||||
|
moduleConfig.external_notification.output_ms = 100;
|
||||||
|
moduleConfig.external_notification.active = true;
|
||||||
#endif
|
#endif
|
||||||
moduleConfig.has_canned_message = true;
|
moduleConfig.has_canned_message = true;
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ SX126xInterface<T>::SX126xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs
|
|||||||
template <typename T> bool SX126xInterface<T>::init()
|
template <typename T> bool SX126xInterface<T>::init()
|
||||||
{
|
{
|
||||||
#ifdef SX126X_POWER_EN
|
#ifdef SX126X_POWER_EN
|
||||||
digitalWrite(SX126X_POWER_EN, HIGH);
|
|
||||||
pinMode(SX126X_POWER_EN, OUTPUT);
|
pinMode(SX126X_POWER_EN, OUTPUT);
|
||||||
|
digitalWrite(SX126X_POWER_EN, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE
|
// FIXME: correct logic to default to not using TCXO if no voltage is specified for SX126X_DIO3_TCXO_VOLTAGE
|
||||||
|
@ -22,8 +22,8 @@ SX128xInterface<T>::SX128xInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs
|
|||||||
template <typename T> bool SX128xInterface<T>::init()
|
template <typename T> bool SX128xInterface<T>::init()
|
||||||
{
|
{
|
||||||
#ifdef SX128X_POWER_EN
|
#ifdef SX128X_POWER_EN
|
||||||
digitalWrite(SX128X_POWER_EN, HIGH);
|
|
||||||
pinMode(SX128X_POWER_EN, OUTPUT);
|
pinMode(SX128X_POWER_EN, OUTPUT);
|
||||||
|
digitalWrite(SX128X_POWER_EN, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RF95_FAN_EN
|
#ifdef RF95_FAN_EN
|
||||||
@ -32,12 +32,12 @@ template <typename T> bool SX128xInterface<T>::init()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode
|
#if defined(SX128X_RXEN) && (SX128X_RXEN != RADIOLIB_NC) // set not rx or tx mode
|
||||||
digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
|
|
||||||
pinMode(SX128X_RXEN, OUTPUT);
|
pinMode(SX128X_RXEN, OUTPUT);
|
||||||
|
digitalWrite(SX128X_RXEN, LOW); // Set low before becoming an output
|
||||||
#endif
|
#endif
|
||||||
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC)
|
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC)
|
||||||
digitalWrite(SX128X_TXEN, LOW);
|
|
||||||
pinMode(SX128X_TXEN, OUTPUT);
|
pinMode(SX128X_TXEN, OUTPUT);
|
||||||
|
digitalWrite(SX128X_TXEN, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RadioLibInterface::init();
|
RadioLibInterface::init();
|
||||||
|
@ -22,4 +22,4 @@ class WiFiServerPort : public APIServerPort<WiFiServerAPI, WiFiServer>
|
|||||||
explicit WiFiServerPort(int port);
|
explicit WiFiServerPort(int port);
|
||||||
};
|
};
|
||||||
|
|
||||||
void initApiServer(int port = 4403);
|
void initApiServer(int port = 4403);
|
@ -5,7 +5,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/http/ContentHelper.h"
|
#include "mesh/http/ContentHelper.h"
|
||||||
#include "mesh/http/WebServer.h"
|
#include "mesh/http/WebServer.h"
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#include "mqtt/JSON.h"
|
#include "mqtt/JSON.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer);
|
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer);
|
||||||
|
|
||||||
// Declare some handler functions for the various URLs on the server
|
// Declare some handler functions for the various URLs on the server
|
||||||
@ -34,4 +33,4 @@ class HttpAPI : public PhoneAPI
|
|||||||
protected:
|
protected:
|
||||||
/// Check the current underlying physical link to see if the client is currently connected
|
/// Check the current underlying physical link to see if the client is currently connected
|
||||||
virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
|
virtual bool checkIsConnected() override { return true; } // FIXME, be smarter about this
|
||||||
};
|
};
|
@ -1,6 +1,6 @@
|
|||||||
#include "mesh/http/ContentHelper.h"
|
#include "mesh/http/ContentHelper.h"
|
||||||
//#include <Arduino.h>
|
// #include <Arduino.h>
|
||||||
//#include "main.h"
|
// #include "main.h"
|
||||||
|
|
||||||
void replaceAll(std::string &str, const std::string &from, const std::string &to)
|
void replaceAll(std::string &str, const std::string &from, const std::string &to)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "graphics/Screen.h"
|
#include "graphics/Screen.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include <HTTPBodyParser.hpp>
|
#include <HTTPBodyParser.hpp>
|
||||||
#include <HTTPMultipartBodyParser.hpp>
|
#include <HTTPMultipartBodyParser.hpp>
|
||||||
@ -210,4 +210,4 @@ void initWebServer()
|
|||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Web Servers Failed! ;-( \n");
|
LOG_ERROR("Web Servers Failed! ;-( \n");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,17 +1,22 @@
|
|||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "concurrency/Periodic.h"
|
#include "concurrency/Periodic.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/api/WiFiServerAPI.h"
|
#include "mesh/api/WiFiServerAPI.h"
|
||||||
#include "mesh/http/WebServer.h"
|
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include <ESPmDNS.h>
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <WiFiUdp.h>
|
#include <WiFiUdp.h>
|
||||||
|
#ifndef ARCH_RP2040
|
||||||
|
#include "mesh/http/WebServer.h"
|
||||||
|
#include <ESPmDNS.h>
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
static void WiFiEvent(WiFiEvent_t event);
|
||||||
|
#else
|
||||||
|
#include <ESP8266mDNS.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DISABLE_NTP
|
#ifndef DISABLE_NTP
|
||||||
#include <NTPClient.h>
|
#include <NTPClient.h>
|
||||||
@ -19,8 +24,6 @@
|
|||||||
|
|
||||||
using namespace concurrency;
|
using namespace concurrency;
|
||||||
|
|
||||||
static void WiFiEvent(WiFiEvent_t event);
|
|
||||||
|
|
||||||
// NTP
|
// NTP
|
||||||
WiFiUDP ntpUDP;
|
WiFiUDP ntpUDP;
|
||||||
|
|
||||||
@ -44,78 +47,6 @@ Syslog syslog(syslogClient);
|
|||||||
|
|
||||||
Periodic *wifiReconnect;
|
Periodic *wifiReconnect;
|
||||||
|
|
||||||
static int32_t reconnectWiFi()
|
|
||||||
{
|
|
||||||
const char *wifiName = config.network.wifi_ssid;
|
|
||||||
const char *wifiPsw = config.network.wifi_psk;
|
|
||||||
|
|
||||||
if (config.network.wifi_enabled && needReconnect) {
|
|
||||||
|
|
||||||
if (!*wifiPsw) // Treat empty password as no password
|
|
||||||
wifiPsw = NULL;
|
|
||||||
|
|
||||||
needReconnect = false;
|
|
||||||
|
|
||||||
// Make sure we clear old connection credentials
|
|
||||||
WiFi.disconnect(false, true);
|
|
||||||
LOG_INFO("Reconnecting to WiFi access point %s\n", wifiName);
|
|
||||||
|
|
||||||
delay(5000);
|
|
||||||
|
|
||||||
if (!WiFi.isConnected()) {
|
|
||||||
WiFi.begin(wifiName, wifiPsw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_NTP
|
|
||||||
if (WiFi.isConnected() && (((millis() - lastrun_ntp) > 43200000) || (lastrun_ntp == 0))) { // every 12 hours
|
|
||||||
LOG_DEBUG("Updating NTP time from %s\n", config.network.ntp_server);
|
|
||||||
if (timeClient.update()) {
|
|
||||||
LOG_DEBUG("NTP Request Success - Setting RTCQualityNTP if needed\n");
|
|
||||||
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = timeClient.getEpochTime();
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
perhapsSetRTC(RTCQualityNTP, &tv);
|
|
||||||
lastrun_ntp = millis();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
LOG_DEBUG("NTP Update failed\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (config.network.wifi_enabled && !WiFi.isConnected()) {
|
|
||||||
return 1000; // check once per second
|
|
||||||
} else {
|
|
||||||
return 300000; // every 5 minutes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isWifiAvailable()
|
|
||||||
{
|
|
||||||
|
|
||||||
if (config.network.wifi_enabled && (config.network.wifi_ssid[0])) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable WiFi
|
|
||||||
void deinitWifi()
|
|
||||||
{
|
|
||||||
LOG_INFO("WiFi deinit\n");
|
|
||||||
|
|
||||||
if (isWifiAvailable()) {
|
|
||||||
WiFi.disconnect(true);
|
|
||||||
WiFi.mode(WIFI_MODE_NULL);
|
|
||||||
LOG_INFO("WiFi Turned Off\n");
|
|
||||||
// WiFi.printDiag(Serial);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onNetworkConnected()
|
static void onNetworkConnected()
|
||||||
{
|
{
|
||||||
if (!APStartupComplete) {
|
if (!APStartupComplete) {
|
||||||
@ -158,7 +89,9 @@ static void onNetworkConnected()
|
|||||||
syslog.enable();
|
syslog.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ARCH_RP2040
|
||||||
initWebServer();
|
initWebServer();
|
||||||
|
#endif
|
||||||
initApiServer();
|
initApiServer();
|
||||||
|
|
||||||
APStartupComplete = true;
|
APStartupComplete = true;
|
||||||
@ -169,6 +102,89 @@ static void onNetworkConnected()
|
|||||||
mqtt->reconnect();
|
mqtt->reconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t reconnectWiFi()
|
||||||
|
{
|
||||||
|
const char *wifiName = config.network.wifi_ssid;
|
||||||
|
const char *wifiPsw = config.network.wifi_psk;
|
||||||
|
|
||||||
|
if (config.network.wifi_enabled && needReconnect) {
|
||||||
|
|
||||||
|
if (!*wifiPsw) // Treat empty password as no password
|
||||||
|
wifiPsw = NULL;
|
||||||
|
|
||||||
|
needReconnect = false;
|
||||||
|
|
||||||
|
// Make sure we clear old connection credentials
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
WiFi.disconnect(false, true);
|
||||||
|
#else
|
||||||
|
WiFi.disconnect(false);
|
||||||
|
#endif
|
||||||
|
LOG_INFO("Reconnecting to WiFi access point %s\n", wifiName);
|
||||||
|
|
||||||
|
delay(5000);
|
||||||
|
|
||||||
|
if (!WiFi.isConnected()) {
|
||||||
|
WiFi.begin(wifiName, wifiPsw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef DISABLE_NTP
|
||||||
|
if (WiFi.isConnected() && (((millis() - lastrun_ntp) > 43200000) || (lastrun_ntp == 0))) { // every 12 hours
|
||||||
|
LOG_DEBUG("Updating NTP time from %s\n", config.network.ntp_server);
|
||||||
|
if (timeClient.update()) {
|
||||||
|
LOG_DEBUG("NTP Request Success - Setting RTCQualityNTP if needed\n");
|
||||||
|
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = timeClient.getEpochTime();
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
perhapsSetRTC(RTCQualityNTP, &tv);
|
||||||
|
lastrun_ntp = millis();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("NTP Update failed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (config.network.wifi_enabled && !WiFi.isConnected()) {
|
||||||
|
return 1000; // check once per second
|
||||||
|
} else {
|
||||||
|
#ifdef ARCH_RP2040
|
||||||
|
onNetworkConnected(); // will only do anything once
|
||||||
|
#endif
|
||||||
|
return 300000; // every 5 minutes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWifiAvailable()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (config.network.wifi_enabled && (config.network.wifi_ssid[0])) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable WiFi
|
||||||
|
void deinitWifi()
|
||||||
|
{
|
||||||
|
LOG_INFO("WiFi deinit\n");
|
||||||
|
|
||||||
|
if (isWifiAvailable()) {
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
WiFi.disconnect(true, false);
|
||||||
|
#else
|
||||||
|
WiFi.disconnect(true);
|
||||||
|
#endif
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
|
LOG_INFO("WiFi Turned Off\n");
|
||||||
|
// WiFi.printDiag(Serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Startup WiFi
|
// Startup WiFi
|
||||||
bool initWifi()
|
bool initWifi()
|
||||||
{
|
{
|
||||||
@ -177,10 +193,10 @@ bool initWifi()
|
|||||||
const char *wifiName = config.network.wifi_ssid;
|
const char *wifiName = config.network.wifi_ssid;
|
||||||
const char *wifiPsw = config.network.wifi_psk;
|
const char *wifiPsw = config.network.wifi_psk;
|
||||||
|
|
||||||
createSSLCert();
|
#ifndef ARCH_RP2040
|
||||||
|
createSSLCert(); // For WebServer
|
||||||
esp_wifi_set_storage(WIFI_STORAGE_RAM); // Disable flash storage for WiFi credentials
|
esp_wifi_set_storage(WIFI_STORAGE_RAM); // Disable flash storage for WiFi credentials
|
||||||
|
#endif
|
||||||
if (!*wifiPsw) // Treat empty password as no password
|
if (!*wifiPsw) // Treat empty password as no password
|
||||||
wifiPsw = NULL;
|
wifiPsw = NULL;
|
||||||
|
|
||||||
@ -189,17 +205,17 @@ bool initWifi()
|
|||||||
getMacAddr(dmac);
|
getMacAddr(dmac);
|
||||||
snprintf(ourHost, sizeof(ourHost), "Meshtastic-%02x%02x", dmac[4], dmac[5]);
|
snprintf(ourHost, sizeof(ourHost), "Meshtastic-%02x%02x", dmac[4], dmac[5]);
|
||||||
|
|
||||||
WiFi.mode(WIFI_MODE_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.setHostname(ourHost);
|
WiFi.setHostname(ourHost);
|
||||||
WiFi.onEvent(WiFiEvent);
|
|
||||||
WiFi.setAutoReconnect(true);
|
|
||||||
WiFi.setSleep(false);
|
|
||||||
if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC &&
|
if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC &&
|
||||||
config.network.ipv4_config.ip != 0) {
|
config.network.ipv4_config.ip != 0) {
|
||||||
WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.gateway, config.network.ipv4_config.subnet,
|
WiFi.config(config.network.ipv4_config.ip, config.network.ipv4_config.gateway, config.network.ipv4_config.subnet,
|
||||||
config.network.ipv4_config.dns,
|
config.network.ipv4_config.dns);
|
||||||
config.network.ipv4_config.dns); // Wifi wants two DNS servers... set both to the same value
|
|
||||||
}
|
}
|
||||||
|
#ifndef ARCH_RP2040
|
||||||
|
WiFi.onEvent(WiFiEvent);
|
||||||
|
WiFi.setAutoReconnect(true);
|
||||||
|
WiFi.setSleep(false);
|
||||||
|
|
||||||
// This is needed to improve performance.
|
// This is needed to improve performance.
|
||||||
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
|
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
|
||||||
@ -218,7 +234,7 @@ bool initWifi()
|
|||||||
wifiDisconnectReason = info.wifi_sta_disconnected.reason;
|
wifiDisconnectReason = info.wifi_sta_disconnected.reason;
|
||||||
},
|
},
|
||||||
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
|
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
|
||||||
|
#endif
|
||||||
LOG_DEBUG("JOINING WIFI soon: ssid=%s\n", wifiName);
|
LOG_DEBUG("JOINING WIFI soon: ssid=%s\n", wifiName);
|
||||||
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
|
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
|
||||||
}
|
}
|
||||||
@ -229,6 +245,7 @@ bool initWifi()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ARCH_RP2040
|
||||||
// Called by the Espressif SDK to
|
// Called by the Espressif SDK to
|
||||||
static void WiFiEvent(WiFiEvent_t event)
|
static void WiFiEvent(WiFiEvent_t event)
|
||||||
{
|
{
|
||||||
@ -369,8 +386,9 @@ static void WiFiEvent(WiFiEvent_t event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t getWifiDisconnectReason()
|
uint8_t getWifiDisconnectReason()
|
||||||
{
|
{
|
||||||
return wifiDisconnectReason;
|
return wifiDisconnectReason;
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#if defined(HAS_WIFI) && !defined(ARCH_PORTDUINO)
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -19,4 +19,4 @@ void deinitWifi();
|
|||||||
|
|
||||||
bool isWifiAvailable();
|
bool isWifiAvailable();
|
||||||
|
|
||||||
uint8_t getWifiDisconnectReason();
|
uint8_t getWifiDisconnectReason();
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ProtobufModule.h"
|
#include "ProtobufModule.h"
|
||||||
#ifdef ARCH_ESP32
|
#if HAS_WIFI
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,4 +50,4 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>
|
|||||||
void reboot(int32_t seconds);
|
void reboot(int32_t seconds);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern AdminModule *adminModule;
|
extern AdminModule *adminModule;
|
@ -7,9 +7,9 @@
|
|||||||
#include "mesh/Router.h"
|
#include "mesh/Router.h"
|
||||||
#include "mesh/generated/meshtastic/mqtt.pb.h"
|
#include "mesh/generated/meshtastic/mqtt.pb.h"
|
||||||
#include "mesh/generated/meshtastic/telemetry.pb.h"
|
#include "mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#if HAS_WIFI
|
#if HAS_WIFI
|
||||||
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#endif
|
#endif
|
||||||
#include "mqtt/JSON.h"
|
#include "mqtt/JSON.h"
|
||||||
|
@ -186,7 +186,7 @@ void NimbleBluetooth::setupService()
|
|||||||
// Setup the battery service
|
// Setup the battery service
|
||||||
NimBLEService *batteryService = bleServer->createService(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
NimBLEService *batteryService = bleServer->createService(NimBLEUUID((uint16_t)0x180f)); // 0x180F is the Battery Service
|
||||||
BatteryCharacteristic = batteryService->createCharacteristic( // 0x2A19 is the Battery Level characteristic)
|
BatteryCharacteristic = batteryService->createCharacteristic( // 0x2A19 is the Battery Level characteristic)
|
||||||
(uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
|
(uint16_t)0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY, 1);
|
||||||
|
|
||||||
NimBLE2904 *batteryLevelDescriptor = (NimBLE2904 *)BatteryCharacteristic->createDescriptor((uint16_t)0x2904);
|
NimBLE2904 *batteryLevelDescriptor = (NimBLE2904 *)BatteryCharacteristic->createDescriptor((uint16_t)0x2904);
|
||||||
batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8);
|
batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8);
|
||||||
@ -208,8 +208,10 @@ void NimbleBluetooth::startAdvertising()
|
|||||||
/// Given a level between 0-100, update the BLE attribute
|
/// Given a level between 0-100, update the BLE attribute
|
||||||
void updateBatteryLevel(uint8_t level)
|
void updateBatteryLevel(uint8_t level)
|
||||||
{
|
{
|
||||||
BatteryCharacteristic->setValue(&level, 1);
|
if ((config.bluetooth.enabled == true) && bleServer && nimbleBluetooth->isConnected()) {
|
||||||
BatteryCharacteristic->notify();
|
BatteryCharacteristic->setValue(&level, 1);
|
||||||
|
BatteryCharacteristic->notify();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NimbleBluetooth::clearBonds()
|
void NimbleBluetooth::clearBonds()
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 hathach for Adafruit Industries
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "InternalFileSystem.h"
|
|
||||||
#include <EEPROM.h>
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// LFS Disk IO
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
static inline uint32_t lba2addr(uint32_t block)
|
|
||||||
{
|
|
||||||
return ((uint32_t)LFS_FLASH_ADDR) + block * LFS_BLOCK_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _internal_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
|
|
||||||
{
|
|
||||||
(void)c;
|
|
||||||
|
|
||||||
uint32_t addr = lba2addr(block) + off;
|
|
||||||
uint8_t prom;
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
prom = EEPROM.read(addr + i);
|
|
||||||
memcpy((char *)buffer + i, &prom, 1);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Program a region in a block. The block must have previously
|
|
||||||
// been erased. Negative error codes are propogated to the user.
|
|
||||||
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
|
||||||
static int _internal_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
|
|
||||||
{
|
|
||||||
(void)c;
|
|
||||||
|
|
||||||
uint32_t addr = lba2addr(block) + off;
|
|
||||||
uint8_t prom;
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
memcpy(&prom, (char *)buffer + i, 1);
|
|
||||||
EEPROM.update(addr + i, prom);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase a block. A block must be erased before being programmed.
|
|
||||||
// The state of an erased block is undefined. Negative error codes
|
|
||||||
// are propogated to the user.
|
|
||||||
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
|
||||||
static int _internal_flash_erase(const struct lfs_config *c, lfs_block_t block)
|
|
||||||
{
|
|
||||||
(void)c;
|
|
||||||
|
|
||||||
uint32_t addr = lba2addr(block);
|
|
||||||
|
|
||||||
// implement as write 0xff to whole block address
|
|
||||||
for (int i = 0; i < LFS_BLOCK_SIZE; i++) {
|
|
||||||
EEPROM.update(addr, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync the state of the underlying block device. Negative error codes
|
|
||||||
// are propogated to the user.
|
|
||||||
static int _internal_flash_sync(const struct lfs_config *c)
|
|
||||||
{
|
|
||||||
// we don't use a ram cache, this is a noop
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct lfs_config _InternalFSConfig = {.context = NULL,
|
|
||||||
|
|
||||||
.read = _internal_flash_read,
|
|
||||||
.prog = _internal_flash_prog,
|
|
||||||
.erase = _internal_flash_erase,
|
|
||||||
.sync = _internal_flash_sync,
|
|
||||||
|
|
||||||
.read_size = LFS_CACHE_SIZE,
|
|
||||||
.prog_size = LFS_CACHE_SIZE,
|
|
||||||
.block_size = LFS_BLOCK_SIZE,
|
|
||||||
.block_count = LFS_FLASH_TOTAL_SIZE / LFS_BLOCK_SIZE,
|
|
||||||
.block_cycles =
|
|
||||||
500, // protection against wear leveling (suggested values between 100-1000)
|
|
||||||
.cache_size = LFS_CACHE_SIZE,
|
|
||||||
.lookahead_size = LFS_CACHE_SIZE,
|
|
||||||
|
|
||||||
.read_buffer = lfs_read_buffer,
|
|
||||||
.prog_buffer = lfs_prog_buffer,
|
|
||||||
.lookahead_buffer = lfs_lookahead_buffer};
|
|
||||||
|
|
||||||
InternalFileSystem InternalFS;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
InternalFileSystem::InternalFileSystem(void) : LittleFS(&_InternalFSConfig) {}
|
|
||||||
|
|
||||||
bool InternalFileSystem::begin(void)
|
|
||||||
{
|
|
||||||
// failed to mount, erase all sector then format and mount again
|
|
||||||
if (!LittleFS::begin()) {
|
|
||||||
// Erase all sectors of internal flash region for Filesystem.
|
|
||||||
// implement as write 0xff to whole block address
|
|
||||||
for (uint32_t addr = LFS_FLASH_ADDR; addr < (LFS_FLASH_ADDR + LFS_FLASH_TOTAL_SIZE); addr++) {
|
|
||||||
EEPROM.update(addr, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
// lfs format
|
|
||||||
this->format();
|
|
||||||
|
|
||||||
// mount again if still failed, give up
|
|
||||||
if (!LittleFS::begin())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 hathach for Adafruit Industries
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INTERNALFILESYSTEM_H_
|
|
||||||
#define INTERNALFILESYSTEM_H_
|
|
||||||
|
|
||||||
#include "LittleFS.h"
|
|
||||||
|
|
||||||
// The EEPROM Library assumes our usable flash area starts at logical 0
|
|
||||||
#define LFS_FLASH_ADDR 0
|
|
||||||
|
|
||||||
// use the built in EEPROM emulation. Total Size is 2Kbyte
|
|
||||||
#define LFS_BLOCK_SIZE 128 // min. block size is 128 to fit CTZ pointers
|
|
||||||
#define LFS_CACHE_SIZE 16
|
|
||||||
|
|
||||||
#define LFS_FLASH_TOTAL_SIZE FLASH_PAGE_SIZE
|
|
||||||
|
|
||||||
static uint8_t lfs_read_buffer[LFS_CACHE_SIZE] = {0};
|
|
||||||
static uint8_t lfs_prog_buffer[LFS_CACHE_SIZE] = {0};
|
|
||||||
static uint8_t lfs_lookahead_buffer[LFS_CACHE_SIZE] = {0};
|
|
||||||
|
|
||||||
class InternalFileSystem : public LittleFS
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InternalFileSystem(void);
|
|
||||||
|
|
||||||
// overwrite to also perform low level format (sector erase of whole flash region)
|
|
||||||
bool begin(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern InternalFileSystem InternalFS;
|
|
||||||
|
|
||||||
#endif /* INTERNALFILESYSTEM_H_ */
|
|
@ -1,258 +0,0 @@
|
|||||||
#include <Arduino.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "LittleFS.h"
|
|
||||||
|
|
||||||
using namespace LittleFS_Namespace;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Implementation
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
LittleFS::LittleFS(void) : LittleFS(NULL) {}
|
|
||||||
|
|
||||||
LittleFS::LittleFS(struct lfs_config *cfg)
|
|
||||||
{
|
|
||||||
memset(&_lfs, 0, sizeof(_lfs));
|
|
||||||
_lfs_cfg = cfg;
|
|
||||||
_mounted = false;
|
|
||||||
_mutex = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
LittleFS::~LittleFS() {}
|
|
||||||
|
|
||||||
// Initialize and mount the file system
|
|
||||||
// Return true if mounted successfully else probably corrupted.
|
|
||||||
// User should format the disk and try again
|
|
||||||
bool LittleFS::begin(struct lfs_config *cfg)
|
|
||||||
{
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
bool ret;
|
|
||||||
// not a loop, just an quick way to short-circuit on error
|
|
||||||
do {
|
|
||||||
if (_mounted) {
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (cfg) {
|
|
||||||
_lfs_cfg = cfg;
|
|
||||||
}
|
|
||||||
if (nullptr == _lfs_cfg) {
|
|
||||||
ret = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// actually attempt to mount, and log error if one occurs
|
|
||||||
int err = lfs_mount(&_lfs, _lfs_cfg);
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
_mounted = (err == LFS_ERR_OK);
|
|
||||||
ret = _mounted;
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tear down and unmount file system
|
|
||||||
void LittleFS::end(void)
|
|
||||||
{
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
if (_mounted) {
|
|
||||||
_mounted = false;
|
|
||||||
int err = lfs_unmount(&_lfs);
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
(void)err;
|
|
||||||
}
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LittleFS::format(void)
|
|
||||||
{
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
int err = LFS_ERR_OK;
|
|
||||||
bool attemptMount = _mounted;
|
|
||||||
// not a loop, just an quick way to short-circuit on error
|
|
||||||
do {
|
|
||||||
// if already mounted: umount first -> format -> remount
|
|
||||||
if (_mounted) {
|
|
||||||
_mounted = false;
|
|
||||||
err = lfs_unmount(&_lfs);
|
|
||||||
if (LFS_ERR_OK != err) {
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = lfs_format(&_lfs, _lfs_cfg);
|
|
||||||
if (LFS_ERR_OK != err) {
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attemptMount) {
|
|
||||||
err = lfs_mount(&_lfs, _lfs_cfg);
|
|
||||||
if (LFS_ERR_OK != err) {
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_mounted = true;
|
|
||||||
}
|
|
||||||
// success!
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
return LFS_ERR_OK == err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open a file or folder
|
|
||||||
LittleFS_Namespace::File LittleFS::open(char const *filepath, uint8_t mode)
|
|
||||||
{
|
|
||||||
// No lock is required here ... the File() object will synchronize with the mutex provided
|
|
||||||
return LittleFS_Namespace::File(filepath, mode, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if file or folder exists
|
|
||||||
bool LittleFS::exists(char const *filepath)
|
|
||||||
{
|
|
||||||
struct lfs_info info;
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
bool ret = (0 == lfs_stat(&_lfs, filepath, &info));
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a directory, create intermediate parent if needed
|
|
||||||
bool LittleFS::mkdir(char const *filepath)
|
|
||||||
{
|
|
||||||
bool ret = true;
|
|
||||||
const char *slash = filepath;
|
|
||||||
if (slash[0] == '/')
|
|
||||||
slash++; // skip root '/'
|
|
||||||
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
// make intermediate parent directory(ies)
|
|
||||||
while (NULL != (slash = strchr(slash, '/'))) {
|
|
||||||
char parent[slash - filepath + 1] = {0};
|
|
||||||
memcpy(parent, filepath, slash - filepath);
|
|
||||||
|
|
||||||
int rc = lfs_mkdir(&_lfs, parent);
|
|
||||||
if (rc != LFS_ERR_OK && rc != LFS_ERR_EXIST) {
|
|
||||||
PRINT_LFS_ERR(rc);
|
|
||||||
ret = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
slash++;
|
|
||||||
}
|
|
||||||
// make the final requested directory
|
|
||||||
if (ret) {
|
|
||||||
int rc = lfs_mkdir(&_lfs, filepath);
|
|
||||||
if (rc != LFS_ERR_OK && rc != LFS_ERR_EXIST) {
|
|
||||||
PRINT_LFS_ERR(rc);
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a file
|
|
||||||
bool LittleFS::remove(char const *filepath)
|
|
||||||
{
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
int err = lfs_remove(&_lfs, filepath);
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
return LFS_ERR_OK == err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rename a file
|
|
||||||
bool LittleFS::rename(char const *oldfilepath, char const *newfilepath)
|
|
||||||
{
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
int err = lfs_rename(&_lfs, oldfilepath, newfilepath);
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
return LFS_ERR_OK == err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a folder
|
|
||||||
bool LittleFS::rmdir(char const *filepath)
|
|
||||||
{
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
int err = lfs_remove(&_lfs, filepath);
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
return LFS_ERR_OK == err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a folder recursively
|
|
||||||
bool LittleFS::rmdir_r(char const *filepath)
|
|
||||||
{
|
|
||||||
/* adafruit: lfs is modified to remove non-empty folder,
|
|
||||||
According to below issue, comment these 2 line won't corrupt filesystem
|
|
||||||
at least when using LFS v1. If moving to LFS v2, see tracked issue
|
|
||||||
to see if issues (such as the orphans in threaded linked list) are resolved.
|
|
||||||
https://github.com/ARMmbed/littlefs/issues/43
|
|
||||||
*/
|
|
||||||
_lockFS();
|
|
||||||
|
|
||||||
int err = lfs_remove(&_lfs, filepath);
|
|
||||||
PRINT_LFS_ERR(err);
|
|
||||||
|
|
||||||
_unlockFS();
|
|
||||||
return LFS_ERR_OK == err;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------- Debug -------------//
|
|
||||||
#if CFG_DEBUG
|
|
||||||
|
|
||||||
const char *dbg_strerr_lfs(int32_t err)
|
|
||||||
{
|
|
||||||
switch (err) {
|
|
||||||
case LFS_ERR_OK:
|
|
||||||
return "LFS_ERR_OK";
|
|
||||||
case LFS_ERR_IO:
|
|
||||||
return "LFS_ERR_IO";
|
|
||||||
case LFS_ERR_CORRUPT:
|
|
||||||
return "LFS_ERR_CORRUPT";
|
|
||||||
case LFS_ERR_NOENT:
|
|
||||||
return "LFS_ERR_NOENT";
|
|
||||||
case LFS_ERR_EXIST:
|
|
||||||
return "LFS_ERR_EXIST";
|
|
||||||
case LFS_ERR_NOTDIR:
|
|
||||||
return "LFS_ERR_NOTDIR";
|
|
||||||
case LFS_ERR_ISDIR:
|
|
||||||
return "LFS_ERR_ISDIR";
|
|
||||||
case LFS_ERR_NOTEMPTY:
|
|
||||||
return "LFS_ERR_NOTEMPTY";
|
|
||||||
case LFS_ERR_BADF:
|
|
||||||
return "LFS_ERR_BADF";
|
|
||||||
case LFS_ERR_INVAL:
|
|
||||||
return "LFS_ERR_INVAL";
|
|
||||||
case LFS_ERR_NOSPC:
|
|
||||||
return "LFS_ERR_NOSPC";
|
|
||||||
case LFS_ERR_NOMEM:
|
|
||||||
return "LFS_ERR_NOMEM";
|
|
||||||
|
|
||||||
default:
|
|
||||||
static char errcode[10];
|
|
||||||
sprintf(errcode, "%ld", err);
|
|
||||||
return errcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,85 +0,0 @@
|
|||||||
|
|
||||||
#ifndef LITTLEFS_H_
|
|
||||||
#define LITTLEFS_H_
|
|
||||||
|
|
||||||
#include <Stream.h>
|
|
||||||
|
|
||||||
#include "lfs.h"
|
|
||||||
|
|
||||||
#include "LittleFS_File.h"
|
|
||||||
|
|
||||||
#include "FreeRTOS.h" // tied to FreeRTOS for serialization
|
|
||||||
#include "semphr.h"
|
|
||||||
|
|
||||||
class LittleFS
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LittleFS(void);
|
|
||||||
explicit LittleFS(struct lfs_config *cfg);
|
|
||||||
virtual ~LittleFS();
|
|
||||||
|
|
||||||
bool begin(struct lfs_config *cfg = NULL);
|
|
||||||
void end(void);
|
|
||||||
|
|
||||||
// Open the specified file/directory with the supplied mode (e.g. read or
|
|
||||||
// write, etc). Returns a File object for interacting with the file.
|
|
||||||
// Note that currently only one file can be open at a time.
|
|
||||||
LittleFS_Namespace::File open(char const *filename, uint8_t mode = LittleFS_Namespace::FILE_O_READ);
|
|
||||||
|
|
||||||
// Methods to determine if the requested file path exists.
|
|
||||||
bool exists(char const *filepath);
|
|
||||||
|
|
||||||
// Create the requested directory hierarchy--if intermediate directories
|
|
||||||
// do not exist they will be created.
|
|
||||||
bool mkdir(char const *filepath);
|
|
||||||
|
|
||||||
// Delete the file.
|
|
||||||
bool remove(char const *filepath);
|
|
||||||
|
|
||||||
// Rename the file.
|
|
||||||
bool rename(char const *oldfilepath, char const *newfilepath);
|
|
||||||
|
|
||||||
// Delete a folder (must be empty)
|
|
||||||
bool rmdir(char const *filepath);
|
|
||||||
|
|
||||||
// Delete a folder (recursively)
|
|
||||||
bool rmdir_r(char const *filepath);
|
|
||||||
|
|
||||||
// format file system
|
|
||||||
bool format(void);
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
|
||||||
/* INTERNAL USAGE ONLY
|
|
||||||
* Although declare as public, it is meant to be invoked by internal
|
|
||||||
* code. User should not call these directly
|
|
||||||
*------------------------------------------------------------------*/
|
|
||||||
lfs_t *_getFS(void) { return &_lfs; }
|
|
||||||
void _lockFS(void) { xSemaphoreTake(_mutex, portMAX_DELAY); }
|
|
||||||
void _unlockFS(void) { xSemaphoreGive(_mutex); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool _mounted;
|
|
||||||
struct lfs_config *_lfs_cfg;
|
|
||||||
lfs_t _lfs;
|
|
||||||
SemaphoreHandle_t _mutex;
|
|
||||||
|
|
||||||
private:
|
|
||||||
StaticSemaphore_t _MutexStorageSpace;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !CFG_DEBUG
|
|
||||||
#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, NULL)
|
|
||||||
#define PRINT_LFS_ERR(_err)
|
|
||||||
#else
|
|
||||||
#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, dbg_strerr_lfs)
|
|
||||||
#define PRINT_LFS_ERR(_err) \
|
|
||||||
do { \
|
|
||||||
if (_err) { \
|
|
||||||
VERIFY_MESS((long int)_err, dbg_strerr_lfs); \
|
|
||||||
} \
|
|
||||||
} while (0) // LFS_ERR are of type int, VERIFY_MESS expects long_int
|
|
||||||
|
|
||||||
const char *dbg_strerr_lfs(int32_t err);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* LITTLEFS_H_ */
|
|
@ -1,362 +0,0 @@
|
|||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
#include "LittleFS.h"
|
|
||||||
|
|
||||||
#include <lfs.h>
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
using namespace LittleFS_Namespace;
|
|
||||||
|
|
||||||
File::File(LittleFS &fs)
|
|
||||||
{
|
|
||||||
_fs = &fs;
|
|
||||||
_is_dir = false;
|
|
||||||
_name[0] = 0;
|
|
||||||
_dir_path = NULL;
|
|
||||||
|
|
||||||
_dir = NULL;
|
|
||||||
_file = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
File::File(char const *filename, uint8_t mode, LittleFS &fs) : File(fs)
|
|
||||||
{
|
|
||||||
// public constructor calls public API open(), which will obtain the mutex
|
|
||||||
this->open(filename, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::_open_file(char const *filepath, uint8_t mode)
|
|
||||||
{
|
|
||||||
int flags = (mode == FILE_O_READ) ? LFS_O_RDONLY : (mode == FILE_O_WRITE) ? (LFS_O_RDWR | LFS_O_CREAT) : 0;
|
|
||||||
|
|
||||||
if (flags) {
|
|
||||||
_file = (lfs_file_t *)malloc(sizeof(lfs_file_t));
|
|
||||||
if (!_file)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int rc = lfs_file_open(_fs->_getFS(), _file, filepath, flags);
|
|
||||||
|
|
||||||
if (rc) {
|
|
||||||
// failed to open
|
|
||||||
PRINT_LFS_ERR(rc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// move to end of file
|
|
||||||
if (mode == FILE_O_WRITE)
|
|
||||||
lfs_file_seek(_fs->_getFS(), _file, 0, LFS_SEEK_END);
|
|
||||||
|
|
||||||
_is_dir = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::_open_dir(char const *filepath)
|
|
||||||
{
|
|
||||||
_dir = (lfs_dir_t *)malloc(sizeof(lfs_dir_t));
|
|
||||||
if (!_dir)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int rc = lfs_dir_open(_fs->_getFS(), _dir, filepath);
|
|
||||||
|
|
||||||
if (rc) {
|
|
||||||
// failed to open
|
|
||||||
PRINT_LFS_ERR(rc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_is_dir = true;
|
|
||||||
|
|
||||||
_dir_path = (char *)malloc(strlen(filepath) + 1);
|
|
||||||
strcpy(_dir_path, filepath);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::open(char const *filepath, uint8_t mode)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
ret = this->_open(filepath, mode);
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::_open(char const *filepath, uint8_t mode)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
// close if currently opened
|
|
||||||
if (this->isOpen())
|
|
||||||
_close();
|
|
||||||
|
|
||||||
struct lfs_info info;
|
|
||||||
int rc = lfs_stat(_fs->_getFS(), filepath, &info);
|
|
||||||
|
|
||||||
if (LFS_ERR_OK == rc) {
|
|
||||||
// file existed, open file or directory accordingly
|
|
||||||
ret = (info.type == LFS_TYPE_REG) ? _open_file(filepath, mode) : _open_dir(filepath);
|
|
||||||
} else if (LFS_ERR_NOENT == rc) {
|
|
||||||
// file not existed, only proceed with FILE_O_WRITE mode
|
|
||||||
if (mode == FILE_O_WRITE)
|
|
||||||
ret = _open_file(filepath, mode);
|
|
||||||
} else {
|
|
||||||
PRINT_LFS_ERR(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// save bare file name
|
|
||||||
if (ret) {
|
|
||||||
char const *splash = strrchr(filepath, '/');
|
|
||||||
strncpy(_name, splash ? (splash + 1) : filepath, LFS_NAME_MAX);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t File::write(uint8_t ch)
|
|
||||||
{
|
|
||||||
return write(&ch, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t File::write(uint8_t const *buf, size_t size)
|
|
||||||
{
|
|
||||||
lfs_ssize_t wrcount = 0;
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
wrcount = lfs_file_write(_fs->_getFS(), _file, buf, size);
|
|
||||||
if (wrcount < 0) {
|
|
||||||
wrcount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return wrcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int File::read(void)
|
|
||||||
{
|
|
||||||
// this thin wrapper relies on called function to synchronize
|
|
||||||
int ret = -1;
|
|
||||||
uint8_t ch;
|
|
||||||
if (read(&ch, 1) > 0) {
|
|
||||||
ret = static_cast<int>(ch);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int File::read(void *buf, uint16_t nbyte)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
ret = lfs_file_read(_fs->_getFS(), _file, buf, nbyte);
|
|
||||||
}
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int File::peek(void)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
|
|
||||||
uint8_t ch = 0;
|
|
||||||
if (lfs_file_read(_fs->_getFS(), _file, &ch, 1) > 0) {
|
|
||||||
ret = static_cast<int>(ch);
|
|
||||||
}
|
|
||||||
(void)lfs_file_seek(_fs->_getFS(), _file, pos, LFS_SEEK_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int File::available(void)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
uint32_t size = lfs_file_size(_fs->_getFS(), _file);
|
|
||||||
uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
|
|
||||||
ret = size - pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::seek(uint32_t pos)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
ret = lfs_file_seek(_fs->_getFS(), _file, pos, LFS_SEEK_SET) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t File::position(void)
|
|
||||||
{
|
|
||||||
uint32_t ret = 0;
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
ret = lfs_file_tell(_fs->_getFS(), _file);
|
|
||||||
}
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t File::size(void)
|
|
||||||
{
|
|
||||||
uint32_t ret = 0;
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
ret = lfs_file_size(_fs->_getFS(), _file);
|
|
||||||
}
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::truncate(uint32_t pos)
|
|
||||||
{
|
|
||||||
int32_t ret = LFS_ERR_ISDIR;
|
|
||||||
_fs->_lockFS();
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
ret = lfs_file_truncate(_fs->_getFS(), _file, pos);
|
|
||||||
}
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return (ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::truncate(void)
|
|
||||||
{
|
|
||||||
int32_t ret = LFS_ERR_ISDIR;
|
|
||||||
_fs->_lockFS();
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
uint32_t pos = lfs_file_tell(_fs->_getFS(), _file);
|
|
||||||
ret = lfs_file_truncate(_fs->_getFS(), _file, pos);
|
|
||||||
}
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return (ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void File::flush(void)
|
|
||||||
{
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
if (!this->_is_dir) {
|
|
||||||
lfs_file_sync(_fs->_getFS(), _file);
|
|
||||||
}
|
|
||||||
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void File::close(void)
|
|
||||||
{
|
|
||||||
_fs->_lockFS();
|
|
||||||
this->_close();
|
|
||||||
_fs->_unlockFS();
|
|
||||||
}
|
|
||||||
|
|
||||||
void File::_close(void)
|
|
||||||
{
|
|
||||||
if (this->isOpen()) {
|
|
||||||
if (this->_is_dir) {
|
|
||||||
lfs_dir_close(_fs->_getFS(), _dir);
|
|
||||||
free(_dir);
|
|
||||||
_dir = NULL;
|
|
||||||
|
|
||||||
if (this->_dir_path)
|
|
||||||
free(_dir_path);
|
|
||||||
_dir_path = NULL;
|
|
||||||
} else {
|
|
||||||
lfs_file_close(this->_fs->_getFS(), _file);
|
|
||||||
free(_file);
|
|
||||||
_file = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File::operator bool(void)
|
|
||||||
{
|
|
||||||
return isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::isOpen(void)
|
|
||||||
{
|
|
||||||
return (_file != NULL) || (_dir != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// WARNING -- although marked as `const`, the values pointed
|
|
||||||
// to may change. For example, if the same File
|
|
||||||
// object has `open()` called with a different
|
|
||||||
// file or directory name, this same pointer will
|
|
||||||
// suddenly (unexpectedly?) have different values.
|
|
||||||
char const *File::name(void)
|
|
||||||
{
|
|
||||||
return this->_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File::isDirectory(void)
|
|
||||||
{
|
|
||||||
return this->_is_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
File File::openNextFile(uint8_t mode)
|
|
||||||
{
|
|
||||||
_fs->_lockFS();
|
|
||||||
|
|
||||||
File ret(*_fs);
|
|
||||||
if (this->_is_dir) {
|
|
||||||
struct lfs_info info;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
// lfs_dir_read returns 0 when reaching end of directory, 1 if found an entry
|
|
||||||
// Skip the "." and ".." entries ...
|
|
||||||
do {
|
|
||||||
rc = lfs_dir_read(_fs->_getFS(), _dir, &info);
|
|
||||||
} while (rc == 1 && (!strcmp(".", info.name) || !strcmp("..", info.name)));
|
|
||||||
|
|
||||||
if (rc == 1) {
|
|
||||||
// string cat name with current folder
|
|
||||||
char filepath[strlen(_dir_path) + 1 + strlen(info.name) + 1]; // potential for significant stack usage
|
|
||||||
strcpy(filepath, _dir_path);
|
|
||||||
if (!(_dir_path[0] == '/' && _dir_path[1] == 0))
|
|
||||||
strcat(filepath, "/"); // only add '/' if cwd is not root
|
|
||||||
strcat(filepath, info.name);
|
|
||||||
|
|
||||||
(void)ret._open(filepath, mode); // return value is ignored ... caller is expected to check isOpened()
|
|
||||||
} else if (rc < 0) {
|
|
||||||
PRINT_LFS_ERR(rc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_fs->_unlockFS();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void File::rewindDirectory(void)
|
|
||||||
{
|
|
||||||
_fs->_lockFS();
|
|
||||||
if (this->_is_dir) {
|
|
||||||
lfs_dir_rewind(_fs->_getFS(), _dir);
|
|
||||||
}
|
|
||||||
_fs->_unlockFS();
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
#ifndef LITTLEFS_FILE_H_
|
|
||||||
#define LITTLEFS_FILE_H_
|
|
||||||
|
|
||||||
// Forward declaration
|
|
||||||
class LittleFS;
|
|
||||||
|
|
||||||
namespace LittleFS_Namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
// avoid conflict with other FileSystem FILE_READ/FILE_WRITE
|
|
||||||
enum {
|
|
||||||
FILE_O_READ = 0,
|
|
||||||
FILE_O_WRITE = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
class File : public Stream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit File(LittleFS &fs);
|
|
||||||
File(char const *filename, uint8_t mode, LittleFS &fs);
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool open(char const *filename, uint8_t mode);
|
|
||||||
|
|
||||||
//------------- Stream API -------------//
|
|
||||||
virtual size_t write(uint8_t ch);
|
|
||||||
virtual size_t write(uint8_t const *buf, size_t size);
|
|
||||||
size_t write(const char *str)
|
|
||||||
{
|
|
||||||
if (str == NULL)
|
|
||||||
return 0;
|
|
||||||
return write((const uint8_t *)str, strlen(str));
|
|
||||||
}
|
|
||||||
size_t write(const char *buffer, size_t size) { return write((const uint8_t *)buffer, size); }
|
|
||||||
|
|
||||||
virtual int read(void);
|
|
||||||
int read(void *buf, uint16_t nbyte);
|
|
||||||
|
|
||||||
virtual int peek(void);
|
|
||||||
virtual int available(void);
|
|
||||||
virtual void flush(void);
|
|
||||||
|
|
||||||
bool seek(uint32_t pos);
|
|
||||||
uint32_t position(void);
|
|
||||||
uint32_t size(void);
|
|
||||||
|
|
||||||
bool truncate(uint32_t pos);
|
|
||||||
bool truncate(void);
|
|
||||||
|
|
||||||
void close(void);
|
|
||||||
|
|
||||||
operator bool(void);
|
|
||||||
|
|
||||||
bool isOpen(void);
|
|
||||||
char const *name(void);
|
|
||||||
|
|
||||||
bool isDirectory(void);
|
|
||||||
File openNextFile(uint8_t mode = FILE_O_READ);
|
|
||||||
void rewindDirectory(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
LittleFS *_fs;
|
|
||||||
|
|
||||||
bool _is_dir;
|
|
||||||
|
|
||||||
union {
|
|
||||||
lfs_file_t *_file;
|
|
||||||
lfs_dir_t *_dir;
|
|
||||||
};
|
|
||||||
|
|
||||||
char *_dir_path;
|
|
||||||
char _name[LFS_NAME_MAX + 1];
|
|
||||||
|
|
||||||
bool _open(char const *filepath, uint8_t mode);
|
|
||||||
bool _open_file(char const *filepath, uint8_t mode);
|
|
||||||
bool _open_dir(char const *filepath);
|
|
||||||
void _close(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LittleFS_Namespace
|
|
||||||
|
|
||||||
#endif /* LITTLEFS_FILE_H_ */
|
|
@ -7,7 +7,7 @@
|
|||||||
#include "nimble/NimbleBluetooth.h"
|
#include "nimble/NimbleBluetooth.h"
|
||||||
#endif
|
#endif
|
||||||
#include "BleOta.h"
|
#include "BleOta.h"
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
|
|
||||||
#include "meshUtils.h"
|
#include "meshUtils.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#include "esp32/pm.h"
|
#include "esp32/pm.h"
|
||||||
#include "esp_pm.h"
|
#include "esp_pm.h"
|
||||||
#include "mesh/http/WiFiAPClient.h"
|
#include "mesh/wifi/WiFiAPClient.h"
|
||||||
#include "rom/rtc.h"
|
#include "rom/rtc.h"
|
||||||
#include <driver/rtc_io.h>
|
#include <driver/rtc_io.h>
|
||||||
#include <driver/uart.h>
|
#include <driver/uart.h>
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
// Radio
|
// Radio
|
||||||
#define USE_SX1262 // E22-900M30S uses SX1262
|
#define USE_SX1262 // E22-900M30S uses SX1262
|
||||||
|
#define USE_SX1268 // E22-400M30S uses SX1268
|
||||||
#define SX126X_MAX_POWER \
|
#define SX126X_MAX_POWER \
|
||||||
22 // Outputting 22dBm from SX1262 results in ~30dBm E22-900M30S output (module only uses last stage of the YP2233W PA)
|
22 // Outputting 22dBm from SX1262 results in ~30dBm E22-900M30S output (module only uses last stage of the YP2233W PA)
|
||||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // E22 series TCXO reference voltage is 1.8V
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // E22 series TCXO reference voltage is 1.8V
|
||||||
|
@ -8,8 +8,10 @@ upload_protocol = picotool
|
|||||||
build_flags = ${rp2040_base.build_flags}
|
build_flags = ${rp2040_base.build_flags}
|
||||||
-DRPI_PICO
|
-DRPI_PICO
|
||||||
-Ivariants/rpipicow
|
-Ivariants/rpipicow
|
||||||
-DDEBUG_RP2040_PORT=Serial
|
|
||||||
-DHW_SPI1_DEVICE
|
-DHW_SPI1_DEVICE
|
||||||
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
|
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
|
||||||
|
-fexceptions # for exception handling in MQTT
|
||||||
|
build_src_filter = ${rp2040_base.build_src_filter} +<mesh/wifi/>
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${rp2040_base.lib_deps}
|
${rp2040_base.lib_deps}
|
||||||
|
${networking_base.lib_deps}
|
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
#define ARDUINO_ARCH_AVR
|
#define ARDUINO_ARCH_AVR
|
||||||
|
|
||||||
|
#ifndef HAS_WIFI
|
||||||
|
#define HAS_WIFI 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#define USE_SH1106 1
|
#define USE_SH1106 1
|
||||||
|
|
||||||
// default I2C pins:
|
// default I2C pins:
|
||||||
@ -46,4 +50,4 @@
|
|||||||
#define SX126X_RESET LORA_RESET
|
#define SX126X_RESET LORA_RESET
|
||||||
#define SX126X_DIO2_AS_RF_SWITCH
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||||
#endif
|
#endif
|
@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 2
|
minor = 2
|
||||||
build = 14
|
build = 16
|
||||||
|
Loading…
Reference in New Issue
Block a user