From f311239c9c358e4d2d14854a70f191df98d9cdfe Mon Sep 17 00:00:00 2001 From: Frank Kunz Date: Thu, 27 Mar 2025 00:48:05 +0100 Subject: [PATCH] Add new AP hardware support OpenEPaperLink_ESP32-PoE-ISO_AP (#431) * Fix filesystem mutex handling This fixes the re-initialization of the filesystem mutex when the dyn storage module is reinitialized. Using xSemaphoreCreateMutex would cause a memory leak when the begin function is called multiple times and a semaphore leakage could be caused by the re-initialization of the global fsMutex variable while the semaphore is taken. The fsMutex should not be taken while the logLine function is called as this would cause a nested take of the fsMutex, which causes a deadlock. Signed-off-by: Frank Kunz * Fix hard coded littlefs in json upload Signed-off-by: Frank Kunz * Add new AP hardware support OpenEPaperLink_ESP32-PoE-ISO_AP This is based on Olimex ESP32-PoE-ISO https://www.olimex.com/Products/IoT/ESP32/ESP32-POE-ISO/open-source-hardware It has a SD Card slot that is used to store all filesystem data on SD. Use the prepare_sdcard.sh script to copy all needed data to an empty SD card that is formatted with FAT filesystem. The AP firmware will format the SD if an unformatted or from formatted card is used. This can be used to intially prepare an empty SD card for usage. For tag communication a ESP32-C6-WROOM-1(U) is used with the following connection scheme: ESP32-PoE-ISO | ESP32-C6-WROOM-1 ---------------+------------------ GPIO5 | EN GPIO13 | GPIO9 GPIO36 | GPIO3 GPIO4 | GPIO2 GPIO33 | GPIO24 GPIO32 | GPIO25 | GPIO8 pullup 5.1k Signed-off-by: Frank Kunz * Avoid error message log print when parsers.json is missing Signed-off-by: Frank Kunz * Workaround for IEEE802.15.4 modem stuck issue The ESP32-C6 esp-idf based modem firmware can run into a case where it does not receive data anymore from the tags. This can be detected when it starts to print "receive buffer full, drop the current frame" and does not recover from that. In such a case a modem reset is triggered. Signed-off-by: Frank Kunz * Add OpenEPaperLink_ESP32-PoE-ISO_AP to release build Signed-off-by: Frank Kunz * Add OpenEPaperLink_ESP32-PoE-ISO_AP to condidional build Signed-off-by: Frank Kunz * Add Ethernet support The ethernet support allows to make the network/internet connection via LAN cable instead of WiFi. LAN is preferred, if a LAN cable is connected and a valid IP configuration via DHCP can be obtained, WiFi is switched off. If the LAN cable is disconnected, a fall back to WiFi is done. Use those defines in platform.ini for PHY settings: ETHERNET_PHY_POWER: IO pin where the PHY can be switched of/on, can be -1 if not used. ETHERNET_CLK_MODE: PHY clock mode, see eth_clock_mode_t in ETH.h ETHERNET_PHY_MDC: PHY MDC pin ETHERNET_PHY_MDIO: PHY MDIO pin ETHERNET_PHY_TYPE: PHY type, see eth_phy_type_t in ETH.h Limitations: - only DHCP is supported, no static IP configuration for LAN so far. - If GPIO0 is used for one of the ETHERNET_CLK_MODE modes, then GPIO0 cannot be used to clear the WiFi configuration. Signed-off-by: Frank Kunz --------- Signed-off-by: Frank Kunz Co-authored-by: Frank Kunz --- .github/workflows/conditional-build-test.yml | 8 +- .github/workflows/release.yml | 41 ++++- .../sdkconfig.defaults | 2 +- ESP32_AP-Flasher/esp32_sdcard_only.csv | 7 + ESP32_AP-Flasher/include/storage.h | 6 + ESP32_AP-Flasher/include/wifimanager.h | 6 +- ESP32_AP-Flasher/platformio.ini | 151 +++++++++++------ ESP32_AP-Flasher/prepare_sdcard.sh | 23 +++ ESP32_AP-Flasher/src/leds.cpp | 10 +- ESP32_AP-Flasher/src/main.cpp | 9 + ESP32_AP-Flasher/src/ota.cpp | 14 +- ESP32_AP-Flasher/src/serialap.cpp | 43 ++++- ESP32_AP-Flasher/src/storage.cpp | 80 ++++++++- ESP32_AP-Flasher/src/system.cpp | 2 +- ESP32_AP-Flasher/src/tag_db.cpp | 2 + ESP32_AP-Flasher/src/tagdata.cpp | 5 +- ESP32_AP-Flasher/src/udp.cpp | 9 +- ESP32_AP-Flasher/src/web.cpp | 10 +- ESP32_AP-Flasher/src/wifimanager.cpp | 160 +++++++++++++++--- 19 files changed, 479 insertions(+), 109 deletions(-) create mode 100644 ESP32_AP-Flasher/esp32_sdcard_only.csv create mode 100755 ESP32_AP-Flasher/prepare_sdcard.sh diff --git a/.github/workflows/conditional-build-test.yml b/.github/workflows/conditional-build-test.yml index 15d9b209..43f6f1c0 100644 --- a/.github/workflows/conditional-build-test.yml +++ b/.github/workflows/conditional-build-test.yml @@ -70,16 +70,22 @@ jobs: #- OpenEPaperLink_AP_and_Flasher - ESP32_S3_16_8_YELLOW_AP - OpenEPaperLink_Mini_AP_v4 + - OpenEPaperLink_ESP32-PoE-ISO_AP runs-on: ubuntu-22.04 steps: - name: Checkout Code uses: actions/checkout@v4 - uses: ./.github/actions/setup-pio - - name: Build ${{ matrix.environment }} + - name: Build ${{ matrix.environment }} binary run: | cd ESP32_AP-Flasher pio run --environment ${{ matrix.environment }} + - name: Build ${{ matrix.environment }} filesystem + if: ${{ matrix.environment != 'OpenEPaperLink_ESP32-PoE-ISO_AP' }} + run: | + cd ESP32_AP-Flasher pio run --target buildfs --environment ${{ matrix.environment }} + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d50e258..c80d109f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,14 +26,14 @@ jobs: - uses: actions/setup-python@v4 with: python-version: '3.9' - -# - name: Commit zipped files + +# - name: Commit zipped files # run: | # git config --global user.name 'Bot' # git config --global user.email "bot@openepaperlink.de" # git commit -am "Zipped web files" # git push origin HEAD:master - + - name: Install PlatformIO Core run: pip install --upgrade platformio @@ -80,10 +80,10 @@ jobs: cp /home/runner/work/OpenEPaperLink/OpenEPaperLink//binaries/ESP32-H2/firmware_H2.json espbinaries # - name: Zip web files -# run: | +# run: | # cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_AP-Flasher # python gzip_wwwfiles.py - + - name: Build firmware for OpenEPaperLink_Mini_AP if: ${{ env.INCLUDE_MINI_AP == 'true' }} run: | @@ -102,7 +102,7 @@ jobs: cd /home/runner/work/OpenEPaperLink/OpenEPaperLink cp OpenEPaperLink_Mini_AP/firmware.bin espbinaries/OpenEPaperLink_Mini_AP.bin cp OpenEPaperLink_Mini_AP/merged-firmware.bin espbinaries/OpenEPaperLink_Mini_AP_full.bin - + - name: Build firmware for OpenEPaperLink_Nano_AP if: ${{ env.INCLUDE_Nano_AP == 'true' }} run: | @@ -124,7 +124,7 @@ jobs: # - name: move files for big APs # run: | # cp -a binaries/ESP32-C6/. ESP32_AP-Flasher/data/ - + - name: Build firmware for OpenEPaperLink_AP_and_Flasher run: | cd ESP32_AP-Flasher @@ -213,7 +213,7 @@ jobs: cd /home/runner/work/OpenEPaperLink/OpenEPaperLink cp OpenEPaperLink_Nano_TLSR/firmware.bin espbinaries/OpenEPaperLink_Nano_TLSR.bin cp OpenEPaperLink_Nano_TLSR/merged-firmware.bin espbinaries/OpenEPaperLink_Nano_TLSR_full.bin - + - name: Build firmware for OpenEPaperLink_PoE_AP run: | cd ESP32_AP-Flasher @@ -267,6 +267,29 @@ jobs: cd /home/runner/work/OpenEPaperLink/OpenEPaperLink cp BLE_ONLY_AP/firmware.bin espbinaries/BLE_ONLY_AP.bin cp BLE_ONLY_AP/merged-firmware.bin espbinaries/BLE_ONLY_AP_full.bin + + - name: Build firmware for OpenEPaperLink_ESP32-PoE-ISO_AP + run: | + cd ESP32_AP-Flasher + export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA" + pio run --environment OpenEPaperLink_ESP32-PoE-ISO_AP + mv data data.bak + mkdir data + pio run --target buildfs --environment OpenEPaperLink_ESP32-PoE-ISO_AP + rmdir data + mv data.bak data + mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_ESP32-PoE-ISO_AP + cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_ESP32-PoE-ISO_AP/boot_app0.bin + cp .pio/build/OpenEPaperLink_ESP32-PoE-ISO_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_ESP32-PoE-ISO_AP/firmware.bin + cp .pio/build/OpenEPaperLink_ESP32-PoE-ISO_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_ESP32-PoE-ISO_AP/bootloader.bin + cp .pio/build/OpenEPaperLink_ESP32-PoE-ISO_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_ESP32-PoE-ISO_AP/partitions.bin + cp .pio/build/OpenEPaperLink_ESP32-PoE-ISO_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_ESP32-PoE-ISO_AP/littlefs.bin + cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_ESP32-PoE-ISO_AP + esptool.py --chip esp32 merge_bin -o merged-firmware.bin --flash_mode qio --flash_freq 80m --flash_size 4MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xD000 boot_app0.bin 0x10000 firmware.bin 0x3D0000 littlefs.bin + cd /home/runner/work/OpenEPaperLink/OpenEPaperLink + cp OpenEPaperLink_ESP32-PoE-ISO_AP/firmware.bin espbinaries/OpenEPaperLink_ESP32-PoE-ISO_AP.bin + cp OpenEPaperLink_ESP32-PoE-ISO_AP/merged-firmware.bin espbinaries/BLE_ONLY_AP_full.bin + - name: generate release json file run: | mkdir jsonfiles @@ -280,7 +303,7 @@ jobs: tag: ${{ github.ref }} file_glob: true overwrite: true - + # this is down here intentionally to be able to modify the binary folder before adding it to the Tag_Flasher later (ota binaries can be removed) - name: Build firmware for Tag_Flasher diff --git a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/sdkconfig.defaults b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/sdkconfig.defaults index 07ac3251..624e7d9f 100644 --- a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/sdkconfig.defaults +++ b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/sdkconfig.defaults @@ -7,4 +7,4 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE=y CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_OEPL_SUBGIG_SUPPORT=y - +CONFIG_IEEE802154_RX_BUFFER_SIZE=100 diff --git a/ESP32_AP-Flasher/esp32_sdcard_only.csv b/ESP32_AP-Flasher/esp32_sdcard_only.csv new file mode 100644 index 00000000..0990a3b4 --- /dev/null +++ b/ESP32_AP-Flasher/esp32_sdcard_only.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1E0000, +app1, app, ota_1, 0x1F0000,0x1E0000, +spiffs, data, spiffs, 0x3D0000,0x20000, +coredump, data, coredump,0x3F0000,0x10000, diff --git a/ESP32_AP-Flasher/include/storage.h b/ESP32_AP-Flasher/include/storage.h index 5ed6e977..f8026d36 100644 --- a/ESP32_AP-Flasher/include/storage.h +++ b/ESP32_AP-Flasher/include/storage.h @@ -4,6 +4,8 @@ #include "FS.h" #ifdef HAS_SDCARD +#ifndef SD_CARD_SDMMC + #ifndef SD_CARD_SS #error SD_CARD_SS UNDEFINED #endif @@ -18,6 +20,8 @@ #ifndef SD_CARD_MOSI #define SD_CARD_MOSI 23 +#endif + #endif #endif @@ -36,7 +40,9 @@ class DynStorage { extern SemaphoreHandle_t fsMutex; extern DynStorage Storage; extern fs::FS *contentFS; +#ifndef SD_CARD_ONLY extern void copyFile(File in, File out); +#endif #endif diff --git a/ESP32_AP-Flasher/include/wifimanager.h b/ESP32_AP-Flasher/include/wifimanager.h index 35e47536..17cf091e 100644 --- a/ESP32_AP-Flasher/include/wifimanager.h +++ b/ESP32_AP-Flasher/include/wifimanager.h @@ -16,7 +16,8 @@ enum WifiStatus { WAIT_CONNECTING, CONNECTED, WAIT_RECONNECT, - AP + AP, + ETHERNET }; class WifiManager { @@ -41,6 +42,7 @@ class WifiManager { bool waitForConnection(); void pollSerial(); static void terminalLog(String text); + static String buildHostname(esp_mac_type_t mac_type); public: WifiManager(); @@ -53,6 +55,8 @@ class WifiManager { void startManagementServer(); void poll(); static void WiFiEvent(WiFiEvent_t event); + void initEth(); + IPAddress localIP(); }; #endif diff --git a/ESP32_AP-Flasher/platformio.ini b/ESP32_AP-Flasher/platformio.ini index f261b1e5..36494404 100644 --- a/ESP32_AP-Flasher/platformio.ini +++ b/ESP32_AP-Flasher/platformio.ini @@ -5,7 +5,7 @@ platform = platformio/espressif32@^6.10.0 ;platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip framework = arduino -lib_deps = +lib_deps = ESP32Async/AsyncTCP ESP32Async/ESPAsyncWebServer @@ -42,7 +42,7 @@ build_unflags = -std=gnu++11 -D ARDUINO_USB_MODE=1 -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_EXT_FLASHER @@ -61,7 +61,7 @@ build_flags = -D FLASHER_AP_MOSI=7 -D FLASHER_AP_MISO=6 -D FLASHER_AP_RESET=15 - -D FLASHER_AP_POWER={0} + -D FLASHER_AP_POWER={0} -D FLASHER_AP_TXD=16 -D FLASHER_AP_RXD=18 -D FLASHER_AP_TEST=17 @@ -85,7 +85,7 @@ build_flags = -D FLASHER_ALT_TEST=13 -D FLASHER_LED=21 -D FLASHER_RGB_LED=48 -build_src_filter = +build_src_filter = +<*>- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -106,7 +106,7 @@ build_unflags = -D ILI9341_DRIVER lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT @@ -151,7 +151,7 @@ build_flags = -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -D C6_OTA_FLASHING -D HAS_SUBGHZ -build_src_filter = +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -173,7 +173,7 @@ build_unflags = ;-D ILI9341_DRIVER lib_deps = ${env.lib_deps} lib_extra_dirs = lib2/Arduino_GFX-1.3.7 -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT @@ -193,7 +193,7 @@ build_flags = -D FLASHER_AP_RESET=34 -D FLASHER_AP_POWER={-1} -D FLASHER_AP_TEST=-1 -; NB: FLASHER_DEBUG_TXD and FLASHER_DEBUG_RXD use the same pins as +; NB: FLASHER_DEBUG_TXD and FLASHER_DEBUG_RXD use the same pins as ; FLASHER_AP_TXD and FLASHER_AP_RXD but the naming convention is different -D FLASHER_DEBUG_SHARED -D FLASHER_DEBUG_PORT=1 @@ -215,7 +215,7 @@ build_flags = -D HAS_H2 -D C6_OTA_FLASHING -D HAS_SUBGHZ -build_src_filter = +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_qspi ;Enable external PSRAM @@ -237,7 +237,7 @@ build_unflags = lib_deps = ${env.lib_deps} lib_extra_dirs = lib2/Arduino_GFX-1.3.7 lib2/gt911-touch -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT @@ -279,7 +279,7 @@ build_flags = -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=200 -D C6_OTA_FLASHING -D HAS_SUBGHZ -build_src_filter = +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi ;Enable external PSRAM @@ -298,7 +298,7 @@ build_unflags = -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_BLE_WRITER @@ -328,7 +328,7 @@ build_flags = -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -D C6_OTA_FLASHING -build_src_filter = +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -347,7 +347,7 @@ build_unflags = -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_BLE_WRITER @@ -377,7 +377,7 @@ build_flags = -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -D C6_OTA_FLASHING -D HAS_SUBGHZ -build_src_filter = +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -396,7 +396,7 @@ build_unflags = -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_BLE_WRITER @@ -428,7 +428,7 @@ build_flags = -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -D C6_OTA_FLASHING -D HAS_SUBGHZ -build_src_filter = +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -449,7 +449,7 @@ build_unflags = -D ILI9341_DRIVER lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT @@ -498,7 +498,7 @@ build_flags = -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=200 -D C6_OTA_FLASHING -D HAS_SUBGHZ -build_src_filter = +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -518,7 +518,7 @@ build_unflags = -D ILI9341_DRIVER lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT @@ -567,7 +567,7 @@ build_flags = -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=200 -D C6_OTA_FLASHING -D HAS_SUBGHZ -build_src_filter = +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -587,7 +587,7 @@ build_unflags = -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D CORE_DEBUG_LEVEL=0 @@ -614,7 +614,7 @@ build_flags = -D HAS_RGB_LED -D FLASHER_RGB_LED=48 -D BLE_ONLY -build_src_filter = +build_src_filter = +<*>---- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -634,7 +634,7 @@ build_unflags = -std=gnu++11 lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D OPENEPAPERLINK_POE_AP_PCB @@ -660,7 +660,7 @@ build_flags = -D SD_CARD_MISO=36 -D SD_CARD_MOSI=14 -D SD_CARD_SS=12 -build_src_filter = +build_src_filter = +<*>---- board_build.flash_mode=qio board_upload.maximum_size = 16777216 @@ -680,7 +680,7 @@ build_unflags = -D ILI9341_DRIVER lib_deps = ${env.lib_deps} -build_flags = +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT @@ -750,7 +750,7 @@ build_flags = -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=200 -D C6_OTA_FLASHING -D HAS_SUBGHZ -build_src_filter = +build_src_filter = +<*> board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -826,6 +826,61 @@ board_upload.maximum_size = 16777216 board_upload.maximum_ram_size = 327680 board_upload.flash_size = 16MB +; ---------------------------------------------------------------------------------------- +; !!! this configuration expects an ESP32-S3 4MB Flash 8MB RAM +; Hardware is https://www.olimex.com/Products/IoT/ESP32/ESP32-POE-ISO/open-source-hardware +; with ESP32-C6-WROOM-1U modem +; all data is stored on SDCARD only +; ---------------------------------------------------------------------------------------- +[env:OpenEPaperLink_ESP32-PoE-ISO_AP] +board=esp32-poe-iso +board_build.partitions = esp32_sdcard_only.csv +build_unflags = + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -std=gnu++11 +lib_deps = + ${env.lib_deps} +build_flags = + -std=gnu++17 + ${env.build_flags} + -D OPENEPAPERLINK_MINI_AP_PCB + -D CONFIG_SPIRAM_USE_MALLOC=1 + -D CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y + -D BOARD_HAS_PSRAM + -mfix-esp32-psram-cache-issue + -D HAS_SDCARD + -D SD_CARD_SDMMC + -D SD_CARD_ONLY + -D POWER_NO_SOFT_POWER + -D FLASHER_AP_SS=-1 + -D FLASHER_AP_CLK=-1 + -D FLASHER_AP_MOSI=-1 + -D FLASHER_AP_MISO=-1 + -D FLASHER_AP_RESET=5 + -D FLASHER_AP_POWER={-1} ;this board has no soft power control + -D FLASHER_AP_TXD=4 + -D FLASHER_AP_RXD=36 + -D FLASHER_AP_TEST=-1 + -D FLASHER_LED=-1 + -D FLASHER_DEBUG_TXD=32 + -D FLASHER_DEBUG_RXD=33 + -D FLASHER_DEBUG_PROG=13 + -D MD5_ENABLED=1 + -D SERIAL_FLASHER_INTERFACE_UART=1 + -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 + -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 + -D C6_OTA_FLASHING + -D ETHERNET_PHY_POWER=12 + -D ETHERNET_CLK_MODE=ETH_CLOCK_GPIO0_OUT + -D ETHERNET_PHY_MDC=ETH_PHY_MDC + -D ETHERNET_PHY_MDIO=ETH_PHY_MDIO + -D ETHERNET_PHY_TYPE=ETH_PHY_TYPE +build_src_filter = + +<*>-- +board_build.flash_mode=qio +board_upload.maximum_size = 4194304 +board_upload.maximum_ram_size = 327680 +board_upload.flash_size = 4MB ; ---------------------------------------------------------------------------------------- ; !!! this configuration expects an SONOFF ZB Bridge-P ; ---------------------------------------------------------------------------------------- @@ -834,7 +889,7 @@ board_upload.flash_size = 16MB ;board_build.partitions = default.csv ;build_unflags = ; -std=gnu++11 -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D CORE_DEBUG_LEVEL=0 @@ -851,7 +906,7 @@ board_upload.flash_size = 16MB ; -D FLASHER_AP_TXD=19 ; -D FLASHER_AP_RXD=23 ; -D FLASHER_LED=2 -;build_src_filter = +;build_src_filter = ; +<*>--- ;board_build.psram_type=qspi_opi ;board_upload.maximum_size = 4194304 @@ -867,7 +922,7 @@ board_upload.flash_size = 16MB ;build_unflags = ; -std=gnu++11 ; -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D OPENEPAPERLINK_MINI_AP_PCB @@ -887,7 +942,7 @@ board_upload.flash_size = 16MB ; -D FLASHER_AP_TEST=-1 ; -D FLASHER_LED=2 ; -D FLASHER_RGB_LED=-1 -;build_src_filter = +;build_src_filter = ; +<*>--- ;board_build.psram_type=qspi_opi ;board_upload.maximum_size = 4194304 @@ -903,7 +958,7 @@ board_upload.flash_size = 16MB ; -std=gnu++11 ; -D ARDUINO_USB_MODE=1 ; -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D OutdoorAP @@ -926,7 +981,7 @@ board_upload.flash_size = 16MB ; -D FLASHER_AP_RXD=18 ; -D FLASHER_LED=21 ; -D FLASHER_RGB_LED=38 -;build_src_filter = +;build_src_filter = ; +<*>--- ;board_build.flash_mode=opi ;board_build.arduino.memory_type = opi_opi @@ -943,7 +998,7 @@ board_upload.flash_size = 16MB ;board_build.partitions = default.csv ;build_unflags = ; -std=gnu++11 -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D CORE_DEBUG_LEVEL=0 @@ -958,7 +1013,7 @@ board_upload.flash_size = 16MB ; -D FLASHER_AP_TXD=16 ; -D FLASHER_AP_RXD=17 ; -D FLASHER_LED=22 -;build_src_filter = +;build_src_filter = ; +<*>--- ; ---------------------------------------------------------------------------------------- ; !!! this configuration expects an m5stack esp32 @@ -969,7 +1024,7 @@ board_upload.flash_size = 16MB ;board_build.partitions = esp32_sdcard.csv ;build_unflags = ; -std=gnu++11 -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D CORE_DEBUG_LEVEL=0 @@ -995,7 +1050,7 @@ board_upload.flash_size = 16MB ; -D DISABLE_ALL_LIBRARY_WARNINGS ; -D ILI9341_DRIVER ; -D SMOOTH_FONT -;build_src_filter = +;build_src_filter = ; +<*>--- ; ---------------------------------------------------------------------------------------- ; !!! this configuration expects the Nano_C6 @@ -1007,7 +1062,7 @@ board_upload.flash_size = 16MB ;build_unflags = ; -std=gnu++11 ; -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D OPENEPAPERLINK_NANO_AP_PCB @@ -1031,7 +1086,7 @@ board_upload.flash_size = 16MB ; -D SERIAL_FLASHER_INTERFACE_UART=1 ; -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 ; -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 -;build_src_filter = +;build_src_filter = ; +<*>--- ;board_build.psram_type=qspi_opi ;board_upload.maximum_size = 4194304 @@ -1039,7 +1094,7 @@ board_upload.flash_size = 16MB ;board_upload.flash_size = 4MB ; ---------------------------------------------------------------------------------------- -; !!! Release 2.75 was the last release that supported ESP32-S2 based APs or ESP32-S3 APs +; !!! Release 2.75 was the last release that supported ESP32-S2 based APs or ESP32-S3 APs ; !!! with less than 16Mb flash and 8MB RAM. ; ---------------------------------------------------------------------------------------- @@ -1053,7 +1108,7 @@ board_upload.flash_size = 16MB ;build_unflags = ; -std=gnu++11 ; -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D OPENEPAPERLINK_MINI_AP_PCB @@ -1075,7 +1130,7 @@ board_upload.flash_size = 16MB ; -D FLASHER_AP_TEST=12 ; -D FLASHER_LED=15 ; -D FLASHER_RGB_LED=33 -;build_src_filter = +;build_src_filter = ; +<*>----- ;board_build.psram_type=qspi_opi ;board_upload.maximum_size = 4194304 @@ -1092,7 +1147,7 @@ board_upload.flash_size = 16MB ;build_unflags = ; -std=gnu++11 ; -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D OPENEPAPERLINK_NANO_AP_PCB @@ -1112,7 +1167,7 @@ board_upload.flash_size = 16MB ; -D FLASHER_AP_TEST=36 ; -D FLASHER_LED=15 ; -D FLASHER_RGB_LED=-1 -;build_src_filter = +;build_src_filter = ; +<*>----- ;board_build.psram_type=qspi_opi ;board_upload.maximum_size = 4194304 @@ -1127,7 +1182,7 @@ board_upload.flash_size = 16MB ;board_build.partitions = default.csv ;build_unflags = ; -std=gnu++11 -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; -D CORE_DEBUG_LEVEL=0 @@ -1143,7 +1198,7 @@ board_upload.flash_size = 16MB ; -D FLASHER_AP_TXD=17 ; -D FLASHER_AP_RXD=16 ; -D FLASHER_LED=22 -;build_src_filter = +;build_src_filter = ; +<*>----- ; ;; ---------------------------------------------------------------------------------------- @@ -1157,7 +1212,7 @@ board_upload.flash_size = 16MB ; -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y ;lib_deps = ; ${env.lib_deps} -;build_flags = +;build_flags = ; -std=gnu++17 ; ${env.build_flags} ; ;-D HAS_BLE_WRITER @@ -1186,7 +1241,7 @@ board_upload.flash_size = 16MB ; -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 ; -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100 ; -D C6_OTA_FLASHING -;build_src_filter = +;build_src_filter = ; +<*>--- ;board_build.psram_type=qspi_opi ;board_upload.maximum_size = 4194304 diff --git a/ESP32_AP-Flasher/prepare_sdcard.sh b/ESP32_AP-Flasher/prepare_sdcard.sh new file mode 100755 index 00000000..eba35783 --- /dev/null +++ b/ESP32_AP-Flasher/prepare_sdcard.sh @@ -0,0 +1,23 @@ +#!/usr/bin/bash + +if [[ -d $1 ]]; then + rm -rf $1/* + cp -r data/* $1 + rm $1/www/* + cp -r wwwroot/* $1/www/ + cp ../binaries/ESP32-C6/firmware.json $1 + for f in bootloader partition-table OpenEPaperLink_esp32_C6 + do + if [[ -e ../ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/build/bootloader/${f}.bin ]]; then + cp ../ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/build/bootloader/${f}.bin $1 + else + cp ../binaries/ESP32-C6/${f}.bin $1 + fi + done + mkdir $1/current + echo "[[]]" > $1/current/tagDB.json + echo "OK" +else + echo "$1 is not a directory" + exit 1 +fi diff --git a/ESP32_AP-Flasher/src/leds.cpp b/ESP32_AP-Flasher/src/leds.cpp index 03eb49b4..5bb7b705 100644 --- a/ESP32_AP-Flasher/src/leds.cpp +++ b/ESP32_AP-Flasher/src/leds.cpp @@ -41,7 +41,7 @@ void ledcSet(uint8_t channel, uint8_t brightness) { ledcWrite(channel, brightness); #else ledcWriteChannel(channel, brightness); -#endif +#endif } #ifdef HAS_RGB_LED @@ -176,7 +176,9 @@ void addFadeMono(uint8_t value) { } void showMono(uint8_t brightness) { - ledcSet(7, gamma8[brightness]); + if (FLASHER_LED != -1) { + ledcSet(7, gamma8[brightness]); + } } void quickBlink(uint8_t repeat) { @@ -295,7 +297,7 @@ void ledTask(void* parameter) { if (monoled->fadeTime <= 1) { showMono(monoled->value); } - } + } } else { if (monoled->fadeTime) { monoled->fadeTime--; @@ -311,4 +313,4 @@ void ledTask(void* parameter) { vTaskDelay(1 / portTICK_PERIOD_MS); } -} \ No newline at end of file +} diff --git a/ESP32_AP-Flasher/src/main.cpp b/ESP32_AP-Flasher/src/main.cpp index 763fd285..856964e5 100644 --- a/ESP32_AP-Flasher/src/main.cpp +++ b/ESP32_AP-Flasher/src/main.cpp @@ -2,6 +2,9 @@ #include #include #include +#ifdef ETHERNET_CLK_MODE +#include +#endif #include "contentmanager.h" #include "flasher.h" @@ -119,6 +122,7 @@ void setup() { } */ + wm.initEth(); initAPconfig(); updateLanguageFromConfig(); @@ -155,7 +159,12 @@ void setup() { // We'll need to start the 'usbflasher' task for boards with a second (USB) port. This can be used as a 'flasher' interface, using a python script on the host xTaskCreate(usbFlasherTask, "usbflasher", 10000, NULL, 5, NULL); #else + +#ifdef ETHERNET_CLK_MODE + if (!(ETHERNET_CLK_MODE == ETH_CLOCK_GPIO0_IN || ETHERNET_CLK_MODE == ETH_CLOCK_GPIO0_OUT)) +#endif pinMode(0, INPUT_PULLUP); + #endif #ifdef HAS_EXT_FLASHER diff --git a/ESP32_AP-Flasher/src/ota.cpp b/ESP32_AP-Flasher/src/ota.cpp index b721852d..18f629e7 100644 --- a/ESP32_AP-Flasher/src/ota.cpp +++ b/ESP32_AP-Flasher/src/ota.cpp @@ -148,12 +148,13 @@ void handleLittleFSUpload(AsyncWebServerRequest* request, String filename, size_ file.write(uploadInfo->buffer, uploadInfo->bufferSize); file.close(); uploadInfo->bufferSize = 0; + xSemaphoreGive(fsMutex); } else { + xSemaphoreGive(fsMutex); logLine("Failed to open file for appending: " + uploadfilename); final = true; error = true; } - xSemaphoreGive(fsMutex); memcpy(uploadInfo->buffer, data, len); uploadInfo->bufferSize = len; @@ -166,11 +167,12 @@ void handleLittleFSUpload(AsyncWebServerRequest* request, String filename, size_ if (file) { file.write(uploadInfo->buffer, uploadInfo->bufferSize); file.close(); + xSemaphoreGive(fsMutex); } else { + xSemaphoreGive(fsMutex); logLine("Failed to open file for appending: " + uploadfilename); error = true; } - xSemaphoreGive(fsMutex); request->_tempObject = nullptr; delete uploadInfo; } @@ -333,7 +335,7 @@ void C6firmwareUpdateTask(void* parameter) { Serial1.begin(115200, SERIAL_8N1, FLASHER_AP_RXD, FLASHER_AP_TXD); #ifndef FLASHER_DEBUG_SHARED rxSerialStopTask2 = false; - xTaskCreate(rxSerialTask2, "rxSerialTask2", 1750, NULL, 2, NULL); + xTaskCreate(rxSerialTask2, "rxSerialTask2", 1850, NULL, 2, NULL); #endif vTaskDelay(1000 / portTICK_PERIOD_MS); @@ -345,12 +347,12 @@ void C6firmwareUpdateTask(void* parameter) { wsSerial("bringing AP online"); if (bringAPOnline()) config.runStatus = RUNSTATUS_RUN; - // Wait for version info to arrive + // Wait for version info to arrive vTaskDelay(50 / portTICK_PERIOD_MS); if(apInfo.version == 0) { result = false; } - } + } if (result) { wsSerial("Finished!"); @@ -409,4 +411,4 @@ void handleUpdateActions(AsyncWebServerRequest* request) { wsSerial("Cleanup finished"); request->send(200, "Clean up finished"); contentFS->remove("/update_actions.json"); -} \ No newline at end of file +} diff --git a/ESP32_AP-Flasher/src/serialap.cpp b/ESP32_AP-Flasher/src/serialap.cpp index 778bd4fd..4e63e8a3 100644 --- a/ESP32_AP-Flasher/src/serialap.cpp +++ b/ESP32_AP-Flasher/src/serialap.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "commstructs.h" #include "contentmanager.h" @@ -706,7 +707,18 @@ void rxSerialTask(void* parameter) { } #if defined(FLASHER_DEBUG_RXD) && !defined(FLASHER_DEBUG_SHARED) +uint32_t millisDiff(uint32_t m) { + uint32_t ms = millis(); + if (ms >= m) + return ms - m; + else + return UINT32_MAX - m + ms + 1; +} + void rxSerialTask2(void* parameter) { + char rxStr[100] = {0}; + int rxStrCount = 0; + uint32_t modemResetHoldoff = millis(); char lastchar = 0; time_t startTime = millis(); int charCount = 0; @@ -718,6 +730,33 @@ void rxSerialTask2(void* parameter) { // debug info Serial.write(lastchar); + + rxStr[rxStrCount] = lastchar; + if (lastchar == '\n' || lastchar == '\r') { + if (strncmp(rxStr, "receive buffer full, drop the current frame", 43) == 0 && millisDiff(modemResetHoldoff) > 20000) { + modemResetHoldoff = millis(); + vTaskDelay(100 / portTICK_PERIOD_MS); + config.runStatus = RUNSTATUS_STOP; + Serial.println("IEEE802.15.4 modem stuck case detected, resetting..."); + APTagReset(); + vTaskDelay(1000 / portTICK_PERIOD_MS); + Serial.println("bringing AP online again"); + if (bringAPOnline()) { + config.runStatus = RUNSTATUS_RUN; + Serial.println("Finished!"); + } else { + Serial.println("Failed!"); + } + logLine("IEEE802.15.4 modem reset " + (config.runStatus == RUNSTATUS_RUN)?("ok"):("failed")); + } + rxStrCount = 0; + memset(rxStr, 0, sizeof(rxStr)); + } else if(rxStrCount < sizeof(rxStr) - 2) { + rxStrCount++; + } else { + rxStrCount = 0; + memset(rxStr, 0, sizeof(rxStr)); + } } vTaskDelay(1 / portTICK_PERIOD_MS); @@ -887,7 +926,7 @@ void APTask(void* parameter) { xTaskCreate(rxCmdProcessor, "rxCmdProcessor", 6000, NULL, 15, NULL); #if defined(FLASHER_DEBUG_RXD) && !defined(FLASHER_DEBUG_SHARED) - xTaskCreate(rxSerialTask2, "rxSerialTask2", 1750, NULL, 2, NULL); + xTaskCreate(rxSerialTask2, "rxSerialTask2", 1850, NULL, 2, NULL); vTaskDelay(500 / portTICK_PERIOD_MS); #endif bringAPOnline(); @@ -924,7 +963,7 @@ void APTask(void* parameter) { if (FLASHER_AP_MOSI != -1) { fsversion = getAPUpdateVersion(apInfo.type); if ((fsversion) && (apInfo.version != fsversion)) { - Serial.printf("Firmware version on LittleFS: %04X\r\n", fsversion); + Serial.printf("Firmware version on FS: %04X\r\n", fsversion); Serial.printf("We're going to try to update the AP's FW in\r\n"); flashCountDown(30); diff --git a/ESP32_AP-Flasher/src/storage.cpp b/ESP32_AP-Flasher/src/storage.cpp index fee95ddf..33be51f1 100644 --- a/ESP32_AP-Flasher/src/storage.cpp +++ b/ESP32_AP-Flasher/src/storage.cpp @@ -2,22 +2,63 @@ #ifdef HAS_SDCARD #include "FS.h" +#ifdef SD_CARD_SDMMC +#include "SD_MMC.h" +#define SDCARD SD_MMC +#else #include "SD.h" #include "SPI.h" +#define SDCARD SD +#endif #endif +#ifndef SD_CARD_ONLY #include "LittleFS.h" +#endif DynStorage::DynStorage() : isInited(0) {} -SemaphoreHandle_t fsMutex; +SemaphoreHandle_t fsMutex = NULL; +#ifndef SD_CARD_ONLY static void initLittleFS() { LittleFS.begin(); contentFS = &LittleFS; } +#endif #ifdef HAS_SDCARD +static bool sd_init_done = false; +#ifdef SD_CARD_SDMMC +static void initSDCard() { + if(!SD_MMC.begin("/sdcard", true, true, BOARD_MAX_SDMMC_FREQ, 5)){ + Serial.println("Card Mount Failed"); + return; + } + uint8_t cardType = SD_MMC.cardType(); + + if(cardType == CARD_NONE){ + Serial.println("No SD_MMC card attached"); + return; + } + + Serial.print("SD_MMC Card Type: "); + if(cardType == CARD_MMC){ + Serial.println("MMC"); + } else if(cardType == CARD_SD){ + Serial.println("SDSC"); + } else if(cardType == CARD_SDHC){ + Serial.println("SDHC"); + } else { + Serial.println("UNKNOWN"); + } + + uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024); + Serial.printf("SD_MMC Card Size: %lluMB\n", cardSize); + + contentFS = &SD_MMC; +} +#else static SPIClass* spi; static void initSDCard() { @@ -45,15 +86,19 @@ static void initSDCard() { contentFS = &SD; } #endif +#endif uint64_t DynStorage::freeSpace(){ this->begin(); #ifdef HAS_SDCARD - return SD.totalBytes() - SD.usedBytes(); + return SDCARD.totalBytes() - SDCARD.usedBytes(); #endif +#ifndef SD_CARD_ONLY return LittleFS.totalBytes() - LittleFS.usedBytes(); +#endif } +#ifndef SD_CARD_ONLY void copyFile(File in, File out) { Serial.print("Copying "); Serial.print(in.path()); @@ -127,14 +172,25 @@ void copyIfNeeded(const char* path) { } } #endif +#endif void DynStorage::begin() { - fsMutex = xSemaphoreCreateMutex(); + if(fsMutex == NULL) { + fsMutex = xSemaphoreCreateMutex(); + } + +#ifndef SD_CARD_ONLY initLittleFS(); +#endif #ifdef HAS_SDCARD - initSDCard(); - + if(!sd_init_done) { + xSemaphoreTake(fsMutex, portMAX_DELAY); + initSDCard(); + xSemaphoreGive(fsMutex); + sd_init_done = true; + } +#ifndef SD_CARD_ONLY copyIfNeeded("/index.html"); copyIfNeeded("/fonts"); copyIfNeeded("/www"); @@ -143,6 +199,7 @@ void DynStorage::begin() { copyIfNeeded("/tag_md5_db.json"); copyIfNeeded("/update_actions.json"); copyIfNeeded("/content_template.json"); +#endif #endif if (!contentFS->exists("/current")) { @@ -155,7 +212,17 @@ void DynStorage::begin() { void DynStorage::end() { #ifdef HAS_SDCARD +#ifndef SD_CARD_ONLY initLittleFS(); +#endif +#ifdef SD_CARD_SDMMC +#ifndef SD_CARD_ONLY + contentFS = &LittleFS; +#endif + SD_MMC.end(); + sd_init_done = false; +#else +#ifndef SD_CARD_ONLY if (SD_CARD_CLK == FLASHER_AP_CLK || SD_CARD_MISO == FLASHER_AP_MISO || SD_CARD_MOSI == FLASHER_AP_MOSI) { @@ -171,7 +238,8 @@ void DynStorage::end() { contentFS = &LittleFS; } - +#endif +#endif #endif } diff --git a/ESP32_AP-Flasher/src/system.cpp b/ESP32_AP-Flasher/src/system.cpp index 65e8eca8..cd8609f5 100644 --- a/ESP32_AP-Flasher/src/system.cpp +++ b/ESP32_AP-Flasher/src/system.cpp @@ -14,7 +14,7 @@ void timeSyncCallback(struct timeval* tv) { } void initTime(void* parameter) { - if (WiFi.status() != WL_CONNECTED) { + if (!(WiFi.status() == WL_CONNECTED || wm.wifiStatus == ETHERNET)) { vTaskDelay(500 / portTICK_PERIOD_MS); } sntp_set_time_sync_notification_cb(timeSyncCallback); diff --git a/ESP32_AP-Flasher/src/tag_db.cpp b/ESP32_AP-Flasher/src/tag_db.cpp index bfcc95f9..4feba865 100644 --- a/ESP32_AP-Flasher/src/tag_db.cpp +++ b/ESP32_AP-Flasher/src/tag_db.cpp @@ -137,8 +137,10 @@ void saveDB(const String& filename) { vTaskDelay(pdMS_TO_TICKS(100)); String backupFilename = filename + ".bak"; if (!contentFS->rename(filename.c_str(), backupFilename.c_str())) { + xSemaphoreGive(fsMutex); logLine("error renaming tagDB to .bak"); wsErr("error renaming tagDB to .bak"); + xSemaphoreTake(fsMutex, portMAX_DELAY); } } diff --git a/ESP32_AP-Flasher/src/tagdata.cpp b/ESP32_AP-Flasher/src/tagdata.cpp index 8d250909..cb74bd3a 100644 --- a/ESP32_AP-Flasher/src/tagdata.cpp +++ b/ESP32_AP-Flasher/src/tagdata.cpp @@ -10,6 +10,9 @@ std::unordered_map TagData::parsers = {}; void TagData::loadParsers(const String& filename) { const long start = millis(); + if (!contentFS->exists(filename)) { + return; + } fs::File file = contentFS->open(filename, "r"); if (!file) { return; @@ -145,4 +148,4 @@ void TagData::parse(const uint8_t src[8], const size_t id, const uint8_t* data, } } -#endif \ No newline at end of file +#endif diff --git a/ESP32_AP-Flasher/src/udp.cpp b/ESP32_AP-Flasher/src/udp.cpp index f548b906..57dbcad4 100644 --- a/ESP32_AP-Flasher/src/udp.cpp +++ b/ESP32_AP-Flasher/src/udp.cpp @@ -9,6 +9,7 @@ #include "serialap.h" #include "tag_db.h" #include "web.h" +#include "wifimanager.h" #define UDPIP IPAddress(239, 10, 0, 1) #define UDPPORT 16033 @@ -34,7 +35,7 @@ void UDPcomm::init() { if (config.discovery == 0) { if (udp.listenMulticast(UDPIP, UDPPORT)) { udp.onPacket([this](AsyncUDPPacket packet) { - if (packet.remoteIP() != WiFi.localIP()) { + if (packet.remoteIP() != wm.localIP()) { this->processPacket(packet); } }); @@ -42,7 +43,7 @@ void UDPcomm::init() { } else { if (udp.listen(UDPPORT)) { udp.onPacket([this](AsyncUDPPacket packet) { - if (packet.isBroadcast() && packet.remoteIP() != WiFi.localIP()) { + if (packet.isBroadcast() && packet.remoteIP() != wm.localIP()) { this->processPacket(packet); } }); @@ -88,7 +89,7 @@ void UDPcomm::processPacket(AsyncUDPPacket packet) { } case PKT_APLIST_REQ: { APlist APitem; - APitem.src = WiFi.localIP(); + APitem.src = wm.localIP(); strcpy(APitem.alias, config.alias); APitem.channelId = curChannel.channel; APitem.tagCount = getTagCount(); @@ -154,7 +155,7 @@ void autoselect(void* pvParameters) { void UDPcomm::getAPList() { APlist APitem; - APitem.src = WiFi.localIP(); + APitem.src = wm.localIP(); strcpy(APitem.alias, config.alias); APitem.channelId = curChannel.channel; APitem.tagCount = getTagCount(); diff --git a/ESP32_AP-Flasher/src/web.cpp b/ESP32_AP-Flasher/src/web.cpp index 76d2e831..19d29577 100644 --- a/ESP32_AP-Flasher/src/web.cpp +++ b/ESP32_AP-Flasher/src/web.cpp @@ -107,7 +107,7 @@ void wsSendSysteminfo() { strftime(timeBuffer, sizeof(timeBuffer), languageDateFormat[0].c_str(), &timeinfo); setVarDB("ap_date", timeBuffer); } - setVarDB("ap_ip", WiFi.localIP().toString()); + setVarDB("ap_ip", wm.localIP().toString()); #ifdef HAS_SUBGHZ String ApChanString = String(apInfo.channel); @@ -874,10 +874,11 @@ void doImageUpload(AsyncWebServerRequest *request, String filename, size_t index file.write(uploadInfo->buffer, uploadInfo->bufferSize); file.close(); uploadInfo->bufferSize = 0; + xSemaphoreGive(fsMutex); } else { + xSemaphoreGive(fsMutex); logLine("Failed to open file for appending: " + uploadfilename); } - xSemaphoreGive(fsMutex); memcpy(uploadInfo->buffer, data, len); uploadInfo->bufferSize = len; @@ -891,10 +892,11 @@ void doImageUpload(AsyncWebServerRequest *request, String filename, size_t index if (file) { file.write(uploadInfo->buffer, uploadInfo->bufferSize); file.close(); + xSemaphoreGive(fsMutex); } else { + xSemaphoreGive(fsMutex); logLine("Failed to open file for appending: " + uploadfilename); } - xSemaphoreGive(fsMutex); request->_tempObject = nullptr; delete uploadInfo; } @@ -964,7 +966,7 @@ void doJsonUpload(AsyncWebServerRequest *request) { uint8_t mac[8]; if (hex2mac(dst, mac)) { xSemaphoreTake(fsMutex, portMAX_DELAY); - File file = LittleFS.open("/current/" + dst + ".json", "w"); + File file = contentFS->open("/current/" + dst + ".json", "w"); if (!file) { request->send(400, "text/plain", "Failed to create file"); xSemaphoreGive(fsMutex); diff --git a/ESP32_AP-Flasher/src/wifimanager.cpp b/ESP32_AP-Flasher/src/wifimanager.cpp index 48a56e01..acbd9a0a 100644 --- a/ESP32_AP-Flasher/src/wifimanager.cpp +++ b/ESP32_AP-Flasher/src/wifimanager.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include "newproto.h" #include "system.h" #include "tag_db.h" @@ -16,6 +18,13 @@ uint8_t WifiManager::apClients = 0; uint8_t x_buffer[100]; uint8_t x_position = 0; +#if defined(ETHERNET_PHY_POWER) && defined(ETHERNET_PHY_MDC) && defined(ETHERNET_PHY_MDIO) && defined(ETHERNET_PHY_TYPE) && defined(ETHERNET_CLK_MODE) +static bool eth_init = false; +static bool eth_connected = false; +static bool eth_ip_ok = false; +static long eth_timeout = 0; +#endif + WifiManager::WifiManager() { _reconnectIntervalCheck = 5000; _retryIntervalCheck = 5 * 60000; @@ -43,6 +52,24 @@ void WifiManager::terminalLog(String text) { } void WifiManager::poll() { + +#if defined(ETHERNET_PHY_POWER) && defined(ETHERNET_PHY_MDC) && defined(ETHERNET_PHY_MDIO) && defined(ETHERNET_PHY_TYPE) && defined(ETHERNET_CLK_MODE) + + if (eth_connected) { + wifiStatus = ETHERNET; + if(!eth_ip_ok && eth_timeout != 0 && millis() - eth_timeout > 2000) { + eth_timeout = 0; + eth_connected = false; + } + } else if(!eth_connected && wifiStatus == ETHERNET) { + wifiStatus = NOINIT; + _APstarted = false; + WiFi.mode(WIFI_STA); + connectToWifi(); + } + +#endif + if (wifiStatus == AP && millis() > _nextReconnectCheck && _ssid != "") { if (apClients == 0) { terminalLog("Attempting to reconnect to WiFi."); @@ -68,6 +95,10 @@ void WifiManager::poll() { } #ifndef HAS_USB + +#ifdef ETHERNET_CLK_MODE + if (!(ETHERNET_CLK_MODE == ETH_CLOCK_GPIO0_IN || ETHERNET_CLK_MODE == ETH_CLOCK_GPIO0_OUT)) { +#endif // ap_and_flasher has gpio0 in use as FLASHER_AP_POWER if (digitalRead(0) == LOW) { Serial.println("GPIO0 LOW"); @@ -99,12 +130,37 @@ void WifiManager::poll() { ESP.restart(); } } +#ifdef ETHERNET_CLK_MODE + } +#endif + #endif pollSerial(); } +void WifiManager::initEth() { +#if defined(ETHERNET_PHY_POWER) && defined(ETHERNET_PHY_MDC) && defined(ETHERNET_PHY_MDIO) && defined(ETHERNET_PHY_TYPE) && defined(ETHERNET_CLK_MODE) + if(!eth_init) { + eth_init = true; + ETH.begin( + ETH_PHY_ADDR, + ETHERNET_PHY_POWER, + ETHERNET_PHY_MDC, + ETHERNET_PHY_MDIO, + ETHERNET_PHY_TYPE, + ETHERNET_CLK_MODE, + false); + } +#endif +} + bool WifiManager::connectToWifi() { +#if defined(ETHERNET_PHY_POWER) && defined(ETHERNET_PHY_MDC) && defined(ETHERNET_PHY_MDIO) && defined(ETHERNET_PHY_TYPE) && defined(ETHERNET_CLK_MODE) + if (wifiStatus == ETHERNET || eth_connected) + return true; +#endif + Preferences preferences; preferences.begin("wifi", false); _ssid = preferences.getString("ssid", WiFi_SSID()); @@ -136,6 +192,11 @@ bool WifiManager::connectToWifi() { } bool WifiManager::connectToWifi(String ssid, String pass, bool savewhensuccessfull) { +#if defined(ETHERNET_PHY_POWER) && defined(ETHERNET_PHY_MDC) && defined(ETHERNET_PHY_MDIO) && defined(ETHERNET_PHY_TYPE) && defined(ETHERNET_CLK_MODE) + if (wifiStatus == ETHERNET) + return true; +#endif + _ssid = ssid; _pass = pass; _savewhensuccessfull = savewhensuccessfull; @@ -145,26 +206,7 @@ bool WifiManager::connectToWifi(String ssid, String pass, bool savewhensuccessfu delay(100); WiFi.mode(WIFI_MODE_NULL); delay(100); - char hostname[32] = "OpenEpaperLink-"; - uint8_t mac[6]; - WiFi.macAddress(mac); - char lastTwoBytes[5]; - sprintf(lastTwoBytes, "%02X%02X", mac[4], mac[5]); - strcat(hostname, lastTwoBytes); - - if (config.alias[0] != '\0') { - int len = strlen(config.alias); - int j = 0; - for (int i = 0; i < len; i++) { - char c = config.alias[i]; - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-') { - hostname[j] = c; - j++; - } - } - hostname[j] = '\0'; - } - WiFi.setHostname(hostname); + WiFi.setHostname(buildHostname(ESP_MAC_WIFI_STA).c_str()); WiFi.mode(WIFI_STA); WiFi.setSleep(WIFI_PS_MIN_MODEM); @@ -177,6 +219,11 @@ bool WifiManager::connectToWifi(String ssid, String pass, bool savewhensuccessfu } bool WifiManager::waitForConnection() { +#if defined(ETHERNET_PHY_POWER) && defined(ETHERNET_PHY_MDC) && defined(ETHERNET_PHY_MDIO) && defined(ETHERNET_PHY_TYPE) && defined(ETHERNET_CLK_MODE) + if (wifiStatus == ETHERNET) + return true; +#endif + unsigned long timeout = millis() + _connectionTimeout; wifiStatus = WAIT_CONNECTING; @@ -209,7 +256,7 @@ bool WifiManager::waitForConnection() { } void WifiManager::startManagementServer() { - if (!_APstarted) { + if (!_APstarted && wifiStatus != ETHERNET) { terminalLog("Starting config AP, ssid: OpenEPaperLink"); logLine("Starting configuration AP, ssid OpenEPaperLink"); WiFi.disconnect(true, true); @@ -225,6 +272,37 @@ void WifiManager::startManagementServer() { } } +String WifiManager::buildHostname(esp_mac_type_t mac_type) { + char hostname[32] = "OpenEpaperLink-"; + uint8_t mac[6]; + esp_read_mac(mac, mac_type); + char lastTwoBytes[5]; + sprintf(lastTwoBytes, "%02X%02X", mac[4], mac[5]); + strcat(hostname, lastTwoBytes); + + if (config.alias[0] != '\0') { + int len = strlen(config.alias); + int j = 0; + for (int i = 0; i < len; i++) { + char c = config.alias[i]; + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-') { + hostname[j] = c; + j++; + } + } + hostname[j] = '\0'; + } + return String(hostname); +} + +IPAddress WifiManager::localIP() { + if (wifiStatus == ETHERNET) { + return ETH.localIP(); + } else { + return WiFi.localIP(); + } +} + String WifiManager::WiFi_SSID() { wifi_config_t conf; esp_wifi_get_config(WIFI_IF_STA, &conf); @@ -296,6 +374,46 @@ void WifiManager::WiFiEvent(WiFiEvent_t event) { // eventname = "Assigned IP address to client"; break; +#if defined(ETHERNET_PHY_POWER) && defined(ETHERNET_PHY_MDC) && defined(ETHERNET_PHY_MDIO) && defined(ETHERNET_PHY_TYPE) && defined(ETHERNET_CLK_MODE) + + case ARDUINO_EVENT_ETH_START: + eventname = "ETH Started"; + //set eth hostname here + ETH.setHostname(buildHostname(ESP_MAC_ETH).c_str()); + eth_timeout = 0; + break; + case ARDUINO_EVENT_ETH_CONNECTED: + eventname = "ETH Connected"; + WiFi.mode(WIFI_MODE_NULL); + WiFi.disconnect(); + eth_connected = true; + eth_timeout = millis(); + break; + case ARDUINO_EVENT_ETH_GOT_IP: + if (ETH.fullDuplex()) { + eventname = "ETH MAC: " + ETH.macAddress() + ", IPv4: " + ETH.localIP().toString() + ", FULL_DUPLEX, " + ETH.linkSpeed() + "Mbps"; + } else { + eventname = "ETH MAC: " + ETH.macAddress() + ", IPv4: " + ETH.localIP().toString() + ", " + ETH.linkSpeed() + "Mbps"; + } + eth_ip_ok = true; + init_udp(); + eth_timeout = 0; + break; + case ARDUINO_EVENT_ETH_DISCONNECTED: + eventname = "ETH Disconnected"; + eth_connected = false; + eth_ip_ok = false; + eth_timeout = 0; + break; + case ARDUINO_EVENT_ETH_STOP: + eventname = "ETH Stopped"; + eth_connected = false; + eth_ip_ok = false; + eth_timeout = 0; + break; + +#endif + default: break; }