Merge branch 'master' into release/v3.3.x
This commit is contained in:
commit
70696df2d6
31 changed files with 1334 additions and 132 deletions
3
.github/workflows/lib.json
vendored
3
.github/workflows/lib.json
vendored
|
|
@ -9,7 +9,8 @@
|
||||||
{
|
{
|
||||||
"name": "ArduinoBLE",
|
"name": "ArduinoBLE",
|
||||||
"exclude_targets": [
|
"exclude_targets": [
|
||||||
"esp32s2"
|
"esp32s2",
|
||||||
|
"esp32p4"
|
||||||
],
|
],
|
||||||
"sketch_path": [
|
"sketch_path": [
|
||||||
"~/Arduino/libraries/ArduinoBLE/examples/Central/Scan/Scan.ino"
|
"~/Arduino/libraries/ArduinoBLE/examples/Central/Scan/Scan.ino"
|
||||||
|
|
|
||||||
402
boards.txt
402
boards.txt
|
|
@ -41204,7 +41204,7 @@ sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2=TinyUF2 4MB (1.3MB APP/960KB F
|
||||||
sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader-tinyuf2
|
sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader-tinyuf2
|
||||||
sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.build.custom_partitions=partitions-4MB-tinyuf2
|
sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.build.custom_partitions=partitions-4MB-tinyuf2
|
||||||
sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.upload.maximum_size=1441792
|
sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.upload.maximum_size=1441792
|
||||||
sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x2d0000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin"
|
sensebox_mcu_esp32s2.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x2d0000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" 0x170000 "{runtime.platform.path}/variants/{build.variant}/APOTA.bin"
|
||||||
sensebox_mcu_esp32s2.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
|
sensebox_mcu_esp32s2.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
|
||||||
sensebox_mcu_esp32s2.menu.PartitionScheme.default.build.partitions=default
|
sensebox_mcu_esp32s2.menu.PartitionScheme.default.build.partitions=default
|
||||||
sensebox_mcu_esp32s2.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
|
sensebox_mcu_esp32s2.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
|
||||||
|
|
@ -50758,3 +50758,403 @@ cyobot_v2_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR
|
||||||
cyobot_v2_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote
|
cyobot_v2_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
|
|
||||||
|
rakwireless_rak3112.name=RAKwireless RAK3112
|
||||||
|
|
||||||
|
rakwireless_rak3112.upload.tool=esptool_py
|
||||||
|
rakwireless_rak3112.upload.tool.default=esptool_py
|
||||||
|
rakwireless_rak3112.upload.tool.network=esp_ota
|
||||||
|
rakwireless_rak3112.upload.maximum_size=1310720
|
||||||
|
rakwireless_rak3112.upload.maximum_data_size=327680
|
||||||
|
rakwireless_rak3112.upload.wait_for_upload_port=false
|
||||||
|
rakwireless_rak3112.upload.speed=460800
|
||||||
|
rakwireless_rak3112.upload.flags=
|
||||||
|
rakwireless_rak3112.upload.extra_flags=
|
||||||
|
|
||||||
|
rakwireless_rak3112.bootloader.tool=esptool_py
|
||||||
|
rakwireless_rak3112.bootloader.tool.default=esptool_py
|
||||||
|
|
||||||
|
rakwireless_rak3112.serial.disableDTR=true
|
||||||
|
rakwireless_rak3112.serial.disableRTS=true
|
||||||
|
|
||||||
|
rakwireless_rak3112.build.tarch=xtensa
|
||||||
|
rakwireless_rak3112.build.bootloader_addr=0x0
|
||||||
|
rakwireless_rak3112.build.mcu=esp32s3
|
||||||
|
rakwireless_rak3112.build.core=esp32
|
||||||
|
rakwireless_rak3112.build.target=esp32s3
|
||||||
|
rakwireless_rak3112.build.variant=rakwireless_rak3112
|
||||||
|
rakwireless_rak3112.build.board=RAKWIRELESS_RAK3112
|
||||||
|
|
||||||
|
rakwireless_rak3112.build.usb_mode=1
|
||||||
|
rakwireless_rak3112.build.cdc_on_boot=1
|
||||||
|
rakwireless_rak3112.build.msc_on_boot=0
|
||||||
|
rakwireless_rak3112.build.dfu_on_boot=0
|
||||||
|
|
||||||
|
rakwireless_rak3112.build.f_cpu=240000000L
|
||||||
|
rakwireless_rak3112.build.flash_size=16MB
|
||||||
|
rakwireless_rak3112.build.flash_freq=80m
|
||||||
|
rakwireless_rak3112.build.flash_mode=dio
|
||||||
|
rakwireless_rak3112.build.boot=dio
|
||||||
|
rakwireless_rak3112.build.partitions=default
|
||||||
|
rakwireless_rak3112.build.defines=
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.PSRAM.enabled=Enabled
|
||||||
|
rakwireless_rak3112.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM
|
||||||
|
rakwireless_rak3112.menu.PSRAM.enabled.build.psram_type=opi
|
||||||
|
rakwireless_rak3112.menu.PSRAM.disabled=Disabled
|
||||||
|
rakwireless_rak3112.menu.PSRAM.disabled.build.defines=
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.LoopCore.1=Core 1
|
||||||
|
rakwireless_rak3112.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1
|
||||||
|
rakwireless_rak3112.menu.LoopCore.0=Core 0
|
||||||
|
rakwireless_rak3112.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.EventsCore.1=Core 1
|
||||||
|
rakwireless_rak3112.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1
|
||||||
|
rakwireless_rak3112.menu.EventsCore.0=Core 0
|
||||||
|
rakwireless_rak3112.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.USBMode.hwcdc=Hardware CDC and JTAG
|
||||||
|
rakwireless_rak3112.menu.USBMode.hwcdc.build.usb_mode=1
|
||||||
|
rakwireless_rak3112.menu.USBMode.default=USB-OTG (TinyUSB)
|
||||||
|
rakwireless_rak3112.menu.USBMode.default.build.usb_mode=0
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.CDCOnBoot.default=Enabled
|
||||||
|
rakwireless_rak3112.menu.CDCOnBoot.default.build.cdc_on_boot=1
|
||||||
|
rakwireless_rak3112.menu.CDCOnBoot.cdc=Disabled
|
||||||
|
rakwireless_rak3112.menu.CDCOnBoot.cdc.build.cdc_on_boot=0
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.MSCOnBoot.default=Disabled
|
||||||
|
rakwireless_rak3112.menu.MSCOnBoot.default.build.msc_on_boot=0
|
||||||
|
rakwireless_rak3112.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode)
|
||||||
|
rakwireless_rak3112.menu.MSCOnBoot.msc.build.msc_on_boot=1
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.DFUOnBoot.default=Disabled
|
||||||
|
rakwireless_rak3112.menu.DFUOnBoot.default.build.dfu_on_boot=0
|
||||||
|
rakwireless_rak3112.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode)
|
||||||
|
rakwireless_rak3112.menu.DFUOnBoot.dfu.build.dfu_on_boot=1
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.UploadMode.default=UART0 / Hardware CDC
|
||||||
|
rakwireless_rak3112.menu.UploadMode.default.upload.use_1200bps_touch=false
|
||||||
|
rakwireless_rak3112.menu.UploadMode.default.upload.wait_for_upload_port=false
|
||||||
|
rakwireless_rak3112.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB)
|
||||||
|
rakwireless_rak3112.menu.UploadMode.cdc.upload.use_1200bps_touch=true
|
||||||
|
rakwireless_rak3112.menu.UploadMode.cdc.upload.wait_for_upload_port=true
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.default_16MB=Default (6.25MB APP/3.43MB SPIFFS)
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.default_16MB.build.partitions=default_16MB
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.default_16MB.upload.maximum_size=6553600
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9MB FATFS)
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2=TinyUF2 16MB (2MB APP/11.6MB FATFS)
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader-tinyuf2
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2.build.partitions=tinyuf2-partitions-16MB
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2.upload.maximum_size=2097152
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x410000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin"
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota=TinyUF2 16MB No OTA(4MB APP/11.6MB FATFS)
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota.build.custom_bootloader=bootloader-tinyuf2
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota.build.partitions=tinyuf2-partitions-16MB-noota
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota.upload.maximum_size=4194304
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.tinyuf2_noota.upload.extra_flags=0x410000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin"
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.large_spiffs=Large SPIFFS (4.5MB APP/6.93MB SPIFFS)
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.large_spiffs.build.partitions=large_spiffs_16MB
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.large_spiffs.upload.maximum_size=4718592
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.custom=Custom
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.custom.build.partitions=
|
||||||
|
rakwireless_rak3112.menu.PartitionScheme.custom.upload.maximum_size=16777216
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.CPUFreq.240=240MHz (WiFi/BT)
|
||||||
|
rakwireless_rak3112.menu.CPUFreq.240.build.f_cpu=240000000L
|
||||||
|
rakwireless_rak3112.menu.CPUFreq.160=160MHz (WiFi/BT)
|
||||||
|
rakwireless_rak3112.menu.CPUFreq.160.build.f_cpu=160000000L
|
||||||
|
rakwireless_rak3112.menu.CPUFreq.80=80MHz (WiFi/BT)
|
||||||
|
rakwireless_rak3112.menu.CPUFreq.80.build.f_cpu=80000000L
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.FlashMode.qio=QIO
|
||||||
|
rakwireless_rak3112.menu.FlashMode.qio.build.flash_mode=dio
|
||||||
|
rakwireless_rak3112.menu.FlashMode.qio.build.boot=qio
|
||||||
|
rakwireless_rak3112.menu.FlashMode.dio=DIO
|
||||||
|
rakwireless_rak3112.menu.FlashMode.dio.build.flash_mode=dio
|
||||||
|
rakwireless_rak3112.menu.FlashMode.dio.build.boot=dio
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.FlashFreq.80=80MHz
|
||||||
|
rakwireless_rak3112.menu.FlashFreq.80.build.flash_freq=80m
|
||||||
|
rakwireless_rak3112.menu.FlashFreq.40=40MHz
|
||||||
|
rakwireless_rak3112.menu.FlashFreq.40.build.flash_freq=40m
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.921600=921600
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.921600.upload.speed=921600
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.115200=115200
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.115200.upload.speed=115200
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.256000.windows=256000
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.256000.upload.speed=256000
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.230400.windows.upload.speed=256000
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.230400=230400
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.230400.upload.speed=230400
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.460800.linux=460800
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.460800.macosx=460800
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.460800.upload.speed=460800
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.512000.windows=512000
|
||||||
|
rakwireless_rak3112.menu.UploadSpeed.512000.upload.speed=512000
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.none=None
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.none.build.code_debug=0
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.error=Error
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.error.build.code_debug=1
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.warn=Warn
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.warn.build.code_debug=2
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.info=Info
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.info.build.code_debug=3
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.debug=Debug
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.debug.build.code_debug=4
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.verbose=Verbose
|
||||||
|
rakwireless_rak3112.menu.DebugLevel.verbose.build.code_debug=5
|
||||||
|
|
||||||
|
rakwireless_rak3112.menu.EraseFlash.none=Disabled
|
||||||
|
rakwireless_rak3112.menu.EraseFlash.none.upload.erase_cmd=
|
||||||
|
rakwireless_rak3112.menu.EraseFlash.all=Enabled
|
||||||
|
rakwireless_rak3112.menu.EraseFlash.all.upload.erase_cmd=-e
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
kodedot.name=kode dot
|
||||||
|
|
||||||
|
kodedot.bootloader.tool=esptool_py
|
||||||
|
kodedot.bootloader.tool.default=esptool_py
|
||||||
|
|
||||||
|
kodedot.upload.tool=esptool_py_app_only
|
||||||
|
kodedot.upload.tool.default=esptool_py_app_only
|
||||||
|
kodedot.upload.tool.network=esp_ota
|
||||||
|
|
||||||
|
kodedot.upload.maximum_size=8388608
|
||||||
|
kodedot.upload.maximum_data_size=327680
|
||||||
|
kodedot.upload.flags=
|
||||||
|
kodedot.upload.extra_flags=
|
||||||
|
kodedot.upload.use_1200bps_touch=false
|
||||||
|
kodedot.upload.wait_for_upload_port=false
|
||||||
|
kodedot.upload.speed=921600
|
||||||
|
|
||||||
|
kodedot.upload.erase_cmd=
|
||||||
|
|
||||||
|
kodedot.serial.disableDTR=false
|
||||||
|
kodedot.serial.disableRTS=false
|
||||||
|
|
||||||
|
kodedot.build.tarch=xtensa
|
||||||
|
kodedot.build.bootloader_addr=0x0
|
||||||
|
kodedot.build.target=esp32s3
|
||||||
|
kodedot.build.mcu=esp32s3
|
||||||
|
kodedot.build.core=esp32
|
||||||
|
kodedot.build.variant=kodedot
|
||||||
|
kodedot.build.board=KODE_DOT
|
||||||
|
|
||||||
|
kodedot.build.usb_mode=1
|
||||||
|
kodedot.build.cdc_on_boot=1
|
||||||
|
kodedot.build.msc_on_boot=0
|
||||||
|
kodedot.build.dfu_on_boot=0
|
||||||
|
|
||||||
|
kodedot.build.f_cpu=240000000L
|
||||||
|
|
||||||
|
kodedot.build.flash_offset=0x400000
|
||||||
|
kodedot.build.flash_size=16MB
|
||||||
|
kodedot.build.flash_freq=80m
|
||||||
|
kodedot.build.flash_mode=dio
|
||||||
|
|
||||||
|
kodedot.build.custom_partitions=kodedot_partitions
|
||||||
|
|
||||||
|
kodedot.build.psram_type=qspi
|
||||||
|
kodedot.build.defines=
|
||||||
|
|
||||||
|
kodedot.build.loop_core=-DARDUINO_RUNNING_CORE=1
|
||||||
|
kodedot.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1
|
||||||
|
|
||||||
|
kodedot.recipe.hooks.objcopy.postobjcopy.3.pattern=
|
||||||
|
kodedot.recipe.hooks.objcopy.postobjcopy.3.pattern_args=
|
||||||
|
|
||||||
|
kodedot.recipe.output.save_file={build.project_name}.ino.bin
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
# FED4 Board
|
||||||
|
fed4.name=FED4
|
||||||
|
fed4.vid.0=0x303A
|
||||||
|
fed4.pid.0=0x82E5
|
||||||
|
fed4.upload_port.0.vid=0x303A
|
||||||
|
fed4.upload_port.0.pid=0x82E5
|
||||||
|
fed4.bootloader.tool=esptool_py
|
||||||
|
fed4.bootloader.tool.default=esptool_py
|
||||||
|
|
||||||
|
fed4.upload.tool=esptool_py
|
||||||
|
fed4.upload.tool.default=esptool_py
|
||||||
|
fed4.upload.tool.network=esp_ota
|
||||||
|
|
||||||
|
fed4.upload.maximum_size=1310720
|
||||||
|
fed4.upload.maximum_data_size=327680
|
||||||
|
fed4.upload.flags=
|
||||||
|
fed4.upload.extra_flags=
|
||||||
|
fed4.upload.use_1200bps_touch=false
|
||||||
|
fed4.upload.wait_for_upload_port=false
|
||||||
|
|
||||||
|
fed4.serial.disableDTR=false
|
||||||
|
fed4.serial.disableRTS=false
|
||||||
|
|
||||||
|
fed4.build.tarch=xtensa
|
||||||
|
fed4.build.bootloader_addr=0x0
|
||||||
|
fed4.build.target=esp32s3
|
||||||
|
fed4.build.mcu=esp32s3
|
||||||
|
fed4.build.core=esp32
|
||||||
|
fed4.build.variant=fed4
|
||||||
|
fed4.build.board=FED4
|
||||||
|
|
||||||
|
fed4.build.usb_mode=1
|
||||||
|
fed4.build.cdc_on_boot=0
|
||||||
|
fed4.build.msc_on_boot=0
|
||||||
|
fed4.build.dfu_on_boot=0
|
||||||
|
fed4.build.f_cpu=240000000L
|
||||||
|
fed4.build.flash_size=16MB
|
||||||
|
fed4.build.flash_freq=80m
|
||||||
|
fed4.build.flash_mode=dio
|
||||||
|
fed4.build.boot=qio
|
||||||
|
fed4.build.boot_freq=80m
|
||||||
|
fed4.build.partitions=default_16MB
|
||||||
|
fed4.build.defines=
|
||||||
|
fed4.build.loop_core=
|
||||||
|
fed4.build.event_core=
|
||||||
|
fed4.build.psram_type=qspi
|
||||||
|
fed4.build.memory_type={build.boot}_{build.psram_type}
|
||||||
|
|
||||||
|
## IDE 2.0 Seems to not update the value
|
||||||
|
fed4.menu.JTAGAdapter.default=Disabled
|
||||||
|
fed4.menu.JTAGAdapter.default.build.copy_jtag_files=0
|
||||||
|
fed4.menu.JTAGAdapter.builtin=Integrated USB JTAG
|
||||||
|
fed4.menu.JTAGAdapter.builtin.build.openocdscript=fed4-builtin.cfg
|
||||||
|
fed4.menu.JTAGAdapter.builtin.build.copy_jtag_files=1
|
||||||
|
fed4.menu.JTAGAdapter.external=FTDI Adapter
|
||||||
|
fed4.menu.JTAGAdapter.external.build.openocdscript=fed4-ftdi.cfg
|
||||||
|
fed4.menu.JTAGAdapter.external.build.copy_jtag_files=1
|
||||||
|
fed4.menu.JTAGAdapter.bridge=ESP USB Bridge
|
||||||
|
fed4.menu.JTAGAdapter.bridge.build.openocdscript=fed4-bridge.cfg
|
||||||
|
fed4.menu.JTAGAdapter.bridge.build.copy_jtag_files=1
|
||||||
|
|
||||||
|
fed4.menu.FlashMode.qio=QIO 80MHz
|
||||||
|
fed4.menu.FlashMode.qio.build.flash_mode=dio
|
||||||
|
fed4.menu.FlashMode.qio.build.boot=qio
|
||||||
|
fed4.menu.FlashMode.qio.build.boot_freq=80m
|
||||||
|
fed4.menu.FlashMode.qio.build.flash_freq=80m
|
||||||
|
fed4.menu.FlashMode.qio120=QIO 120MHz
|
||||||
|
fed4.menu.FlashMode.qio120.build.flash_mode=dio
|
||||||
|
fed4.menu.FlashMode.qio120.build.boot=qio
|
||||||
|
fed4.menu.FlashMode.qio120.build.boot_freq=120m
|
||||||
|
fed4.menu.FlashMode.qio120.build.flash_freq=80m
|
||||||
|
fed4.menu.FlashMode.dio=DIO 80MHz
|
||||||
|
fed4.menu.FlashMode.dio.build.flash_mode=dio
|
||||||
|
fed4.menu.FlashMode.dio.build.boot=dio
|
||||||
|
fed4.menu.FlashMode.dio.build.boot_freq=80m
|
||||||
|
fed4.menu.FlashMode.dio.build.flash_freq=80m
|
||||||
|
|
||||||
|
fed4.menu.FlashSize.16M=16MB (128Mb)
|
||||||
|
fed4.menu.FlashSize.16M.build.flash_size=16MB
|
||||||
|
|
||||||
|
fed4.menu.LoopCore.1=Core 1
|
||||||
|
fed4.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1
|
||||||
|
fed4.menu.LoopCore.0=Core 0
|
||||||
|
fed4.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0
|
||||||
|
|
||||||
|
fed4.menu.EventsCore.1=Core 1
|
||||||
|
fed4.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1
|
||||||
|
fed4.menu.EventsCore.0=Core 0
|
||||||
|
fed4.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0
|
||||||
|
|
||||||
|
fed4.menu.USBMode.hwcdc=Hardware CDC and JTAG
|
||||||
|
fed4.menu.USBMode.hwcdc.build.usb_mode=1
|
||||||
|
fed4.menu.USBMode.default=USB-OTG (TinyUSB)
|
||||||
|
fed4.menu.USBMode.default.build.usb_mode=0
|
||||||
|
|
||||||
|
fed4.menu.CDCOnBoot.default=Disabled
|
||||||
|
fed4.menu.CDCOnBoot.default.build.cdc_on_boot=0
|
||||||
|
fed4.menu.CDCOnBoot.cdc=Enabled
|
||||||
|
fed4.menu.CDCOnBoot.cdc.build.cdc_on_boot=1
|
||||||
|
|
||||||
|
fed4.menu.MSCOnBoot.default=Disabled
|
||||||
|
fed4.menu.MSCOnBoot.default.build.msc_on_boot=0
|
||||||
|
fed4.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode)
|
||||||
|
fed4.menu.MSCOnBoot.msc.build.msc_on_boot=1
|
||||||
|
|
||||||
|
fed4.menu.DFUOnBoot.default=Disabled
|
||||||
|
fed4.menu.DFUOnBoot.default.build.dfu_on_boot=0
|
||||||
|
fed4.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode)
|
||||||
|
fed4.menu.DFUOnBoot.dfu.build.dfu_on_boot=1
|
||||||
|
|
||||||
|
fed4.menu.UploadMode.default=UART0 / Hardware CDC
|
||||||
|
fed4.menu.UploadMode.default.upload.use_1200bps_touch=false
|
||||||
|
fed4.menu.UploadMode.default.upload.wait_for_upload_port=false
|
||||||
|
fed4.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB)
|
||||||
|
fed4.menu.UploadMode.cdc.upload.use_1200bps_touch=true
|
||||||
|
fed4.menu.UploadMode.cdc.upload.wait_for_upload_port=true
|
||||||
|
|
||||||
|
fed4.menu.PartitionScheme.default_16MB=Default (6.25MB APP/3.43MB SPIFFS)
|
||||||
|
fed4.menu.PartitionScheme.default_16MB.build.partitions=default_16MB
|
||||||
|
fed4.menu.PartitionScheme.default_16MB.upload.maximum_size=6553600
|
||||||
|
fed4.menu.PartitionScheme.large_spiffs=Large SPIFFS (4.5MB APP/6.93MB SPIFFS)
|
||||||
|
fed4.menu.PartitionScheme.large_spiffs.build.partitions=large_spiffs_16MB
|
||||||
|
fed4.menu.PartitionScheme.large_spiffs.upload.maximum_size=4718592
|
||||||
|
fed4.menu.PartitionScheme.app3M_fat9M_16MB=FFAT (3MB APP/9MB FATFS)
|
||||||
|
fed4.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB
|
||||||
|
fed4.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728
|
||||||
|
fed4.menu.PartitionScheme.fatflash=Large FFAT (2MB APP/12.5MB FATFS)
|
||||||
|
fed4.menu.PartitionScheme.fatflash.build.partitions=ffat
|
||||||
|
fed4.menu.PartitionScheme.fatflash.upload.maximum_size=2097152
|
||||||
|
|
||||||
|
fed4.menu.CPUFreq.240=240MHz (WiFi)
|
||||||
|
fed4.menu.CPUFreq.240.build.f_cpu=240000000L
|
||||||
|
fed4.menu.CPUFreq.160=160MHz (WiFi)
|
||||||
|
fed4.menu.CPUFreq.160.build.f_cpu=160000000L
|
||||||
|
fed4.menu.CPUFreq.80=80MHz (WiFi)
|
||||||
|
fed4.menu.CPUFreq.80.build.f_cpu=80000000L
|
||||||
|
fed4.menu.CPUFreq.40=40MHz
|
||||||
|
fed4.menu.CPUFreq.40.build.f_cpu=40000000L
|
||||||
|
fed4.menu.CPUFreq.20=20MHz
|
||||||
|
fed4.menu.CPUFreq.20.build.f_cpu=20000000L
|
||||||
|
fed4.menu.CPUFreq.10=10MHz
|
||||||
|
fed4.menu.CPUFreq.10.build.f_cpu=10000000L
|
||||||
|
|
||||||
|
fed4.menu.UploadSpeed.921600=921600
|
||||||
|
fed4.menu.UploadSpeed.921600.upload.speed=921600
|
||||||
|
fed4.menu.UploadSpeed.115200=115200
|
||||||
|
fed4.menu.UploadSpeed.115200.upload.speed=115200
|
||||||
|
fed4.menu.UploadSpeed.256000.windows=256000
|
||||||
|
fed4.menu.UploadSpeed.256000.upload.speed=256000
|
||||||
|
fed4.menu.UploadSpeed.230400.windows.upload.speed=256000
|
||||||
|
fed4.menu.UploadSpeed.230400=230400
|
||||||
|
fed4.menu.UploadSpeed.230400.upload.speed=230400
|
||||||
|
fed4.menu.UploadSpeed.460800.linux=460800
|
||||||
|
fed4.menu.UploadSpeed.460800.macosx=460800
|
||||||
|
fed4.menu.UploadSpeed.460800.upload.speed=460800
|
||||||
|
fed4.menu.UploadSpeed.512000.windows=512000
|
||||||
|
fed4.menu.UploadSpeed.512000.upload.speed=512000
|
||||||
|
|
||||||
|
fed4.menu.DebugLevel.none=None
|
||||||
|
fed4.menu.DebugLevel.none.build.code_debug=0
|
||||||
|
fed4.menu.DebugLevel.error=Error
|
||||||
|
fed4.menu.DebugLevel.error.build.code_debug=1
|
||||||
|
fed4.menu.DebugLevel.warn=Warn
|
||||||
|
fed4.menu.DebugLevel.warn.build.code_debug=2
|
||||||
|
fed4.menu.DebugLevel.info=Info
|
||||||
|
fed4.menu.DebugLevel.info.build.code_debug=3
|
||||||
|
fed4.menu.DebugLevel.debug=Debug
|
||||||
|
fed4.menu.DebugLevel.debug.build.code_debug=4
|
||||||
|
fed4.menu.DebugLevel.verbose=Verbose
|
||||||
|
fed4.menu.DebugLevel.verbose.build.code_debug=5
|
||||||
|
|
||||||
|
fed4.menu.EraseFlash.none=Disabled
|
||||||
|
fed4.menu.EraseFlash.none.upload.erase_cmd=
|
||||||
|
fed4.menu.EraseFlash.all=Enabled
|
||||||
|
fed4.menu.EraseFlash.all.upload.erase_cmd=-e
|
||||||
|
|
||||||
|
fed4.menu.ZigbeeMode.default=Disabled
|
||||||
|
fed4.menu.ZigbeeMode.default.build.zigbee_mode=
|
||||||
|
fed4.menu.ZigbeeMode.default.build.zigbee_libs=
|
||||||
|
fed4.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router)
|
||||||
|
fed4.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR
|
||||||
|
fed4.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ bool String::changeBuffer(unsigned int maxStrLen) {
|
||||||
if (maxStrLen < sizeof(sso.buff) - 1) {
|
if (maxStrLen < sizeof(sso.buff) - 1) {
|
||||||
if (isSSO() || !buffer()) {
|
if (isSSO() || !buffer()) {
|
||||||
// Already using SSO, nothing to do
|
// Already using SSO, nothing to do
|
||||||
uint16_t oldLen = len();
|
size_t oldLen = len();
|
||||||
setSSO(true);
|
setSSO(true);
|
||||||
setLen(oldLen);
|
setLen(oldLen);
|
||||||
} else { // if bufptr && !isSSO()
|
} else { // if bufptr && !isSSO()
|
||||||
|
|
@ -188,7 +188,7 @@ bool String::changeBuffer(unsigned int maxStrLen) {
|
||||||
char temp[sizeof(sso.buff)];
|
char temp[sizeof(sso.buff)];
|
||||||
memcpy(temp, buffer(), maxStrLen);
|
memcpy(temp, buffer(), maxStrLen);
|
||||||
free(wbuffer());
|
free(wbuffer());
|
||||||
uint16_t oldLen = len();
|
size_t oldLen = len();
|
||||||
setSSO(true);
|
setSSO(true);
|
||||||
memcpy(wbuffer(), temp, maxStrLen);
|
memcpy(wbuffer(), temp, maxStrLen);
|
||||||
setLen(oldLen);
|
setLen(oldLen);
|
||||||
|
|
@ -201,7 +201,7 @@ bool String::changeBuffer(unsigned int maxStrLen) {
|
||||||
if (newSize > CAPACITY_MAX) {
|
if (newSize > CAPACITY_MAX) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint16_t oldLen = len();
|
size_t oldLen = len();
|
||||||
char *newbuffer = (char *)realloc(isSSO() ? nullptr : wbuffer(), newSize);
|
char *newbuffer = (char *)realloc(isSSO() ? nullptr : wbuffer(), newSize);
|
||||||
if (newbuffer) {
|
if (newbuffer) {
|
||||||
size_t oldSize = capacity() + 1; // include NULL.
|
size_t oldSize = capacity() + 1; // include NULL.
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,10 @@
|
||||||
#include "esp_camera.h"
|
#include "esp_camera.h"
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
|
||||||
//
|
// ===========================
|
||||||
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
|
// Select camera model in board_config.h
|
||||||
// Ensure ESP32 Wrover Module or other board with PSRAM is selected
|
// ===========================
|
||||||
// Partial images will be transmitted if image exceeds buffer size
|
#include "board_config.h"
|
||||||
//
|
|
||||||
// You must select partition scheme from the board menu that has at least 3MB APP space.
|
|
||||||
// Face Recognition is DISABLED for ESP32 and ESP32-S2, because it takes up from 15
|
|
||||||
// seconds to process single frame. Face Detection is ENABLED if PSRAM is enabled as well
|
|
||||||
|
|
||||||
// ===================
|
|
||||||
// Select camera model
|
|
||||||
// ===================
|
|
||||||
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
|
|
||||||
#define CAMERA_MODEL_ESP_EYE // Has PSRAM
|
|
||||||
//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
|
|
||||||
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
|
|
||||||
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
|
|
||||||
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
|
|
||||||
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
|
|
||||||
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
|
|
||||||
//#define CAMERA_MODEL_M5STACK_CAMS3_UNIT // Has PSRAM
|
|
||||||
//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
|
|
||||||
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
|
|
||||||
//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM
|
|
||||||
// ** Espressif Internal Boards **
|
|
||||||
//#define CAMERA_MODEL_ESP32_CAM_BOARD
|
|
||||||
//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
|
|
||||||
//#define CAMERA_MODEL_ESP32S3_CAM_LCD
|
|
||||||
//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM
|
|
||||||
//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM
|
|
||||||
#include "camera_pins.h"
|
|
||||||
|
|
||||||
// ===========================
|
// ===========================
|
||||||
// Enter your WiFi credentials
|
// Enter your WiFi credentials
|
||||||
|
|
@ -40,7 +13,7 @@ const char *ssid = "**********";
|
||||||
const char *password = "**********";
|
const char *password = "**********";
|
||||||
|
|
||||||
void startCameraServer();
|
void startCameraServer();
|
||||||
void setupLedFlash(int pin);
|
void setupLedFlash();
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
|
@ -130,7 +103,7 @@ void setup() {
|
||||||
|
|
||||||
// Setup LED FLash if LED pin is defined in camera_pins.h
|
// Setup LED FLash if LED pin is defined in camera_pins.h
|
||||||
#if defined(LED_GPIO_NUM)
|
#if defined(LED_GPIO_NUM)
|
||||||
setupLedFlash(LED_GPIO_NUM);
|
setupLedFlash();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WiFi.begin(ssid, password);
|
WiFi.begin(ssid, password);
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,14 @@
|
||||||
#include "esp32-hal-ledc.h"
|
#include "esp32-hal-ledc.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "camera_index.h"
|
#include "camera_index.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
|
||||||
#include "esp32-hal-log.h"
|
#include "esp32-hal-log.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable LED FLASH setting
|
|
||||||
#define CONFIG_LED_ILLUMINATOR_ENABLED 1
|
|
||||||
|
|
||||||
// LED FLASH setup
|
// LED FLASH setup
|
||||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
#if defined(LED_GPIO_NUM)
|
||||||
|
|
||||||
#define LED_LEDC_GPIO 22 //configure LED pin
|
|
||||||
#define CONFIG_LED_MAX_INTENSITY 255
|
#define CONFIG_LED_MAX_INTENSITY 255
|
||||||
|
|
||||||
int led_duty = 0;
|
int led_duty = 0;
|
||||||
|
|
@ -91,13 +87,13 @@ static int ra_filter_run(ra_filter_t *filter, int value) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
#if defined(LED_GPIO_NUM)
|
||||||
void enable_led(bool en) { // Turn LED On or Off
|
void enable_led(bool en) { // Turn LED On or Off
|
||||||
int duty = en ? led_duty : 0;
|
int duty = en ? led_duty : 0;
|
||||||
if (en && isStreaming && (led_duty > CONFIG_LED_MAX_INTENSITY)) {
|
if (en && isStreaming && (led_duty > CONFIG_LED_MAX_INTENSITY)) {
|
||||||
duty = CONFIG_LED_MAX_INTENSITY;
|
duty = CONFIG_LED_MAX_INTENSITY;
|
||||||
}
|
}
|
||||||
ledcWrite(LED_LEDC_GPIO, duty);
|
ledcWrite(LED_GPIO_NUM, duty);
|
||||||
//ledc_set_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL, duty);
|
//ledc_set_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL, duty);
|
||||||
//ledc_update_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL);
|
//ledc_update_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL);
|
||||||
log_i("Set LED intensity to %d", duty);
|
log_i("Set LED intensity to %d", duty);
|
||||||
|
|
@ -162,7 +158,7 @@ static esp_err_t capture_handler(httpd_req_t *req) {
|
||||||
int64_t fr_start = esp_timer_get_time();
|
int64_t fr_start = esp_timer_get_time();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
#if defined(LED_GPIO_NUM)
|
||||||
enable_led(true);
|
enable_led(true);
|
||||||
vTaskDelay(150 / portTICK_PERIOD_MS); // The LED needs to be turned on ~150ms before the call to esp_camera_fb_get()
|
vTaskDelay(150 / portTICK_PERIOD_MS); // The LED needs to be turned on ~150ms before the call to esp_camera_fb_get()
|
||||||
fb = esp_camera_fb_get(); // or it won't be visible in the frame. A better way to do this is needed.
|
fb = esp_camera_fb_get(); // or it won't be visible in the frame. A better way to do this is needed.
|
||||||
|
|
@ -230,7 +226,7 @@ static esp_err_t stream_handler(httpd_req_t *req) {
|
||||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||||
httpd_resp_set_hdr(req, "X-Framerate", "60");
|
httpd_resp_set_hdr(req, "X-Framerate", "60");
|
||||||
|
|
||||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
#if defined(LED_GPIO_NUM)
|
||||||
isStreaming = true;
|
isStreaming = true;
|
||||||
enable_led(true);
|
enable_led(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -293,7 +289,7 @@ static esp_err_t stream_handler(httpd_req_t *req) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
#if defined(LED_GPIO_NUM)
|
||||||
isStreaming = false;
|
isStreaming = false;
|
||||||
enable_led(false);
|
enable_led(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -393,7 +389,7 @@ static esp_err_t cmd_handler(httpd_req_t *req) {
|
||||||
} else if (!strcmp(variable, "ae_level")) {
|
} else if (!strcmp(variable, "ae_level")) {
|
||||||
res = s->set_ae_level(s, val);
|
res = s->set_ae_level(s, val);
|
||||||
}
|
}
|
||||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
#if defined(LED_GPIO_NUM)
|
||||||
else if (!strcmp(variable, "led_intensity")) {
|
else if (!strcmp(variable, "led_intensity")) {
|
||||||
led_duty = val;
|
led_duty = val;
|
||||||
if (isStreaming) {
|
if (isStreaming) {
|
||||||
|
|
@ -481,7 +477,7 @@ static esp_err_t status_handler(httpd_req_t *req) {
|
||||||
p += sprintf(p, "\"vflip\":%u,", s->status.vflip);
|
p += sprintf(p, "\"vflip\":%u,", s->status.vflip);
|
||||||
p += sprintf(p, "\"dcw\":%u,", s->status.dcw);
|
p += sprintf(p, "\"dcw\":%u,", s->status.dcw);
|
||||||
p += sprintf(p, "\"colorbar\":%u", s->status.colorbar);
|
p += sprintf(p, "\"colorbar\":%u", s->status.colorbar);
|
||||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
#if defined(LED_GPIO_NUM)
|
||||||
p += sprintf(p, ",\"led_intensity\":%u", led_duty);
|
p += sprintf(p, ",\"led_intensity\":%u", led_duty);
|
||||||
#else
|
#else
|
||||||
p += sprintf(p, ",\"led_intensity\":%d", -1);
|
p += sprintf(p, ",\"led_intensity\":%d", -1);
|
||||||
|
|
@ -843,10 +839,10 @@ void startCameraServer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupLedFlash(int pin) {
|
void setupLedFlash() {
|
||||||
#if CONFIG_LED_ILLUMINATOR_ENABLED
|
#if defined(LED_GPIO_NUM)
|
||||||
ledcAttach(pin, 5000, 8);
|
ledcAttach(LED_GPIO_NUM, 5000, 8);
|
||||||
#else
|
#else
|
||||||
log_i("LED flash is disabled -> CONFIG_LED_ILLUMINATOR_ENABLED = 0");
|
log_i("LED flash is disabled -> LED_GPIO_NUM undefined");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef BOARD_CONFIG_H
|
||||||
|
#define BOARD_CONFIG_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
|
||||||
|
// Ensure ESP32 Wrover Module or other board with PSRAM is selected
|
||||||
|
// Partial images will be transmitted if image exceeds buffer size
|
||||||
|
//
|
||||||
|
// You must select partition scheme from the board menu that has at least 3MB APP space.
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Select camera model
|
||||||
|
// ===================
|
||||||
|
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
|
||||||
|
#define CAMERA_MODEL_ESP_EYE // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
|
||||||
|
//#define CAMERA_MODEL_M5STACK_CAMS3_UNIT // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
|
||||||
|
//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM
|
||||||
|
// ** Espressif Internal Boards **
|
||||||
|
//#define CAMERA_MODEL_ESP32_CAM_BOARD
|
||||||
|
//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
|
||||||
|
//#define CAMERA_MODEL_ESP32S3_CAM_LCD
|
||||||
|
//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM
|
||||||
|
//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM
|
||||||
|
#include "camera_pins.h"
|
||||||
|
|
||||||
|
#endif // BOARD_CONFIG_H
|
||||||
|
|
@ -86,6 +86,8 @@ void setup() {
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
|
||||||
|
|
||||||
Serial.println("Setup complete. Broadcasting messages every 5 seconds.");
|
Serial.println("Setup complete. Broadcasting messages every 5 seconds.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,8 @@ void setup() {
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
|
||||||
|
|
||||||
// Register the new peer callback
|
// Register the new peer callback
|
||||||
ESP_NOW.onNewPeer(register_new_master, nullptr);
|
ESP_NOW.onNewPeer(register_new_master, nullptr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,12 @@
|
||||||
// The following struct is used to send data to the peer device.
|
// The following struct is used to send data to the peer device.
|
||||||
// We use the attribute "packed" to ensure that the struct is not padded (all data
|
// We use the attribute "packed" to ensure that the struct is not padded (all data
|
||||||
// is contiguous in the memory and without gaps).
|
// is contiguous in the memory and without gaps).
|
||||||
// The maximum size of the complete message is 250 bytes (ESP_NOW_MAX_DATA_LEN).
|
// The maximum size of the payload is 250 bytes (ESP_NOW_MAX_DATA_LEN) for ESP-NOW v1.0.
|
||||||
|
// For ESP-NOW v2.0, the maximum size of the payload is 1470 bytes (ESP_NOW_MAX_DATA_LEN_V2).
|
||||||
|
// You can use ESP_NOW.getMaxDataLen() after calling ESP_NOW.begin() to get the maximum size
|
||||||
|
// of the data that can be sent.
|
||||||
|
// Read about the compatibility between ESP-NOW v1.0 and v2.0 in the ESP-IDF documentation:
|
||||||
|
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html#frame-format
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
|
|
@ -276,6 +281,8 @@ void setup() {
|
||||||
fail_reboot();
|
fail_reboot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
|
||||||
|
|
||||||
if (!broadcast_peer.begin()) {
|
if (!broadcast_peer.begin()) {
|
||||||
Serial.println("Failed to initialize broadcast peer");
|
Serial.println("Failed to initialize broadcast peer");
|
||||||
fail_reboot();
|
fail_reboot();
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ void setup() {
|
||||||
// Start the ESP-NOW communication
|
// Start the ESP-NOW communication
|
||||||
Serial.println("ESP-NOW communication starting...");
|
Serial.println("ESP-NOW communication starting...");
|
||||||
NowSerial.begin(115200);
|
NowSerial.begin(115200);
|
||||||
|
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
|
||||||
Serial.println("You can now send data to the peer device using the Serial Monitor.\n");
|
Serial.println("You can now send data to the peer device using the Serial Monitor.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,10 @@ static void _esp_now_tx_cb(const uint8_t *mac_addr, esp_now_send_status_t status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_NOW_Class::ESP_NOW_Class() {}
|
ESP_NOW_Class::ESP_NOW_Class() {
|
||||||
|
max_data_len = 0;
|
||||||
|
version = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ESP_NOW_Class::~ESP_NOW_Class() {}
|
ESP_NOW_Class::~ESP_NOW_Class() {}
|
||||||
|
|
||||||
|
|
@ -160,6 +163,23 @@ bool ESP_NOW_Class::begin(const uint8_t *pmk) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unfortunately we can't get the ESP-NOW version before initializing the Wi-Fi
|
||||||
|
uint32_t esp_now_version;
|
||||||
|
err = esp_now_get_version(&esp_now_version);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
log_w("esp_now_get_version failed! Assuming ESP-NOW v1.0");
|
||||||
|
esp_now_version = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esp_now_version == 1) {
|
||||||
|
max_data_len = ESP_NOW_MAX_DATA_LEN;
|
||||||
|
} else {
|
||||||
|
max_data_len = ESP_NOW_MAX_DATA_LEN_V2;
|
||||||
|
}
|
||||||
|
|
||||||
|
version = esp_now_version;
|
||||||
|
log_i("ESP-NOW version: %lu, max_data_len: %lu", version, max_data_len);
|
||||||
|
|
||||||
_esp_now_has_begun = true;
|
_esp_now_has_begun = true;
|
||||||
|
|
||||||
memset(_esp_now_peers, 0, sizeof(ESP_NOW_Peer *) * ESP_NOW_MAX_TOTAL_PEER_NUM);
|
memset(_esp_now_peers, 0, sizeof(ESP_NOW_Peer *) * ESP_NOW_MAX_TOTAL_PEER_NUM);
|
||||||
|
|
@ -217,7 +237,7 @@ bool ESP_NOW_Class::end() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ESP_NOW_Class::getTotalPeerCount() {
|
int ESP_NOW_Class::getTotalPeerCount() const {
|
||||||
if (!_esp_now_has_begun) {
|
if (!_esp_now_has_begun) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -230,7 +250,7 @@ int ESP_NOW_Class::getTotalPeerCount() {
|
||||||
return num.total_num;
|
return num.total_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ESP_NOW_Class::getEncryptedPeerCount() {
|
int ESP_NOW_Class::getEncryptedPeerCount() const {
|
||||||
if (!_esp_now_has_begun) {
|
if (!_esp_now_has_begun) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -243,16 +263,38 @@ int ESP_NOW_Class::getEncryptedPeerCount() {
|
||||||
return num.encrypt_num;
|
return num.encrypt_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ESP_NOW_Class::getMaxDataLen() const {
|
||||||
|
if (max_data_len == 0) {
|
||||||
|
log_e("ESP-NOW not initialized. Please call begin() first to get the max data length.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_data_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP_NOW_Class::getVersion() const {
|
||||||
|
if (version == 0) {
|
||||||
|
log_e("ESP-NOW not initialized. Please call begin() first to get the version.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
int ESP_NOW_Class::availableForWrite() {
|
int ESP_NOW_Class::availableForWrite() {
|
||||||
return ESP_NOW_MAX_DATA_LEN;
|
int available = getMaxDataLen();
|
||||||
|
if (available < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return available;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ESP_NOW_Class::write(const uint8_t *data, size_t len) {
|
size_t ESP_NOW_Class::write(const uint8_t *data, size_t len) {
|
||||||
if (!_esp_now_has_begun) {
|
if (!_esp_now_has_begun) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (len > ESP_NOW_MAX_DATA_LEN) {
|
if (len > max_data_len) {
|
||||||
len = ESP_NOW_MAX_DATA_LEN;
|
len = max_data_len;
|
||||||
}
|
}
|
||||||
esp_err_t result = esp_now_send(nullptr, data, len);
|
esp_err_t result = esp_now_send(nullptr, data, len);
|
||||||
if (result == ESP_OK) {
|
if (result == ESP_OK) {
|
||||||
|
|
@ -391,8 +433,15 @@ size_t ESP_NOW_Peer::send(const uint8_t *data, int len) {
|
||||||
log_e("Peer not added.");
|
log_e("Peer not added.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (len > ESP_NOW_MAX_DATA_LEN) {
|
|
||||||
len = ESP_NOW_MAX_DATA_LEN;
|
int max_data_len = ESP_NOW.getMaxDataLen();
|
||||||
|
if (max_data_len < 0) {
|
||||||
|
log_e("Error getting max data length.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > max_data_len) {
|
||||||
|
len = max_data_len;
|
||||||
}
|
}
|
||||||
esp_err_t result = esp_now_send(mac, data, len);
|
esp_err_t result = esp_now_send(mac, data, len);
|
||||||
if (result == ESP_OK) {
|
if (result == ESP_OK) {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,10 @@ public:
|
||||||
bool begin(const uint8_t *pmk = nullptr /* 16 bytes */);
|
bool begin(const uint8_t *pmk = nullptr /* 16 bytes */);
|
||||||
bool end();
|
bool end();
|
||||||
|
|
||||||
int getTotalPeerCount();
|
int getTotalPeerCount() const;
|
||||||
int getEncryptedPeerCount();
|
int getEncryptedPeerCount() const;
|
||||||
|
int getMaxDataLen() const;
|
||||||
|
int getVersion() const;
|
||||||
|
|
||||||
int availableForWrite();
|
int availableForWrite();
|
||||||
size_t write(const uint8_t *data, size_t len);
|
size_t write(const uint8_t *data, size_t len);
|
||||||
|
|
@ -34,6 +36,10 @@ public:
|
||||||
|
|
||||||
void onNewPeer(void (*cb)(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg), void *arg);
|
void onNewPeer(void (*cb)(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg), void *arg);
|
||||||
bool removePeer(ESP_NOW_Peer &peer);
|
bool removePeer(ESP_NOW_Peer &peer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t max_data_len;
|
||||||
|
uint32_t version;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ESP_NOW_Peer {
|
class ESP_NOW_Peer {
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,25 @@ bool ESP_NOW_Serial_Class::begin(unsigned long baud) {
|
||||||
//xSemaphoreTake(tx_sem, 0);
|
//xSemaphoreTake(tx_sem, 0);
|
||||||
xSemaphoreGive(tx_sem);
|
xSemaphoreGive(tx_sem);
|
||||||
}
|
}
|
||||||
setRxBufferSize(1024); //default if not preset
|
|
||||||
setTxBufferSize(1024); //default if not preset
|
size_t buf_size = 0;
|
||||||
|
if (ESP_NOW.getVersion() == 2) {
|
||||||
|
// ESP-NOW v2.0 has a larger maximum data length, so we need to increase the buffer sizes
|
||||||
|
// to hold around 3-4 packets
|
||||||
|
buf_size = setRxBufferSize(4096);
|
||||||
|
buf_size &= setTxBufferSize(4096);
|
||||||
|
} else {
|
||||||
|
// ESP-NOW v1.0 has a smaller maximum data length, so we can use the default buffer sizes
|
||||||
|
// to hold around 3-4 packets
|
||||||
|
buf_size = setRxBufferSize(1024);
|
||||||
|
buf_size &= setTxBufferSize(1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf_size == 0) {
|
||||||
|
log_e("Failed to set buffer size");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,7 +181,6 @@ void ESP_NOW_Serial_Class::onReceive(const uint8_t *data, size_t len, bool broad
|
||||||
|
|
||||||
//Print
|
//Print
|
||||||
int ESP_NOW_Serial_Class::availableForWrite() {
|
int ESP_NOW_Serial_Class::availableForWrite() {
|
||||||
//return ESP_NOW_MAX_DATA_LEN;
|
|
||||||
if (tx_ring_buf == nullptr) {
|
if (tx_ring_buf == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +205,7 @@ bool ESP_NOW_Serial_Class::checkForTxData() {
|
||||||
//do we have something that failed the last time?
|
//do we have something that failed the last time?
|
||||||
resend_count = 0;
|
resend_count = 0;
|
||||||
if (queued_buff == nullptr) {
|
if (queued_buff == nullptr) {
|
||||||
queued_buff = (uint8_t *)xRingbufferReceiveUpTo(tx_ring_buf, &queued_size, 0, ESP_NOW_MAX_DATA_LEN);
|
queued_buff = (uint8_t *)xRingbufferReceiveUpTo(tx_ring_buf, &queued_size, 0, ESP_NOW.getMaxDataLen());
|
||||||
} else {
|
} else {
|
||||||
log_d(MACSTR " : PREVIOUS", MAC2STR(addr()));
|
log_d(MACSTR " : PREVIOUS", MAC2STR(addr()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ static const char serverIndex[] PROGMEM =
|
||||||
</body>
|
</body>
|
||||||
</html>)";
|
</html>)";
|
||||||
static const char successResponse[] PROGMEM = "<META http-equiv=\"refresh\" content=\"15;URL=/\">Update Success! Rebooting...";
|
static const char successResponse[] PROGMEM = "<META http-equiv=\"refresh\" content=\"15;URL=/\">Update Success! Rebooting...";
|
||||||
|
static const char *csrfHeaders[2] = {"Origin", "Host"};
|
||||||
|
|
||||||
class HTTPUpdateServer {
|
class HTTPUpdateServer {
|
||||||
public:
|
public:
|
||||||
|
|
@ -56,6 +57,9 @@ public:
|
||||||
_username = username;
|
_username = username;
|
||||||
_password = password;
|
_password = password;
|
||||||
|
|
||||||
|
// collect headers for CSRF verification
|
||||||
|
_server->collectHeaders(csrfHeaders, 2);
|
||||||
|
|
||||||
// handler for the /update form page
|
// handler for the /update form page
|
||||||
_server->on(path.c_str(), HTTP_GET, [&]() {
|
_server->on(path.c_str(), HTTP_GET, [&]() {
|
||||||
if (_username != emptyString && _password != emptyString && !_server->authenticate(_username.c_str(), _password.c_str())) {
|
if (_username != emptyString && _password != emptyString && !_server->authenticate(_username.c_str(), _password.c_str())) {
|
||||||
|
|
@ -69,6 +73,10 @@ public:
|
||||||
path.c_str(), HTTP_POST,
|
path.c_str(), HTTP_POST,
|
||||||
[&]() {
|
[&]() {
|
||||||
if (!_authenticated) {
|
if (!_authenticated) {
|
||||||
|
if (_username == emptyString || _password == emptyString) {
|
||||||
|
_server->send(200, F("text/html"), String(F("Update error: Wrong origin received!")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
return _server->requestAuthentication();
|
return _server->requestAuthentication();
|
||||||
}
|
}
|
||||||
if (Update.hasError()) {
|
if (Update.hasError()) {
|
||||||
|
|
@ -100,6 +108,17 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String origin = _server->header(String(csrfHeaders[0]));
|
||||||
|
String host = _server->header(String(csrfHeaders[1]));
|
||||||
|
String expectedOrigin = String("http://") + host;
|
||||||
|
if (origin != expectedOrigin) {
|
||||||
|
if (_serial_output) {
|
||||||
|
Serial.printf("Wrong origin received! Expected: %s, Received: %s\n", expectedOrigin.c_str(), origin.c_str());
|
||||||
|
}
|
||||||
|
_authenticated = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_serial_output) {
|
if (_serial_output) {
|
||||||
Serial.printf("Update: %s\n", upload.filename.c_str());
|
Serial.printf("Update: %s\n", upload.filename.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ using namespace fs;
|
||||||
|
|
||||||
SDFS::SDFS(FSImplPtr impl) : FS(impl), _pdrv(0xFF) {}
|
SDFS::SDFS(FSImplPtr impl) : FS(impl), _pdrv(0xFF) {}
|
||||||
|
|
||||||
|
SDFS::~SDFS() {
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
bool SDFS::begin(uint8_t ssPin, SPIClass &spi, uint32_t frequency, const char *mountpoint, uint8_t max_files, bool format_if_empty) {
|
bool SDFS::begin(uint8_t ssPin, SPIClass &spi, uint32_t frequency, const char *mountpoint, uint8_t max_files, bool format_if_empty) {
|
||||||
if (_pdrv != 0xFF) {
|
if (_pdrv != 0xFF) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SDFS(FSImplPtr impl);
|
SDFS(FSImplPtr impl);
|
||||||
|
~SDFS();
|
||||||
bool begin(
|
bool begin(
|
||||||
uint8_t ssPin = SS, SPIClass &spi = SPI, uint32_t frequency = 4000000, const char *mountpoint = "/sd", uint8_t max_files = 5, bool format_if_empty = false
|
uint8_t ssPin = SS, SPIClass &spi = SPI, uint32_t frequency = 4000000, const char *mountpoint = "/sd", uint8_t max_files = 5, bool format_if_empty = false
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,17 @@
|
||||||
#define SSID_FORMAT "ESP32-%06lX" // 12 chars total
|
#define SSID_FORMAT "ESP32-%06lX" // 12 chars total
|
||||||
//#define PASSWORD "test123456" // generate if remarked
|
//#define PASSWORD "test123456" // generate if remarked
|
||||||
|
|
||||||
|
// Set the username and password for firmware upload
|
||||||
|
const char *authUser = "........";
|
||||||
|
const char *authPass = "........";
|
||||||
|
|
||||||
WebServer server(80);
|
WebServer server(80);
|
||||||
Ticker tkSecond;
|
Ticker tkSecond;
|
||||||
uint8_t otaDone = 0;
|
uint8_t otaDone = 0;
|
||||||
|
|
||||||
|
const char *csrfHeaders[2] = {"Origin", "Host"};
|
||||||
|
static bool authenticated = false;
|
||||||
|
|
||||||
const char *alphanum = "0123456789!@#$%^&*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
const char *alphanum = "0123456789!@#$%^&*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
String generatePass(uint8_t str_len) {
|
String generatePass(uint8_t str_len) {
|
||||||
String buff;
|
String buff;
|
||||||
|
|
@ -38,6 +45,9 @@ void apMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleUpdateEnd() {
|
void handleUpdateEnd() {
|
||||||
|
if (!authenticated) {
|
||||||
|
return server.requestAuthentication();
|
||||||
|
}
|
||||||
server.sendHeader("Connection", "close");
|
server.sendHeader("Connection", "close");
|
||||||
if (Update.hasError()) {
|
if (Update.hasError()) {
|
||||||
server.send(502, "text/plain", Update.errorString());
|
server.send(502, "text/plain", Update.errorString());
|
||||||
|
|
@ -45,6 +55,7 @@ void handleUpdateEnd() {
|
||||||
server.sendHeader("Refresh", "10");
|
server.sendHeader("Refresh", "10");
|
||||||
server.sendHeader("Location", "/");
|
server.sendHeader("Location", "/");
|
||||||
server.send(307);
|
server.send(307);
|
||||||
|
delay(500);
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -56,18 +67,34 @@ void handleUpdate() {
|
||||||
}
|
}
|
||||||
HTTPUpload &upload = server.upload();
|
HTTPUpload &upload = server.upload();
|
||||||
if (upload.status == UPLOAD_FILE_START) {
|
if (upload.status == UPLOAD_FILE_START) {
|
||||||
|
authenticated = server.authenticate(authUser, authPass);
|
||||||
|
if (!authenticated) {
|
||||||
|
Serial.println("Authentication fail!");
|
||||||
|
otaDone = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String origin = server.header(String(csrfHeaders[0]));
|
||||||
|
String host = server.header(String(csrfHeaders[1]));
|
||||||
|
String expectedOrigin = String("http://") + host;
|
||||||
|
if (origin != expectedOrigin) {
|
||||||
|
Serial.printf("Wrong origin received! Expected: %s, Received: %s\n", expectedOrigin.c_str(), origin.c_str());
|
||||||
|
authenticated = false;
|
||||||
|
otaDone = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Serial.printf("Receiving Update: %s, Size: %d\n", upload.filename.c_str(), fsize);
|
Serial.printf("Receiving Update: %s, Size: %d\n", upload.filename.c_str(), fsize);
|
||||||
if (!Update.begin(fsize)) {
|
if (!Update.begin(fsize)) {
|
||||||
otaDone = 0;
|
otaDone = 0;
|
||||||
Update.printError(Serial);
|
Update.printError(Serial);
|
||||||
}
|
}
|
||||||
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
} else if (authenticated && upload.status == UPLOAD_FILE_WRITE) {
|
||||||
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
||||||
Update.printError(Serial);
|
Update.printError(Serial);
|
||||||
} else {
|
} else {
|
||||||
otaDone = 100 * Update.progress() / Update.size();
|
otaDone = 100 * Update.progress() / Update.size();
|
||||||
}
|
}
|
||||||
} else if (upload.status == UPLOAD_FILE_END) {
|
} else if (authenticated && upload.status == UPLOAD_FILE_END) {
|
||||||
if (Update.end(true)) {
|
if (Update.end(true)) {
|
||||||
Serial.printf("Update Success: %u bytes\nRebooting...\n", upload.totalSize);
|
Serial.printf("Update Success: %u bytes\nRebooting...\n", upload.totalSize);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -78,6 +105,7 @@ void handleUpdate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void webServerInit() {
|
void webServerInit() {
|
||||||
|
server.collectHeaders(csrfHeaders, 2);
|
||||||
server.on(
|
server.on(
|
||||||
"/update", HTTP_POST,
|
"/update", HTTP_POST,
|
||||||
[]() {
|
[]() {
|
||||||
|
|
@ -92,6 +120,9 @@ void webServerInit() {
|
||||||
server.send_P(200, "image/x-icon", favicon_ico_gz, favicon_ico_gz_len);
|
server.send_P(200, "image/x-icon", favicon_ico_gz, favicon_ico_gz_len);
|
||||||
});
|
});
|
||||||
server.onNotFound([]() {
|
server.onNotFound([]() {
|
||||||
|
if (!server.authenticate(authUser, authPass)) {
|
||||||
|
return server.requestAuthentication();
|
||||||
|
}
|
||||||
server.send(200, "text/html", indexHtml);
|
server.send(200, "text/html", indexHtml);
|
||||||
});
|
});
|
||||||
server.begin();
|
server.begin();
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,17 @@ const char *host = "esp32-webupdate";
|
||||||
const char *ssid = "........";
|
const char *ssid = "........";
|
||||||
const char *password = "........";
|
const char *password = "........";
|
||||||
|
|
||||||
|
// Set the username and password for firmware upload
|
||||||
|
const char *authUser = "........";
|
||||||
|
const char *authPass = "........";
|
||||||
|
|
||||||
WebServer server(80);
|
WebServer server(80);
|
||||||
const char *serverIndex =
|
const char *serverIndex =
|
||||||
"<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>";
|
"<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>";
|
||||||
|
|
||||||
|
const char *csrfHeaders[2] = {"Origin", "Host"};
|
||||||
|
static bool authenticated = false;
|
||||||
|
|
||||||
void setup(void) {
|
void setup(void) {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
|
@ -24,37 +31,63 @@ void setup(void) {
|
||||||
WiFi.begin(ssid, password);
|
WiFi.begin(ssid, password);
|
||||||
if (WiFi.waitForConnectResult() == WL_CONNECTED) {
|
if (WiFi.waitForConnectResult() == WL_CONNECTED) {
|
||||||
MDNS.begin(host);
|
MDNS.begin(host);
|
||||||
|
server.collectHeaders(csrfHeaders, 2);
|
||||||
server.on("/", HTTP_GET, []() {
|
server.on("/", HTTP_GET, []() {
|
||||||
|
if (!server.authenticate(authUser, authPass)) {
|
||||||
|
return server.requestAuthentication();
|
||||||
|
}
|
||||||
server.sendHeader("Connection", "close");
|
server.sendHeader("Connection", "close");
|
||||||
server.send(200, "text/html", serverIndex);
|
server.send(200, "text/html", serverIndex);
|
||||||
});
|
});
|
||||||
server.on(
|
server.on(
|
||||||
"/update", HTTP_POST,
|
"/update", HTTP_POST,
|
||||||
[]() {
|
[]() {
|
||||||
|
if (!authenticated) {
|
||||||
|
return server.requestAuthentication();
|
||||||
|
}
|
||||||
server.sendHeader("Connection", "close");
|
server.sendHeader("Connection", "close");
|
||||||
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
|
if (Update.hasError()) {
|
||||||
ESP.restart();
|
server.send(200, "text/plain", "FAIL");
|
||||||
|
} else {
|
||||||
|
server.send(200, "text/plain", "Success! Rebooting...");
|
||||||
|
delay(500);
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[]() {
|
[]() {
|
||||||
HTTPUpload &upload = server.upload();
|
HTTPUpload &upload = server.upload();
|
||||||
if (upload.status == UPLOAD_FILE_START) {
|
if (upload.status == UPLOAD_FILE_START) {
|
||||||
Serial.setDebugOutput(true);
|
Serial.setDebugOutput(true);
|
||||||
|
authenticated = server.authenticate(authUser, authPass);
|
||||||
|
if (!authenticated) {
|
||||||
|
Serial.println("Authentication fail!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String origin = server.header(String(csrfHeaders[0]));
|
||||||
|
String host = server.header(String(csrfHeaders[1]));
|
||||||
|
String expectedOrigin = String("http://") + host;
|
||||||
|
if (origin != expectedOrigin) {
|
||||||
|
Serial.printf("Wrong origin received! Expected: %s, Received: %s\n", expectedOrigin.c_str(), origin.c_str());
|
||||||
|
authenticated = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Serial.printf("Update: %s\n", upload.filename.c_str());
|
Serial.printf("Update: %s\n", upload.filename.c_str());
|
||||||
if (!Update.begin()) { //start with max available size
|
if (!Update.begin()) { //start with max available size
|
||||||
Update.printError(Serial);
|
Update.printError(Serial);
|
||||||
}
|
}
|
||||||
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
} else if (authenticated && upload.status == UPLOAD_FILE_WRITE) {
|
||||||
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
||||||
Update.printError(Serial);
|
Update.printError(Serial);
|
||||||
}
|
}
|
||||||
} else if (upload.status == UPLOAD_FILE_END) {
|
} else if (authenticated && upload.status == UPLOAD_FILE_END) {
|
||||||
if (Update.end(true)) { //true to set the size to the current progress
|
if (Update.end(true)) { //true to set the size to the current progress
|
||||||
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
|
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
|
||||||
} else {
|
} else {
|
||||||
Update.printError(Serial);
|
Update.printError(Serial);
|
||||||
}
|
}
|
||||||
Serial.setDebugOutput(false);
|
Serial.setDebugOutput(false);
|
||||||
} else {
|
} else if (authenticated) {
|
||||||
Serial.printf("Update Failed Unexpectedly (likely broken connection): status=%d\n", upload.status);
|
Serial.printf("Update Failed Unexpectedly (likely broken connection): status=%d\n", upload.status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -246,29 +246,67 @@ extern "C" {
|
||||||
extern esp_err_t esp_hosted_init();
|
extern esp_err_t esp_hosted_init();
|
||||||
extern esp_err_t esp_hosted_deinit();
|
extern esp_err_t esp_hosted_deinit();
|
||||||
};
|
};
|
||||||
|
typedef struct {
|
||||||
|
uint8_t pin_clk;
|
||||||
|
uint8_t pin_cmd;
|
||||||
|
uint8_t pin_d0;
|
||||||
|
uint8_t pin_d1;
|
||||||
|
uint8_t pin_d2;
|
||||||
|
uint8_t pin_d3;
|
||||||
|
uint8_t pin_reset;
|
||||||
|
} sdio_pin_config_t;
|
||||||
|
|
||||||
static bool hosted_initialized = false;
|
static bool hosted_initialized = false;
|
||||||
|
static sdio_pin_config_t sdio_pin_config = {
|
||||||
|
#ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||||
|
.pin_clk = BOARD_SDIO_ESP_HOSTED_CLK,
|
||||||
|
.pin_cmd = BOARD_SDIO_ESP_HOSTED_CMD,
|
||||||
|
.pin_d0 = BOARD_SDIO_ESP_HOSTED_D0,
|
||||||
|
.pin_d1 = BOARD_SDIO_ESP_HOSTED_D1,
|
||||||
|
.pin_d2 = BOARD_SDIO_ESP_HOSTED_D2,
|
||||||
|
.pin_d3 = BOARD_SDIO_ESP_HOSTED_D3,
|
||||||
|
.pin_reset = BOARD_SDIO_ESP_HOSTED_RESET
|
||||||
|
#else
|
||||||
|
.pin_clk = CONFIG_ESP_SDIO_PIN_CLK,
|
||||||
|
.pin_cmd = CONFIG_ESP_SDIO_PIN_CMD,
|
||||||
|
.pin_d0 = CONFIG_ESP_SDIO_PIN_D0,
|
||||||
|
.pin_d1 = CONFIG_ESP_SDIO_PIN_D1,
|
||||||
|
.pin_d2 = CONFIG_ESP_SDIO_PIN_D2,
|
||||||
|
.pin_d3 = CONFIG_ESP_SDIO_PIN_D3,
|
||||||
|
.pin_reset = CONFIG_ESP_SDIO_GPIO_RESET_SLAVE
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
bool WiFiGenericClass::setPins(int8_t clk, int8_t cmd, int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t rst) {
|
||||||
|
if (clk < 0 || cmd < 0 || d0 < 0 || d1 < 0 || d2 < 0 || d3 < 0 || rst < 0) {
|
||||||
|
log_e("All SDIO pins must be defined");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (hosted_initialized) {
|
||||||
|
log_e("SDIO pins must be set before WiFi is initialized");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sdio_pin_config.pin_clk = clk;
|
||||||
|
sdio_pin_config.pin_cmd = cmd;
|
||||||
|
sdio_pin_config.pin_d0 = d0;
|
||||||
|
sdio_pin_config.pin_d1 = d1;
|
||||||
|
sdio_pin_config.pin_d2 = d2;
|
||||||
|
sdio_pin_config.pin_d3 = d3;
|
||||||
|
sdio_pin_config.pin_reset = rst;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool wifiHostedInit() {
|
static bool wifiHostedInit() {
|
||||||
if (!hosted_initialized) {
|
if (!hosted_initialized) {
|
||||||
hosted_initialized = true;
|
hosted_initialized = true;
|
||||||
struct esp_hosted_sdio_config conf = INIT_DEFAULT_HOST_SDIO_CONFIG();
|
struct esp_hosted_sdio_config conf = INIT_DEFAULT_HOST_SDIO_CONFIG();
|
||||||
#ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
conf.pin_clk.pin = sdio_pin_config.pin_clk;
|
||||||
conf.pin_clk.pin = BOARD_SDIO_ESP_HOSTED_CLK;
|
conf.pin_cmd.pin = sdio_pin_config.pin_cmd;
|
||||||
conf.pin_cmd.pin = BOARD_SDIO_ESP_HOSTED_CMD;
|
conf.pin_d0.pin = sdio_pin_config.pin_d0;
|
||||||
conf.pin_d0.pin = BOARD_SDIO_ESP_HOSTED_D0;
|
conf.pin_d1.pin = sdio_pin_config.pin_d1;
|
||||||
conf.pin_d1.pin = BOARD_SDIO_ESP_HOSTED_D1;
|
conf.pin_d2.pin = sdio_pin_config.pin_d2;
|
||||||
conf.pin_d2.pin = BOARD_SDIO_ESP_HOSTED_D2;
|
conf.pin_d3.pin = sdio_pin_config.pin_d3;
|
||||||
conf.pin_d3.pin = BOARD_SDIO_ESP_HOSTED_D3;
|
conf.pin_reset.pin = sdio_pin_config.pin_reset;
|
||||||
conf.pin_reset.pin = BOARD_SDIO_ESP_HOSTED_RESET;
|
|
||||||
#else
|
|
||||||
conf.pin_clk.pin = CONFIG_ESP_SDIO_PIN_CLK;
|
|
||||||
conf.pin_cmd.pin = CONFIG_ESP_SDIO_PIN_CMD;
|
|
||||||
conf.pin_d0.pin = CONFIG_ESP_SDIO_PIN_D0;
|
|
||||||
conf.pin_d1.pin = CONFIG_ESP_SDIO_PIN_D1;
|
|
||||||
conf.pin_d2.pin = CONFIG_ESP_SDIO_PIN_D2;
|
|
||||||
conf.pin_d3.pin = CONFIG_ESP_SDIO_PIN_D3;
|
|
||||||
conf.pin_reset.pin = CONFIG_ESP_SDIO_GPIO_RESET_SLAVE;
|
|
||||||
#endif
|
|
||||||
// esp_hosted_sdio_set_config() will fail on second attempt but here temporarily to not cause exception on reinit
|
// esp_hosted_sdio_set_config() will fail on second attempt but here temporarily to not cause exception on reinit
|
||||||
if (esp_hosted_sdio_set_config(&conf) != ESP_OK || esp_hosted_init() != ESP_OK) {
|
if (esp_hosted_sdio_set_config(&conf) != ESP_OK || esp_hosted_init() != ESP_OK) {
|
||||||
log_e("esp_hosted_init failed!");
|
log_e("esp_hosted_init failed!");
|
||||||
|
|
@ -279,13 +317,13 @@ static bool wifiHostedInit() {
|
||||||
}
|
}
|
||||||
// Attach pins to PeriMan here
|
// Attach pins to PeriMan here
|
||||||
// Slave chip model is CONFIG_IDF_SLAVE_TARGET
|
// Slave chip model is CONFIG_IDF_SLAVE_TARGET
|
||||||
// CONFIG_ESP_SDIO_PIN_CMD
|
// sdio_pin_config.pin_clk
|
||||||
// CONFIG_ESP_SDIO_PIN_CLK
|
// sdio_pin_config.pin_cmd
|
||||||
// CONFIG_ESP_SDIO_PIN_D0
|
// sdio_pin_config.pin_d0
|
||||||
// CONFIG_ESP_SDIO_PIN_D1
|
// sdio_pin_config.pin_d1
|
||||||
// CONFIG_ESP_SDIO_PIN_D2
|
// sdio_pin_config.pin_d2
|
||||||
// CONFIG_ESP_SDIO_PIN_D3
|
// sdio_pin_config.pin_d3
|
||||||
// CONFIG_ESP_SDIO_GPIO_RESET_SLAVE
|
// sdio_pin_config.pin_reset
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,11 @@ class WiFiGenericClass {
|
||||||
public:
|
public:
|
||||||
WiFiGenericClass();
|
WiFiGenericClass();
|
||||||
|
|
||||||
|
#if CONFIG_ESP_WIFI_REMOTE_ENABLED
|
||||||
|
// Set SDIO pins for connection to external ESP MCU
|
||||||
|
static bool setPins(int8_t clk, int8_t cmd, int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t rst);
|
||||||
|
#endif
|
||||||
|
|
||||||
wifi_event_id_t onEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
|
wifi_event_id_t onEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
|
||||||
wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
|
wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
|
||||||
wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
|
wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <algorithm>
|
||||||
#include "ZigbeeColorDimmableLight.h"
|
#include "ZigbeeColorDimmableLight.h"
|
||||||
#if CONFIG_ZB_ENABLED
|
#if CONFIG_ZB_ENABLED
|
||||||
|
|
||||||
|
|
@ -127,7 +128,8 @@ bool ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red,
|
||||||
|
|
||||||
espXyColor_t xy_color = espRgbColorToXYColor(_current_color);
|
espXyColor_t xy_color = espRgbColorToXYColor(_current_color);
|
||||||
espHsvColor_t hsv_color = espRgbColorToHsvColor(_current_color);
|
espHsvColor_t hsv_color = espRgbColorToHsvColor(_current_color);
|
||||||
uint8_t hue = (uint8_t)hsv_color.h;
|
uint8_t hue = std::min((uint8_t)hsv_color.h, (uint8_t)254); // Clamp to 0-254
|
||||||
|
uint8_t saturation = std::min((uint8_t)hsv_color.s, (uint8_t)254); // Clamp to 0-254
|
||||||
|
|
||||||
log_v("Updating light state: %d, level: %d, color: %d, %d, %d", state, level, red, green, blue);
|
log_v("Updating light state: %d, level: %d, color: %d, %d, %d", state, level, red, green, blue);
|
||||||
/* Update light clusters */
|
/* Update light clusters */
|
||||||
|
|
@ -174,7 +176,7 @@ bool ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red,
|
||||||
}
|
}
|
||||||
//set saturation
|
//set saturation
|
||||||
ret = esp_zb_zcl_set_attribute_val(
|
ret = esp_zb_zcl_set_attribute_val(
|
||||||
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &hsv_color.s, false
|
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &saturation, false
|
||||||
);
|
);
|
||||||
if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
|
if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
|
||||||
log_e("Failed to set light saturation: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
|
log_e("Failed to set light saturation: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
|
||||||
|
|
|
||||||
16
platform.txt
16
platform.txt
|
|
@ -339,3 +339,19 @@ tools.dfu-util.cmd=dfu-util
|
||||||
tools.dfu-util.upload.params.verbose=-d
|
tools.dfu-util.upload.params.verbose=-d
|
||||||
tools.dfu-util.upload.params.quiet=
|
tools.dfu-util.upload.params.quiet=
|
||||||
tools.dfu-util.upload.pattern="{path}/{cmd}" --device {vid.0}:{pid.0} -D "{build.path}/{build.project_name}.bin" -Q
|
tools.dfu-util.upload.pattern="{path}/{cmd}" --device {vid.0}:{pid.0} -D "{build.path}/{build.project_name}.bin" -Q
|
||||||
|
|
||||||
|
## --------------------------------------------------------------------------
|
||||||
|
## esptool_py_app_only is used to upload only the application image
|
||||||
|
## It won't upload the bootloader or any other binary except for the main application
|
||||||
|
## --------------------------------------------------------------------------
|
||||||
|
tools.esptool_py_app_only.path={runtime.tools.esptool_py.path}
|
||||||
|
tools.esptool_py_app_only.cmd=esptool
|
||||||
|
tools.esptool_py_app_only.cmd.windows=esptool.exe
|
||||||
|
|
||||||
|
tools.esptool_py_app_only.upload.protocol=serial
|
||||||
|
tools.esptool_py_app_only.upload.params.verbose=
|
||||||
|
tools.esptool_py_app_only.upload.params.quiet=
|
||||||
|
|
||||||
|
tools.esptool_py_app_only.upload.pattern_args=--chip {build.mcu} --port "{serial.port}" --baud {upload.speed} {upload.flags} --before default_reset --after hard_reset write_flash --flash_mode {build.flash_mode} --flash_freq {build.flash_freq} --flash_size {build.flash_size} {build.flash_offset} "{build.path}/{build.project_name}.bin" {upload.extra_flags}
|
||||||
|
|
||||||
|
tools.esptool_py_app_only.upload.pattern="{path}/{cmd}" {tools.esptool_py_app_only.upload.pattern_args}
|
||||||
|
|
|
||||||
|
|
@ -220,8 +220,14 @@ env.Append(
|
||||||
),
|
),
|
||||||
get_bootloader_image(variants_dir),
|
get_bootloader_image(variants_dir),
|
||||||
),
|
),
|
||||||
("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")),
|
(
|
||||||
("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")),
|
board_config.get("upload.arduino.partitions_bin", "0x8000"),
|
||||||
|
join(env.subst("$BUILD_DIR"), "partitions.bin"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
board_config.get("upload.arduino.boot_app0", "0xe000"),
|
||||||
|
join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin"),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
+ [(offset, join(FRAMEWORK_DIR, img)) for offset, img in board_config.get("upload.arduino.flash_extra_images", [])],
|
+ [(offset, join(FRAMEWORK_DIR, img)) for offset, img in board_config.get("upload.arduino.flash_extra_images", [])],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
79
variants/fed4/pins_arduino.h
Normal file
79
variants/fed4/pins_arduino.h
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
#ifndef Pins_Arduino_h
|
||||||
|
#define Pins_Arduino_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
|
#define USB_VID 0x303A
|
||||||
|
#define USB_PID 0x82E5
|
||||||
|
#define USB_MANUFACTURER "Smart Bee Designs LLC"
|
||||||
|
#define USB_PRODUCT "FED4"
|
||||||
|
#define USB_SERIAL ""
|
||||||
|
|
||||||
|
static const uint8_t TX = 43;
|
||||||
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
static const uint8_t SDA = 8;
|
||||||
|
static const uint8_t SCL = 9;
|
||||||
|
static const uint8_t SDA2 = 20;
|
||||||
|
static const uint8_t SCL2 = 19;
|
||||||
|
|
||||||
|
static const uint8_t SS = 47;
|
||||||
|
static const uint8_t MOSI = 11;
|
||||||
|
static const uint8_t MISO = 13;
|
||||||
|
static const uint8_t SCK = 12;
|
||||||
|
static const uint8_t SDCS = 10; // sd cs pin
|
||||||
|
static const uint8_t DSCS = 14; //display cs pin
|
||||||
|
|
||||||
|
static const uint8_t A1 = 1;
|
||||||
|
static const uint8_t A2 = 2;
|
||||||
|
static const uint8_t A3 = 3;
|
||||||
|
static const uint8_t A4 = 4;
|
||||||
|
static const uint8_t A5 = 5;
|
||||||
|
static const uint8_t A6 = 6;
|
||||||
|
|
||||||
|
static const uint8_t D1 = 1;
|
||||||
|
static const uint8_t D2 = 2;
|
||||||
|
static const uint8_t D3 = 3;
|
||||||
|
static const uint8_t D4 = 4;
|
||||||
|
static const uint8_t D5 = 5;
|
||||||
|
static const uint8_t D6 = 6;
|
||||||
|
static const uint8_t D8 = 8;
|
||||||
|
static const uint8_t D13 = 13;
|
||||||
|
static const uint8_t D9 = 9;
|
||||||
|
|
||||||
|
static const uint8_t T1 = 1;
|
||||||
|
static const uint8_t T2 = 2;
|
||||||
|
static const uint8_t T3 = 3;
|
||||||
|
static const uint8_t T4 = 4;
|
||||||
|
static const uint8_t T5 = 5;
|
||||||
|
static const uint8_t T6 = 6;
|
||||||
|
|
||||||
|
static const uint8_t BOOT_BTN = 0;
|
||||||
|
static const uint8_t VBAT_VOLTAGE = 7;
|
||||||
|
static const uint8_t LDO2 = 47;
|
||||||
|
static const uint8_t STATUS_RGB = 35;
|
||||||
|
static const uint8_t RGB_STRIP = 36;
|
||||||
|
static const uint8_t INTERRUPT_PIN = 18;
|
||||||
|
static const uint8_t USER_BTN_1 = 14;
|
||||||
|
static const uint8_t USER_BTN_2 = 39;
|
||||||
|
static const uint8_t USER_BTN_3 = 40;
|
||||||
|
static const uint8_t AMP_DIN = 39;
|
||||||
|
static const uint8_t AMP_SD = 42;
|
||||||
|
static const uint8_t AMP_BCLK = 45;
|
||||||
|
static const uint8_t AMP_LRCLK = 48;
|
||||||
|
static const uint8_t MSBY = 15;
|
||||||
|
static const uint8_t TRRS_1 = 4;
|
||||||
|
static const uint8_t TRRS_2 = 2;
|
||||||
|
static const uint8_t TRRS_3 = 3;
|
||||||
|
|
||||||
|
#define PIN_RGB_LED STATUS_RGB
|
||||||
|
// BUILTIN_LED can be used in new Arduino API digitalWrite() like in Blink.ino
|
||||||
|
static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT + PIN_RGB_LED;
|
||||||
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
|
#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN
|
||||||
|
// RGB_BUILTIN and RGB_BRIGHTNESS can be used in new Arduino API rgbLedWrite()
|
||||||
|
#define RGB_BUILTIN LED_BUILTIN
|
||||||
|
#define RGB_BRIGHTNESS 64
|
||||||
|
|
||||||
|
#endif /* Pins_Arduino_h */
|
||||||
14
variants/kodedot/custom_ota_override.cpp
Normal file
14
variants/kodedot/custom_ota_override.cpp
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// custom_ota_override.cpp
|
||||||
|
// This function overrides the weak definition of `verifyRollbackLater()` in the kode dot board.
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
// Declare the weak function symbol to override it
|
||||||
|
bool verifyRollbackLater() __attribute__((weak));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom implementation of verifyRollbackLater()
|
||||||
|
// Returning `true` prevents the OTA image from being automatically marked as valid.
|
||||||
|
// This ensures that the system will roll back to the previous image unless it is explicitly validated later.
|
||||||
|
bool verifyRollbackLater() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
7
variants/kodedot/kodedot_partitions.csv
Normal file
7
variants/kodedot/kodedot_partitions.csv
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
otadata, data, ota, 0x10000, 0x2000,
|
||||||
|
ota_0, app, ota_0, 0x20000, 0x3E0000,
|
||||||
|
ota_1, app, ota_1, 0x400000, 0x800000,
|
||||||
|
storage, data, spiffs, 0xC00000, 0x400000,
|
||||||
|
107
variants/kodedot/pins_arduino.h
Normal file
107
variants/kodedot/pins_arduino.h
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
────────────────────────────────────────────────────────────────────────
|
||||||
|
KodeDot – ESP32-S3R8 Variant
|
||||||
|
Pin definition file for the Arduino-ESP32 core
|
||||||
|
────────────────────────────────────────────────────────────────────────
|
||||||
|
* External 2 × 10 connector → simple aliases PIN1 … PIN20
|
||||||
|
* On-board QSPI LCD 410×502 @40 MHz (SPI3_HOST)
|
||||||
|
* micro-SD on SPI2_HOST
|
||||||
|
* Dual-I²C: external (GPIO37/36) + internal-sensors (GPIO48/47)
|
||||||
|
* USB VID/PID 0x303A:0x1001
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Pins_Arduino_h
|
||||||
|
#define Pins_Arduino_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/*──────────────── USB device descriptor ────────────────*/
|
||||||
|
#define USB_VID 0x303A // Espressif Systems VID
|
||||||
|
#define USB_PID 0x1001 // Product ID: KodeDot-S3
|
||||||
|
|
||||||
|
/*──────────────── UART0 (Arduino Serial) ────────────────*/
|
||||||
|
static const uint8_t TX = 43; // U0TXD – PIN16 on the 2×10 header
|
||||||
|
static const uint8_t RX = 44; // U0RXD – PIN18 on the 2×10 header
|
||||||
|
|
||||||
|
/*──────────────── I²C buses ─────────────────────────────*/
|
||||||
|
/* External expansion bus → header pins 11/13 */
|
||||||
|
static const uint8_t SCL = 37; // GPIO37 – PIN12
|
||||||
|
static const uint8_t SDA = 36; // GPIO36 – PIN14
|
||||||
|
|
||||||
|
/* Internal sensor/touch bus (not on header) */
|
||||||
|
#define INT_I2C_SCL 47 // GPIO47
|
||||||
|
#define INT_I2C_SDA 48 // GPIO48
|
||||||
|
|
||||||
|
/*──────────────── SPI2 – micro-SD ───────────────────────*/
|
||||||
|
static const uint8_t SS = 15; // SD_CS
|
||||||
|
static const uint8_t MOSI = 16; // SD_MOSI
|
||||||
|
static const uint8_t MISO = 18; // SD_MISO
|
||||||
|
static const uint8_t SCK = 17; // SD_CLK
|
||||||
|
#define BOARD_HAS_SD_SPI
|
||||||
|
#define SD_CS SS
|
||||||
|
|
||||||
|
/*──────────────── QSPI LCD (SPI3_HOST) ─────────────────–
|
||||||
|
* Controller: ST7789 / 4-line SPI (no D/C pin)
|
||||||
|
* Resolution: 410×502 px, 16 bpp, RGB color-space
|
||||||
|
* Clock: 40 MHz
|
||||||
|
*/
|
||||||
|
#define BOARD_HAS_SPI_LCD
|
||||||
|
#define LCD_MODEL ST7789
|
||||||
|
#define LCD_WIDTH 410
|
||||||
|
#define LCD_HEIGHT 502
|
||||||
|
|
||||||
|
#define LCD_HOST SPI3_HOST
|
||||||
|
#define LCD_SCK 35 // GPIO35 • QSPI_CLK
|
||||||
|
#define LCD_MOSI 33 // GPIO33 • QSPI_IO0 (D0)
|
||||||
|
#define LCD_IO1 34 // GPIO34 • QSPI_IO1 (D1)
|
||||||
|
#define LCD_IO2 37 // GPIO37 • QSPI_IO2 (D2)
|
||||||
|
#define LCD_IO3 36 // GPIO36 • QSPI_IO3 (D3)
|
||||||
|
#define LCD_CS 10 // GPIO10
|
||||||
|
#define LCD_RST 9 // GPIO09
|
||||||
|
#define LCD_DC -1 // not used in 4-line SPI
|
||||||
|
/* Optional: back-light enable shares the NeoPixel pin */
|
||||||
|
#define LCD_BL 5 // GPIO05 (same as NEOPIXEL)
|
||||||
|
|
||||||
|
/*──────────────── Analog / Touch pads ────────────────*/
|
||||||
|
static const uint8_t A0 = 11; // PIN4 – GPIO11 / TOUCH11 / ADC2_CH0
|
||||||
|
static const uint8_t A1 = 12; // PIN6 – GPIO12 / TOUCH12 / ADC2_CH1
|
||||||
|
static const uint8_t A2 = 13; // PIN8 – GPIO13 / TOUCH13 / ADC2_CH2
|
||||||
|
static const uint8_t A3 = 14; // PIN10 – GPIO14 / TOUCH14 / ADC2_CH3
|
||||||
|
static const uint8_t T0 = A0, T1 = A1, T2 = A2, T3 = A3;
|
||||||
|
|
||||||
|
/*──────────────── On-board controls & indicator ─────────*/
|
||||||
|
#define BUTTON_TOP 0 // GPIO00 – BOOT • active-LOW
|
||||||
|
#define BUTTON_BOTTOM 6 // GPIO06 • active-LOW
|
||||||
|
#define NEOPIXEL_PIN 5 // GPIO05 – WS2812
|
||||||
|
#define LED_BUILTIN NEOPIXEL_PIN
|
||||||
|
|
||||||
|
/*──────────────── JTAG (also on connector) ──────────────*/
|
||||||
|
#define MTCK 39 // PIN11 – GPIO39
|
||||||
|
#define MTDO 40 // PIN13 – GPIO40
|
||||||
|
#define MTDI 41 // PIN15 – GPIO41
|
||||||
|
#define MTMS 42 // PIN17 – GPIO42
|
||||||
|
|
||||||
|
/*──────────────── 2×10 header: simple aliases ───────────
|
||||||
|
NOTE: power pins (1 = 5 V, 2 = 3 V3, 19/20 = GND) are **not**
|
||||||
|
exposed as GPIO numbers – they remain undefined here. */
|
||||||
|
#define PIN3 1 // GPIO01 / TOUCH1 / ADC1_CH0
|
||||||
|
#define PIN4 11 // GPIO11 / TOUCH11 / ADC2_CH0
|
||||||
|
#define PIN5 2 // GPIO02 / TOUCH2 / ADC1_CH1
|
||||||
|
#define PIN6 12 // GPIO12 / TOUCH12 / ADC2_CH1
|
||||||
|
#define PIN7 3 // GPIO03 / TOUCH3 / ADC1_CH2
|
||||||
|
#define PIN8 13 // GPIO13 / TOUCH13 / ADC2_CH2
|
||||||
|
#define PIN9 4 // GPIO04 / TOUCH4 / ADC1_CH3
|
||||||
|
#define PIN10 14 // GPIO14 / TOUCH14 / ADC2_CH3
|
||||||
|
#define PIN11 39 // MTCK
|
||||||
|
#define PIN12 37 // SCL (external I²C)
|
||||||
|
#define PIN13 40 // MTDO
|
||||||
|
#define PIN14 36 // SDA (external I²C)
|
||||||
|
#define PIN15 41 // MTDI
|
||||||
|
#define PIN16 43 // TX (U0TXD)
|
||||||
|
#define PIN17 42 // MTMS
|
||||||
|
#define PIN18 44 // RX (U0RXD)
|
||||||
|
/* PIN1, PIN2, PIN19, PIN20 are power/ground and deliberately
|
||||||
|
left undefined – they are **not** usable as GPIO. */
|
||||||
|
|
||||||
|
#endif /* Pins_Arduino_h */
|
||||||
50
variants/rakwireless_rak3112/pins_arduino.h
Normal file
50
variants/rakwireless_rak3112/pins_arduino.h
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef Pins_Arduino_h
|
||||||
|
#define Pins_Arduino_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Reference: RAK3112 Module Datasheet
|
||||||
|
// https://docs.rakwireless.com/product-categories/wisduo/rak3112-module/datasheet/
|
||||||
|
|
||||||
|
// Note:GPIO33,GPIO34,GPIO35.GPIO36,GPIO37 is not available in the 8MB and 16MB Octal PSRAM version
|
||||||
|
|
||||||
|
#define USB_VID 0x303a
|
||||||
|
#define USB_PID 0x1001
|
||||||
|
|
||||||
|
#define LED_GREEN 46
|
||||||
|
#define LED_BLUE 45
|
||||||
|
|
||||||
|
static const uint8_t LED_BUILTIN = LED_GREEN;
|
||||||
|
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||||
|
#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN
|
||||||
|
|
||||||
|
static const uint8_t BAT_VOLT = 21;
|
||||||
|
|
||||||
|
static const uint8_t TX = 43;
|
||||||
|
static const uint8_t RX = 44;
|
||||||
|
|
||||||
|
static const uint8_t SDA = 9;
|
||||||
|
static const uint8_t SCL = 40;
|
||||||
|
|
||||||
|
#define WIRE1_PIN_DEFINED
|
||||||
|
static const uint8_t SDA1 = 17;
|
||||||
|
static const uint8_t SCL1 = 18;
|
||||||
|
|
||||||
|
static const uint8_t SS = 12;
|
||||||
|
static const uint8_t MOSI = 11;
|
||||||
|
static const uint8_t MISO = 10;
|
||||||
|
static const uint8_t SCK = 13;
|
||||||
|
|
||||||
|
#define LORA_ANT_SWITCH 4 // Antenna switch power control pin
|
||||||
|
|
||||||
|
#define LORA_SCK 5 // SX1262 SCK
|
||||||
|
#define LORA_MISO 3 // SX1262 MISO
|
||||||
|
#define LORA_MOSI 6 // SX1262 MOSI
|
||||||
|
#define LORA_CS 7 // SX1262 CS
|
||||||
|
#define LORA_RST 8 // SX1262 RST
|
||||||
|
|
||||||
|
#define LORA_DIO1 47 //SX1262 DIO1
|
||||||
|
#define LORA_BUSY 48
|
||||||
|
#define LORA_IRQ LORA_DIO1
|
||||||
|
|
||||||
|
#endif /* Pins_Arduino_h */
|
||||||
BIN
variants/sensebox_mcu_esp32s2/APOTA.bin
Normal file
BIN
variants/sensebox_mcu_esp32s2/APOTA.bin
Normal file
Binary file not shown.
283
variants/sensebox_mcu_esp32s2/APOTA.ino
Normal file
283
variants/sensebox_mcu_esp32s2/APOTA.ino
Normal file
|
|
@ -0,0 +1,283 @@
|
||||||
|
#define DISPLAY_ENABLED
|
||||||
|
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <WebServer.h>
|
||||||
|
#include <ESPmDNS.h>
|
||||||
|
#include <WiFiAP.h>
|
||||||
|
#include <Update.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#ifdef DISPLAY_ENABLED
|
||||||
|
#define SCREEN_WIDTH 128
|
||||||
|
#define SCREEN_HEIGHT 64
|
||||||
|
#define OLED_RESET -1
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <Adafruit_SSD1306.h>
|
||||||
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||||
|
#include <Adafruit_NeoPixel.h>
|
||||||
|
Adafruit_NeoPixel rgb_led_1 = Adafruit_NeoPixel(1, 1, NEO_GRB + NEO_KHZ800);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#include "esp_partition.h"
|
||||||
|
#include "esp_ota_ops.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
|
||||||
|
String ssid;
|
||||||
|
uint8_t mac[6];
|
||||||
|
|
||||||
|
// Create an instance of the server
|
||||||
|
WebServer server(80);
|
||||||
|
bool displayEnabled;
|
||||||
|
|
||||||
|
const int BUTTON_PIN = 0; // GPIO for the button
|
||||||
|
volatile unsigned long lastPressTime = 0; // Time of last button press
|
||||||
|
volatile bool doublePressDetected = false; // Flag for double press
|
||||||
|
const unsigned long doublePressInterval = 500; // Max. time (in ms) between two presses for double press
|
||||||
|
volatile int pressCount = 0; // Counts the button presses
|
||||||
|
|
||||||
|
const unsigned char epd_bitmap_wifi[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0xff, 0x00, 0x00,
|
||||||
|
0x00, 0x3f, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x7c, 0x00, 0x03, 0xe0, 0x00, 0x00, 0xf0, 0x00, 0x01, 0xf0, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x78, 0x00,
|
||||||
|
0x03, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x07, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x7f, 0xe0, 0x0e, 0x00,
|
||||||
|
0x0c, 0x01, 0xff, 0xf0, 0x06, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x02, 0x00, 0x00, 0x0f, 0x80, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x0f, 0x00, 0x00,
|
||||||
|
0x00, 0x1c, 0x00, 0x07, 0x80, 0x00, 0x00, 0x38, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x70, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x70, 0x00, 0x00, 0xc0, 0x00,
|
||||||
|
0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x78, 0x00, 0x00, 0x00, 0x03, 0x80, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
// 'checkmark', 44x44px
|
||||||
|
const unsigned char epd_bitmap_checkmark[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x00,
|
||||||
|
0x00, 0x0f, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x07, 0xc7, 0x80, 0x00, 0x00, 0x00, 0x03, 0xef, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
void IRAM_ATTR handleButtonPress() {
|
||||||
|
unsigned long currentTime = millis(); // Get current time
|
||||||
|
|
||||||
|
// Debounce: If the current press is too close to the last one, ignore it
|
||||||
|
if (currentTime - lastPressTime > 50) {
|
||||||
|
pressCount++; // Count the button press
|
||||||
|
|
||||||
|
// Check if this is the second press within the double-press interval
|
||||||
|
if (pressCount == 2 && (currentTime - lastPressTime <= doublePressInterval)) {
|
||||||
|
doublePressDetected = true; // Double press detected
|
||||||
|
pressCount = 0; // Reset counter
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPressTime = currentTime; // Update the time of the last press
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to switch the boot partition to OTA1
|
||||||
|
void setBootPartitionToOTA0() {
|
||||||
|
const esp_partition_t *ota0_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL);
|
||||||
|
|
||||||
|
if (ota0_partition) {
|
||||||
|
// Set OTA1 as new boot partition
|
||||||
|
esp_ota_set_boot_partition(ota0_partition);
|
||||||
|
Serial.println("Boot partition changed to OTA0. Restarting...");
|
||||||
|
|
||||||
|
// Restart to boot from the new partition
|
||||||
|
esp_restart();
|
||||||
|
} else {
|
||||||
|
Serial.println("OTA1 partition not found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupDisplay() {
|
||||||
|
displayEnabled = display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
|
||||||
|
if (displayEnabled) {
|
||||||
|
display.display();
|
||||||
|
delay(100);
|
||||||
|
display.clearDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayStatusBar(int progress) {
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setCursor(24, 8);
|
||||||
|
display.println("Sketch wird");
|
||||||
|
display.setCursor(22, 22);
|
||||||
|
display.println("hochgeladen!");
|
||||||
|
|
||||||
|
display.fillRect(0, SCREEN_HEIGHT - 24, SCREEN_WIDTH - 4, 8, BLACK); // Clear status bar area
|
||||||
|
display.drawRect(0, SCREEN_HEIGHT - 24, SCREEN_WIDTH - 4, 8, WHITE); // Draw border
|
||||||
|
int filledWidth = (progress * SCREEN_WIDTH - 4) / 100; // Calculate progress width
|
||||||
|
display.fillRect(1, SCREEN_HEIGHT - 23, filledWidth - 4, 6, WHITE); // Fill progress bar
|
||||||
|
|
||||||
|
display.setCursor((SCREEN_WIDTH / 2) - 12, SCREEN_HEIGHT - 10);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
display.print(progress);
|
||||||
|
display.println(" %");
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayWelcomeScreen() {
|
||||||
|
display.clearDisplay();
|
||||||
|
|
||||||
|
// Draw WiFi symbol
|
||||||
|
display.drawBitmap(0, 12, epd_bitmap_wifi, 44, 44, WHITE);
|
||||||
|
|
||||||
|
// Display SSID text
|
||||||
|
display.setCursor(40, 13);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
display.println("Verbinde dich"); // "Connect"
|
||||||
|
display.setCursor(60, 27);
|
||||||
|
display.println("mit:"); // "with"
|
||||||
|
|
||||||
|
// Display SSID
|
||||||
|
display.setCursor(40, 43);
|
||||||
|
display.setTextSize(1); // Larger text for SSID
|
||||||
|
display.print(ssid);
|
||||||
|
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void displaySuccessScreen() {
|
||||||
|
display.clearDisplay();
|
||||||
|
|
||||||
|
// Draw WiFi symbol
|
||||||
|
display.drawBitmap(0, 12, epd_bitmap_checkmark, 44, 44, WHITE);
|
||||||
|
|
||||||
|
// Display SSID text
|
||||||
|
display.setCursor(48, 22);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
display.println("Erfolgreich"); // "Successfully"
|
||||||
|
display.setCursor(48, 36);
|
||||||
|
display.println("hochgeladen!"); // "uploaded!"
|
||||||
|
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wipeDisplay() {
|
||||||
|
display.clearDisplay();
|
||||||
|
display.println("");
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupWiFi() {
|
||||||
|
WiFi.macAddress(mac);
|
||||||
|
char macLastFour[5];
|
||||||
|
snprintf(macLastFour, sizeof(macLastFour), "%02X%02X", mac[4], mac[5]);
|
||||||
|
ssid = "senseBox:" + String(macLastFour);
|
||||||
|
|
||||||
|
// Define the IP address, gateway, and subnet mask
|
||||||
|
IPAddress local_IP(192, 168, 1, 1); // The new IP address
|
||||||
|
IPAddress gateway(192, 168, 1, 1); // Gateway address (can be the same as the AP's IP)
|
||||||
|
IPAddress subnet(255, 255, 255, 0); // Subnet mask
|
||||||
|
|
||||||
|
// Set the IP address, gateway, and subnet mask of the access point
|
||||||
|
WiFi.softAPConfig(local_IP, gateway, subnet);
|
||||||
|
|
||||||
|
// Start the access point
|
||||||
|
WiFi.softAP(ssid.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupOTA() {
|
||||||
|
// Handle updating process
|
||||||
|
server.on(
|
||||||
|
"/sketch", HTTP_POST,
|
||||||
|
[]() {
|
||||||
|
server.sendHeader("Connection", "close");
|
||||||
|
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
|
||||||
|
ESP.restart();
|
||||||
|
},
|
||||||
|
[]() {
|
||||||
|
HTTPUpload &upload = server.upload();
|
||||||
|
|
||||||
|
if (upload.status == UPLOAD_FILE_START) {
|
||||||
|
Serial.setDebugOutput(true);
|
||||||
|
size_t fsize = UPDATE_SIZE_UNKNOWN;
|
||||||
|
if (server.clientContentLength() > 0) {
|
||||||
|
fsize = server.clientContentLength();
|
||||||
|
}
|
||||||
|
Serial.printf("Receiving Update: %s, Size: %d\n", upload.filename.c_str(), fsize);
|
||||||
|
|
||||||
|
Serial.printf("Update: %s\n", upload.filename.c_str());
|
||||||
|
if (!Update.begin(fsize)) { //start with max available size
|
||||||
|
Update.printError(Serial);
|
||||||
|
}
|
||||||
|
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
||||||
|
/* flashing firmware to ESP*/
|
||||||
|
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
||||||
|
Update.printError(Serial);
|
||||||
|
} else {
|
||||||
|
int progress = (Update.progress() * 100) / Update.size();
|
||||||
|
displayStatusBar(progress); // Update progress on status bar
|
||||||
|
}
|
||||||
|
} else if (upload.status == UPLOAD_FILE_END) {
|
||||||
|
if (Update.end(true)) { //true to set the size to the current progress
|
||||||
|
displaySuccessScreen();
|
||||||
|
delay(3000);
|
||||||
|
wipeDisplay();
|
||||||
|
} else {
|
||||||
|
Update.printError(Serial);
|
||||||
|
}
|
||||||
|
Serial.setDebugOutput(false);
|
||||||
|
}
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Start Serial communication
|
||||||
|
Serial.begin(115200);
|
||||||
|
rgb_led_1.begin();
|
||||||
|
rgb_led_1.setBrightness(30);
|
||||||
|
rgb_led_1.setPixelColor(0, rgb_led_1.Color(51, 51, 255));
|
||||||
|
rgb_led_1.show();
|
||||||
|
|
||||||
|
// Configure button pin as input
|
||||||
|
pinMode(BUTTON_PIN, INPUT_PULLUP);
|
||||||
|
|
||||||
|
// Interrupt for the button
|
||||||
|
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleButtonPress, FALLING);
|
||||||
|
|
||||||
|
#ifdef DISPLAY_ENABLED
|
||||||
|
setupDisplay();
|
||||||
|
#endif
|
||||||
|
setupWiFi();
|
||||||
|
// Set the ESP32 as an access point
|
||||||
|
setupOTA();
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Handle client requests
|
||||||
|
server.handleClient();
|
||||||
|
|
||||||
|
#ifdef DISPLAY_ENABLED
|
||||||
|
displayWelcomeScreen();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (doublePressDetected) {
|
||||||
|
Serial.println("Doppeldruck erkannt!"); // "Double press detected!"
|
||||||
|
setBootPartitionToOTA0();
|
||||||
|
#ifdef DISPLAY_ENABLED
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(WHITE, BLACK);
|
||||||
|
display.println("");
|
||||||
|
display.display();
|
||||||
|
delay(50);
|
||||||
|
#endif
|
||||||
|
// Restart to boot from the new partition
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,29 +1,10 @@
|
||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021 Ha Thach (tinyusb.org) 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 "esp32-hal-gpio.h"
|
#include "esp32-hal-gpio.h"
|
||||||
#include "pins_arduino.h"
|
#include "pins_arduino.h"
|
||||||
|
#include "esp_partition.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_ota_ops.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include <esp_chip_info.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
|
@ -41,12 +22,51 @@ void initVariant(void) {
|
||||||
pinMode(PIN_XB1_ENABLE, OUTPUT);
|
pinMode(PIN_XB1_ENABLE, OUTPUT);
|
||||||
digitalWrite(PIN_XB1_ENABLE, LOW);
|
digitalWrite(PIN_XB1_ENABLE, LOW);
|
||||||
|
|
||||||
//enable UART by default
|
//enable UART only for chip without PSRAM
|
||||||
pinMode(PIN_UART_ENABLE, OUTPUT);
|
esp_chip_info_t chip_info;
|
||||||
digitalWrite(PIN_UART_ENABLE, LOW);
|
esp_chip_info(&chip_info);
|
||||||
|
if (chip_info.revision <= 0) {
|
||||||
|
pinMode(PIN_UART_ENABLE, OUTPUT);
|
||||||
|
digitalWrite(PIN_UART_ENABLE, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
//enable PD-Sensor by default
|
//enable PD-Sensor by default
|
||||||
pinMode(PD_ENABLE, OUTPUT);
|
pinMode(PD_ENABLE, OUTPUT);
|
||||||
digitalWrite(PD_ENABLE, HIGH);
|
digitalWrite(PD_ENABLE, HIGH);
|
||||||
|
|
||||||
|
// define button pin
|
||||||
|
const int PIN_BUTTON = 0;
|
||||||
|
pinMode(PIN_BUTTON, INPUT_PULLUP);
|
||||||
|
|
||||||
|
// keep button pressed
|
||||||
|
unsigned long pressStartTime = 0;
|
||||||
|
bool buttonPressed = false;
|
||||||
|
|
||||||
|
// Wait 5 seconds for the button to be pressed
|
||||||
|
unsigned long startTime = millis();
|
||||||
|
|
||||||
|
// Check if button is pressed
|
||||||
|
while (millis() - startTime < 5000) {
|
||||||
|
if (digitalRead(PIN_BUTTON) == LOW) {
|
||||||
|
if (!buttonPressed) {
|
||||||
|
// The button was pressed
|
||||||
|
buttonPressed = true;
|
||||||
|
}
|
||||||
|
} else if (buttonPressed) {
|
||||||
|
// When the button is pressed and then released, boot into the OTA1 partition
|
||||||
|
const esp_partition_t *ota1_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL);
|
||||||
|
|
||||||
|
if (ota1_partition) {
|
||||||
|
esp_err_t err = esp_ota_set_boot_partition(ota1_partition);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
esp_restart(); // restart, to boot OTA1 partition
|
||||||
|
} else {
|
||||||
|
ESP_LOGE("OTA", "Error setting OTA1 partition: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Abort after releasing the button
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue