diff --git a/.github/scripts/install-arduino-core-esp32.sh b/.github/scripts/install-arduino-core-esp32.sh index 8584da5b6e2..cc685711e15 100755 --- a/.github/scripts/install-arduino-core-esp32.sh +++ b/.github/scripts/install-arduino-core-esp32.sh @@ -20,7 +20,7 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then ln -s $GITHUB_WORKSPACE esp32 else echo "Cloning Core Repository..." - git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1 + git clone https://github.com/tasmota/arduino-esp32.git esp32 > /dev/null 2>&1 fi #echo "Updating Submodules ..." diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh index 5292c5d8caf..71c1a55b297 100755 --- a/.github/scripts/install-platformio-esp32.sh +++ b/.github/scripts/install-platformio-esp32.sh @@ -1,7 +1,7 @@ #!/bin/bash export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32" -PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master" +PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git" TOOLCHAIN_VERSION="8.4.0+2021r2-patch3" ESPTOOLPY_VERSION="~1.30100.0" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c270418bfd8..34d3564c4a8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,7 +15,7 @@ jobs: if: | github.event.workflow_run.event == 'pull_request' && (github.event.workflow_run.conclusion == 'success' || - (github.event.workflow_run.conclusion == 'failure') + github.event.workflow_run.conclusion == 'failure') steps: - name: Download and Extract Artifacts env: diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b0300fc743..e5819d55a25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,11 +90,6 @@ set(LIBRARY_SRCS libraries/I2S/src/I2S.cpp libraries/NetBIOS/src/NetBIOS.cpp libraries/Preferences/src/Preferences.cpp - libraries/RainMaker/src/RMaker.cpp - libraries/RainMaker/src/RMakerNode.cpp - libraries/RainMaker/src/RMakerParam.cpp - libraries/RainMaker/src/RMakerDevice.cpp - libraries/RainMaker/src/RMakerType.cpp libraries/SD_MMC/src/SD_MMC.cpp libraries/SD/src/SD.cpp libraries/SD/src/sd_diskio.cpp @@ -184,7 +179,6 @@ set(includedirs libraries/I2S/src libraries/NetBIOS/src libraries/Preferences/src - libraries/RainMaker/src libraries/SD_MMC/src libraries/SD/src libraries/SimpleBLE/src @@ -239,10 +233,6 @@ endfunction() maybe_add_component(esp-dsp) -if(CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK) - maybe_add_component(esp_rainmaker) - maybe_add_component(qrcode) -endif() if(IDF_TARGET MATCHES "esp32s2|esp32s3" AND CONFIG_TINYUSB_ENABLED) maybe_add_component(arduino_tinyusb) endif() diff --git a/boards.txt b/boards.txt index 5104f80101d..a19d9e0a07f 100644 --- a/boards.txt +++ b/boards.txt @@ -184,6 +184,9 @@ esp32s3.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 esp32s3.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9MB FATFS) esp32s3.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB esp32s3.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +esp32s3.menu.PartitionScheme.rainmaker=RainMaker +esp32s3.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +esp32s3.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 esp32s3.menu.CPUFreq.240=240MHz (WiFi) esp32s3.menu.CPUFreq.240.build.f_cpu=240000000L @@ -304,6 +307,9 @@ esp32c3.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 esp32c3.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9MB FATFS) esp32c3.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB esp32c3.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +esp32c3.menu.PartitionScheme.rainmaker=RainMaker +esp32c3.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +esp32c3.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 esp32c3.menu.CPUFreq.160=160MHz (WiFi) esp32c3.menu.CPUFreq.160.build.f_cpu=160000000L @@ -475,6 +481,9 @@ esp32s2.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 esp32s2.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9MB FATFS) esp32s2.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB esp32s2.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +esp32s2.menu.PartitionScheme.rainmaker=RainMaker +esp32s2.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +esp32s2.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 esp32s2.menu.CPUFreq.240=240MHz (WiFi) esp32s2.menu.CPUFreq.240.build.f_cpu=240000000L @@ -2119,7 +2128,131 @@ tinys2.menu.DebugLevel.verbose=Verbose tinys2.menu.DebugLevel.verbose.build.code_debug=5 ############################################################## +rmp.name=UM RMP +rmp.vid.0=0x303a +rmp.pid.0=0x80F6 + +rmp.upload.tool=esptool_py +rmp.upload.maximum_size=1310720 +rmp.upload.maximum_data_size=327680 +rmp.upload.flags= +rmp.upload.extra_flags= +rmp.upload.use_1200bps_touch=true +rmp.upload.wait_for_upload_port=true + +rmp.serial.disableDTR=false +rmp.serial.disableRTS=false + +rmp.build.tarch=xtensa +rmp.build.bootloader_addr=0x1000 +rmp.build.target=esp32s2 +rmp.build.mcu=esp32s2 +rmp.build.core=esp32 +rmp.build.variant=um_rmp +rmp.build.board=RMP + +rmp.build.cdc_on_boot=1 +rmp.build.msc_on_boot=0 +rmp.build.dfu_on_boot=0 +rmp.build.f_cpu=240000000L +rmp.build.flash_size=4MB +rmp.build.flash_freq=80m +rmp.build.flash_mode=dio +rmp.build.boot=qio +rmp.build.partitions=default +rmp.build.defines= + +rmp.menu.CDCOnBoot.cdc=Enabled +rmp.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 +rmp.menu.CDCOnBoot.default=Disabled +rmp.menu.CDCOnBoot.default.build.cdc_on_boot=0 + +rmp.menu.MSCOnBoot.default=Disabled +rmp.menu.MSCOnBoot.default.build.msc_on_boot=0 +rmp.menu.MSCOnBoot.msc=Enabled +rmp.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +rmp.menu.DFUOnBoot.default=Disabled +rmp.menu.DFUOnBoot.default.build.dfu_on_boot=0 +rmp.menu.DFUOnBoot.dfu=Enabled +rmp.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +rmp.menu.PSRAM.enabled=Enabled +rmp.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM +rmp.menu.PSRAM.disabled=Disabled +rmp.menu.PSRAM.disabled.build.defines= + +rmp.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +rmp.menu.PartitionScheme.default.build.partitions=default +rmp.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +rmp.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +rmp.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +rmp.menu.PartitionScheme.minimal.build.partitions=minimal +rmp.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +rmp.menu.PartitionScheme.no_ota.build.partitions=no_ota +rmp.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +rmp.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +rmp.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +rmp.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +rmp.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +rmp.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +rmp.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +rmp.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +rmp.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +rmp.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +rmp.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +rmp.menu.PartitionScheme.huge_app.build.partitions=huge_app +rmp.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +rmp.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +rmp.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +rmp.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 + +rmp.menu.CPUFreq.240=240MHz (WiFi) +rmp.menu.CPUFreq.240.build.f_cpu=240000000L +rmp.menu.CPUFreq.160=160MHz (WiFi) +rmp.menu.CPUFreq.160.build.f_cpu=160000000L +rmp.menu.CPUFreq.80=80MHz (WiFi) +rmp.menu.CPUFreq.80.build.f_cpu=80000000L +rmp.menu.CPUFreq.40=40MHz +rmp.menu.CPUFreq.40.build.f_cpu=40000000L +rmp.menu.CPUFreq.20=20MHz +rmp.menu.CPUFreq.20.build.f_cpu=20000000L +rmp.menu.CPUFreq.10=10MHz +rmp.menu.CPUFreq.10.build.f_cpu=10000000L + +rmp.menu.FlashSize.4M=4MB (32Mb) +rmp.menu.FlashSize.4M.build.flash_size=4MB +rmp.menu.FlashSize.2M=2MB (16Mb) +rmp.menu.FlashSize.2M.build.flash_size=2MB +rmp.menu.FlashSize.2M.build.partitions=minimal + +rmp.menu.UploadSpeed.921600=921600 +rmp.menu.UploadSpeed.921600.upload.speed=921600 +rmp.menu.UploadSpeed.115200=115200 +rmp.menu.UploadSpeed.115200.upload.speed=115200 +rmp.menu.UploadSpeed.256000.windows=256000 +rmp.menu.UploadSpeed.256000.upload.speed=256000 +rmp.menu.UploadSpeed.230400.windows.upload.speed=256000 +rmp.menu.UploadSpeed.230400=230400 +rmp.menu.UploadSpeed.230400.upload.speed=230400 +rmp.menu.UploadSpeed.460800.linux=460800 +rmp.menu.UploadSpeed.460800.macosx=460800 +rmp.menu.UploadSpeed.460800.upload.speed=460800 + +rmp.menu.DebugLevel.none=None +rmp.menu.DebugLevel.none.build.code_debug=0 +rmp.menu.DebugLevel.error=Error +rmp.menu.DebugLevel.error.build.code_debug=1 +rmp.menu.DebugLevel.warn=Warn +rmp.menu.DebugLevel.warn.build.code_debug=2 +rmp.menu.DebugLevel.info=Info +rmp.menu.DebugLevel.info.build.code_debug=3 +rmp.menu.DebugLevel.debug=Debug +rmp.menu.DebugLevel.debug.build.code_debug=4 +rmp.menu.DebugLevel.verbose=Verbose +rmp.menu.DebugLevel.verbose.build.code_debug=5 +############################################################## tinys3.name=UM TinyS3 tinys3.vid.0=0x303a tinys3.pid.0=0x80D0 @@ -14258,3 +14391,104 @@ deneyapkart1A.menu.DebugLevel.verbose=Verbose deneyapkart1A.menu.DebugLevel.verbose.build.code_debug=5 ############################################################## + +AirM2M_CORE_ESP32C3.name=AirM2M_CORE_ESP32C3 +AirM2M_CORE_ESP32C3.vid.0=0x303a +AirM2M_CORE_ESP32C3.pid.0=0x1001 + +AirM2M_CORE_ESP32C3.upload.tool=esptool_py +AirM2M_CORE_ESP32C3.upload.maximum_size=1310720 +AirM2M_CORE_ESP32C3.upload.maximum_data_size=327680 +AirM2M_CORE_ESP32C3.upload.flags= +AirM2M_CORE_ESP32C3.upload.extra_flags= +AirM2M_CORE_ESP32C3.upload.use_1200bps_touch=false +AirM2M_CORE_ESP32C3.upload.wait_for_upload_port=false + +AirM2M_CORE_ESP32C3.serial.disableDTR=false +AirM2M_CORE_ESP32C3.serial.disableRTS=false + +AirM2M_CORE_ESP32C3.build.tarch=riscv32 +AirM2M_CORE_ESP32C3.build.target=esp +AirM2M_CORE_ESP32C3.build.mcu=esp32c3 +AirM2M_CORE_ESP32C3.build.core=esp32 +AirM2M_CORE_ESP32C3.build.variant=AirM2M_CORE_ESP32C3 +AirM2M_CORE_ESP32C3.build.board=AirM2M_CORE_ESP32C3 +AirM2M_CORE_ESP32C3.build.bootloader_addr=0x0 + +AirM2M_CORE_ESP32C3.build.cdc_on_boot=0 +AirM2M_CORE_ESP32C3.build.f_cpu=160000000L +AirM2M_CORE_ESP32C3.build.flash_size=4MB +AirM2M_CORE_ESP32C3.build.flash_freq=80m +AirM2M_CORE_ESP32C3.build.flash_mode=dio +AirM2M_CORE_ESP32C3.build.boot=dio +AirM2M_CORE_ESP32C3.build.partitions=default +AirM2M_CORE_ESP32C3.build.defines= + +AirM2M_CORE_ESP32C3.menu.CDCOnBoot.default=Disabled +AirM2M_CORE_ESP32C3.menu.CDCOnBoot.default.build.cdc_on_boot=0 +AirM2M_CORE_ESP32C3.menu.CDCOnBoot.cdc=Enabled +AirM2M_CORE_ESP32C3.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 + +AirM2M_CORE_ESP32C3.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.default.build.partitions=default +AirM2M_CORE_ESP32C3.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +AirM2M_CORE_ESP32C3.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.default_8MB.build.partitions=default_8MB +AirM2M_CORE_ESP32C3.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336 +AirM2M_CORE_ESP32C3.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.minimal.build.partitions=minimal +AirM2M_CORE_ESP32C3.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.no_ota.build.partitions=no_ota +AirM2M_CORE_ESP32C3.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +AirM2M_CORE_ESP32C3.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +AirM2M_CORE_ESP32C3.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +AirM2M_CORE_ESP32C3.menu.PartitionScheme.huge_app.build.partitions=huge_app +AirM2M_CORE_ESP32C3.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 + +AirM2M_CORE_ESP32C3.menu.CPUFreq.160=160MHz (WiFi) +AirM2M_CORE_ESP32C3.menu.CPUFreq.160.build.f_cpu=160000000L +AirM2M_CORE_ESP32C3.menu.CPUFreq.80=80MHz (WiFi) +AirM2M_CORE_ESP32C3.menu.CPUFreq.80.build.f_cpu=80000000L +AirM2M_CORE_ESP32C3.menu.CPUFreq.40=40MHz +AirM2M_CORE_ESP32C3.menu.CPUFreq.40.build.f_cpu=40000000L +AirM2M_CORE_ESP32C3.menu.CPUFreq.20=20MHz +AirM2M_CORE_ESP32C3.menu.CPUFreq.20.build.f_cpu=20000000L +AirM2M_CORE_ESP32C3.menu.CPUFreq.10=10MHz +AirM2M_CORE_ESP32C3.menu.CPUFreq.10.build.f_cpu=10000000L + +AirM2M_CORE_ESP32C3.menu.FlashFreq.80=80MHz +AirM2M_CORE_ESP32C3.menu.FlashFreq.80.build.flash_freq=80m +AirM2M_CORE_ESP32C3.menu.FlashFreq.40=40MHz +AirM2M_CORE_ESP32C3.menu.FlashFreq.40.build.flash_freq=40m + +AirM2M_CORE_ESP32C3.menu.UploadSpeed.921600=921600 +AirM2M_CORE_ESP32C3.menu.UploadSpeed.921600.upload.speed=921600 +AirM2M_CORE_ESP32C3.menu.UploadSpeed.115200=115200 +AirM2M_CORE_ESP32C3.menu.UploadSpeed.115200.upload.speed=115200 +AirM2M_CORE_ESP32C3.menu.UploadSpeed.1152000=1152000 +AirM2M_CORE_ESP32C3.menu.UploadSpeed.1152000.upload.speed=1152000 + + +AirM2M_CORE_ESP32C3.menu.DebugLevel.none=None +AirM2M_CORE_ESP32C3.menu.DebugLevel.none.build.code_debug=0 +AirM2M_CORE_ESP32C3.menu.DebugLevel.error=Error +AirM2M_CORE_ESP32C3.menu.DebugLevel.error.build.code_debug=1 +AirM2M_CORE_ESP32C3.menu.DebugLevel.warn=Warn +AirM2M_CORE_ESP32C3.menu.DebugLevel.warn.build.code_debug=2 +AirM2M_CORE_ESP32C3.menu.DebugLevel.info=Info +AirM2M_CORE_ESP32C3.menu.DebugLevel.info.build.code_debug=3 +AirM2M_CORE_ESP32C3.menu.DebugLevel.debug=Debug +AirM2M_CORE_ESP32C3.menu.DebugLevel.debug.build.code_debug=4 +AirM2M_CORE_ESP32C3.menu.DebugLevel.verbose=Verbose +AirM2M_CORE_ESP32C3.menu.DebugLevel.verbose.build.code_debug=5 + +############################################################# diff --git a/cores/esp32/Esp.cpp b/cores/esp32/Esp.cpp index 6cca85ac64c..fa82cdb6556 100644 --- a/cores/esp32/Esp.cpp +++ b/cores/esp32/Esp.cpp @@ -231,6 +231,10 @@ String EspClass::getSketchMD5() md5.add(buf.get(), readBytes); lengthLeft -= readBytes; offset += readBytes; + + #if CONFIG_FREERTOS_UNICORE + delay(1); // Fix solo WDT + #endif } md5.calculate(); result = md5.toString(); diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index c4ec85e732c..f01b501a020 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -317,6 +317,8 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency){ hal.dev = I2C_LL_GET_HW(i2c_num); i2c_hal_set_bus_timing(&(hal), frequency, src_clk); bus[i2c_num].frequency = frequency; + //Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2 + i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT); } end: diff --git a/cores/esp32/esp32-hal-log.h b/cores/esp32/esp32-hal-log.h index 43d84a40ba6..3198387fdd8 100644 --- a/cores/esp32/esp32-hal-log.h +++ b/cores/esp32/esp32-hal-log.h @@ -206,16 +206,16 @@ void log_print_buf(const uint8_t *b, size_t len); #undef ESP_EARLY_LOGD #undef ESP_EARLY_LOGV -#define ESP_LOGE(tag, ...) log_e(__VA_ARGS__) -#define ESP_LOGW(tag, ...) log_w(__VA_ARGS__) -#define ESP_LOGI(tag, ...) log_i(__VA_ARGS__) -#define ESP_LOGD(tag, ...) log_d(__VA_ARGS__) -#define ESP_LOGV(tag, ...) log_v(__VA_ARGS__) -#define ESP_EARLY_LOGE(tag, ...) isr_log_e(__VA_ARGS__) -#define ESP_EARLY_LOGW(tag, ...) isr_log_w(__VA_ARGS__) -#define ESP_EARLY_LOGI(tag, ...) isr_log_i(__VA_ARGS__) -#define ESP_EARLY_LOGD(tag, ...) isr_log_d(__VA_ARGS__) -#define ESP_EARLY_LOGV(tag, ...) isr_log_v(__VA_ARGS__) +#define ESP_LOGE(tag, format, ...) log_e("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_LOGW(tag, format, ...) log_w("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_LOGI(tag, format, ...) log_i("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_LOGD(tag, format, ...) log_d("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_LOGV(tag, format, ...) log_v("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_EARLY_LOGE(tag, format, ...) isr_log_e("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_EARLY_LOGW(tag, format, ...) isr_log_w("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_EARLY_LOGI(tag, format, ...) isr_log_i("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_EARLY_LOGD(tag, format, ...) isr_log_d("[%s] " format, tag, ##__VA_ARGS__) +#define ESP_EARLY_LOGV(tag, format, ...) isr_log_v("[%s] " format, tag, ##__VA_ARGS__) #endif #endif diff --git a/cores/esp32/esp32-hal-touch.c b/cores/esp32/esp32-hal-touch.c index e5eaf497b5e..539c0004f98 100644 --- a/cores/esp32/esp32-hal-touch.c +++ b/cores/esp32/esp32-hal-touch.c @@ -119,11 +119,6 @@ static void __touchInit() if (err != ESP_OK) { goto err; } - // Initial no Threshold and setup - for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) { - __touchInterruptHandlers[i].fn = NULL; - touch_pad_config(i, SOC_TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK - } // keep ISR activated - it can run all together (ISR + touchRead()) err = touch_pad_isr_register(__touchISR, NULL); if (err != ESP_OK) { @@ -148,18 +143,7 @@ static void __touchInit() // Touch Sensor Timer initiated touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK touch_pad_fsm_start(); // returns ESP_OK - - // Initial no Threshold and setup - TOUCH0 is internal denoise channel - for (int i = 1; i < SOC_TOUCH_SENSOR_NUM; i++) { - __touchInterruptHandlers[i].fn = NULL; - touch_pad_config(i); // returns ESP_OK - } - // keep ISR activated - it can run all together (ISR + touchRead()) - err = touch_pad_isr_register(__touchISR, NULL, TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); - if (err != ESP_OK) { - goto err; - } - touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); // returns ESP_OK + //ISR setup moved to __touchChannelInit #endif initialized = true; @@ -170,13 +154,43 @@ static void __touchInit() return; } +static void __touchChannelInit(int pad) +{ + static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = { false }; + if(channels_initialized[pad]){ + return; + } + +#if SOC_TOUCH_VERSION_1 // ESP32 + // Initial no Threshold and setup + __touchInterruptHandlers[pad].fn = NULL; + touch_pad_config(pad, SOC_TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK +#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3 + // Initial no Threshold and setup + __touchInterruptHandlers[pad].fn = NULL; + touch_pad_config(pad); // returns ESP_OK + // keep ISR activated - it can run all together (ISR + touchRead()) + esp_err_t err = touch_pad_isr_register(__touchISR, NULL, TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); + if (err != ESP_OK) { + log_e(" Touch sensor initialization error."); + return; + } + touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); // returns ESP_OK +#endif + + channels_initialized[pad] = true; + delay(20); //delay needed before reading from touch channel after config +} + static touch_value_t __touchRead(uint8_t pin) { int8_t pad = digitalPinToTouchChannel(pin); if(pad < 0){ return 0; } + __touchInit(); + __touchChannelInit(pad); touch_value_t touch_value; touch_pad_read_raw_data(pad, &touch_value); @@ -198,6 +212,9 @@ static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Ar } else { // attach ISR User Call __touchInit(); + #if SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3 + __touchChannelInit(pad); + #endif __touchInterruptHandlers[pad].fn = userFunc; __touchInterruptHandlers[pad].callWithArgs = callWithArgs; __touchInterruptHandlers[pad].arg = Args; diff --git a/libraries/LittleFS/examples/LITTLEFS_test/.skip.esp32c3 b/libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32c3 similarity index 100% rename from libraries/LittleFS/examples/LITTLEFS_test/.skip.esp32c3 rename to libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32c3 diff --git a/libraries/LittleFS/examples/LITTLEFS_time/.skip.esp32c3 b/libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32s2 similarity index 100% rename from libraries/LittleFS/examples/LITTLEFS_time/.skip.esp32c3 rename to libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32s2 diff --git a/libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32s3 b/libraries/BluetoothSerial/examples/DiscoverConnect/.skip.esp32s3 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino b/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino new file mode 100644 index 00000000000..168ea9d19c4 --- /dev/null +++ b/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino @@ -0,0 +1,114 @@ +/** + * Bluetooth Classic Example + * Scan for devices - asyncronously, print device as soon as found + * query devices for SPP - SDP profile + * connect to first device offering a SPP connection + * + * Example python server: + * source: https://gist.github.com/ukBaz/217875c83c2535d22a16ba38fc8f2a91 + * + * Tested with Raspberry Pi onboard Wifi/BT, USB BT 4.0 dongles, USB BT 1.1 dongles, + * 202202: does NOT work with USB BT 2.0 dongles when esp32 aduino lib is compiled with SSP support! + * see https://github.com/espressif/esp-idf/issues/8394 + * + * use ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE in connect() if remote side requests 'RequireAuthentication': dbus.Boolean(True), + * use ESP_SPP_SEC_NONE or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE in connect() if remote side has Authentication: False + */ + +#include +#include + +#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) +#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it +#endif + +#if !defined(CONFIG_BT_SPP_ENABLED) +#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip. +#endif + +BluetoothSerial SerialBT; + + +#define BT_DISCOVER_TIME 10000 +esp_spp_sec_t sec_mask=ESP_SPP_SEC_NONE; // or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE to request pincode confirmation +esp_spp_role_t role=ESP_SPP_ROLE_SLAVE; // or ESP_SPP_ROLE_MASTER + +// std::map btDeviceList; + +void setup() { + Serial.begin(115200); + if(! SerialBT.begin("ESP32test", true) ) { + Serial.println("========== serialBT failed!"); + abort(); + } + // SerialBT.setPin("1234"); // doesn't seem to change anything + // SerialBT.enableSSP(); // doesn't seem to change anything + + + Serial.println("Starting discoverAsync..."); + BTScanResults* btDeviceList = SerialBT.getScanResults(); // maybe accessing from different threads! + if (SerialBT.discoverAsync([](BTAdvertisedDevice* pDevice) { + // BTAdvertisedDeviceSet*set = reinterpret_cast(pDevice); + // btDeviceList[pDevice->getAddress()] = * set; + Serial.printf(">>>>>>>>>>>Found a new device asynchronously: %s\n", pDevice->toString().c_str()); + } ) + ) { + delay(BT_DISCOVER_TIME); + Serial.print("Stopping discoverAsync... "); + SerialBT.discoverAsyncStop(); + Serial.println("discoverAsync stopped"); + delay(5000); + if(btDeviceList->getCount() > 0) { + BTAddress addr; + int channel=0; + Serial.println("Found devices:"); + for (int i=0; i < btDeviceList->getCount(); i++) { + BTAdvertisedDevice *device=btDeviceList->getDevice(i); + Serial.printf(" ----- %s %s %d\n", device->getAddress().toString().c_str(), device->getName().c_str(), device->getRSSI()); + std::map channels=SerialBT.getChannels(device->getAddress()); + Serial.printf("scanned for services, found %d\n", channels.size()); + for(auto const &entry : channels) { + Serial.printf(" channel %d (%s)\n", entry.first, entry.second.c_str()); + } + if(channels.size() > 0) { + addr = device->getAddress(); + channel=channels.begin()->first; + } + } + if(addr) { + Serial.printf("connecting to %s - %d\n", addr.toString().c_str(), channel); + SerialBT.connect(addr, channel, sec_mask, role); + } + } else { + Serial.println("Didn't find any devices"); + } + } else { + Serial.println("Error on discoverAsync f.e. not workin after a \"connect\""); + } +} + + +String sendData="Hi from esp32!\n"; + +void loop() { + if(! SerialBT.isClosed() && SerialBT.connected()) { + if( SerialBT.write((const uint8_t*) sendData.c_str(),sendData.length()) != sendData.length()) { + Serial.println("tx: error"); + } else { + Serial.printf("tx: %s",sendData.c_str()); + } + if(SerialBT.available()) { + Serial.print("rx: "); + while(SerialBT.available()) { + int c=SerialBT.read(); + if(c >= 0) { + Serial.print((char) c); + } + } + Serial.println(); + } + } else { + Serial.println("not connected"); + } + delay(1000); +} diff --git a/libraries/BluetoothSerial/src/BTAddress.cpp b/libraries/BluetoothSerial/src/BTAddress.cpp index 7ef1eb1a85e..72fe7587b72 100644 --- a/libraries/BluetoothSerial/src/BTAddress.cpp +++ b/libraries/BluetoothSerial/src/BTAddress.cpp @@ -29,6 +29,9 @@ BTAddress::BTAddress(esp_bd_addr_t address) { memcpy(m_address, address, ESP_BD_ADDR_LEN); } // BTAddress +BTAddress::BTAddress() { + bzero(m_address, ESP_BD_ADDR_LEN); +} // BTAddress /** * @brief Create an address from a hex string @@ -64,13 +67,20 @@ bool BTAddress::equals(BTAddress otherAddress) { return memcmp(otherAddress.getNative(), m_address, 6) == 0; } // equals +BTAddress::operator bool () const { + for(int i = 0; i < ESP_BD_ADDR_LEN; i++){ + if(this->m_address[i]) + return true; + } + return false; +} // operator () /** * @brief Return the native representation of the address. * @return The native representation of the address. */ -esp_bd_addr_t *BTAddress::getNative() { - return &m_address; +esp_bd_addr_t *BTAddress::getNative() const { + return const_cast(&m_address); } // getNative @@ -85,7 +95,7 @@ esp_bd_addr_t *BTAddress::getNative() { * * @return The string representation of the address. */ -std::string BTAddress::toString() { +std::string BTAddress::toString() const { auto size = 18; char *res = (char*)malloc(size); snprintf(res, size, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[0], m_address[1], m_address[2], m_address[3], m_address[4], m_address[5]); diff --git a/libraries/BluetoothSerial/src/BTAddress.h b/libraries/BluetoothSerial/src/BTAddress.h index 6213d01fdf2..3e51d053ebb 100644 --- a/libraries/BluetoothSerial/src/BTAddress.h +++ b/libraries/BluetoothSerial/src/BTAddress.h @@ -22,11 +22,14 @@ */ class BTAddress { public: + BTAddress(); BTAddress(esp_bd_addr_t address); BTAddress(std::string stringAddress); bool equals(BTAddress otherAddress); - esp_bd_addr_t* getNative(); - std::string toString(); + operator bool () const; + + esp_bd_addr_t* getNative() const; + std::string toString() const; private: esp_bd_addr_t m_address; diff --git a/libraries/BluetoothSerial/src/BTAdvertisedDevice.h b/libraries/BluetoothSerial/src/BTAdvertisedDevice.h index 07e93622e92..918946f1910 100644 --- a/libraries/BluetoothSerial/src/BTAdvertisedDevice.h +++ b/libraries/BluetoothSerial/src/BTAdvertisedDevice.h @@ -16,14 +16,14 @@ class BTAdvertisedDevice { virtual ~BTAdvertisedDevice() = default; virtual BTAddress getAddress(); - virtual uint32_t getCOD(); - virtual std::string getName(); - virtual int8_t getRSSI(); + virtual uint32_t getCOD() const; + virtual std::string getName() const; + virtual int8_t getRSSI() const; - virtual bool haveCOD(); - virtual bool haveName(); - virtual bool haveRSSI(); + virtual bool haveCOD() const; + virtual bool haveName() const; + virtual bool haveRSSI() const; virtual std::string toString(); }; @@ -35,14 +35,14 @@ class BTAdvertisedDeviceSet : public virtual BTAdvertisedDevice { BTAddress getAddress(); - uint32_t getCOD(); - std::string getName(); - int8_t getRSSI(); + uint32_t getCOD() const; + std::string getName() const; + int8_t getRSSI() const; - bool haveCOD(); - bool haveName(); - bool haveRSSI(); + bool haveCOD() const; + bool haveName() const; + bool haveRSSI() const; std::string toString(); @@ -62,4 +62,4 @@ class BTAdvertisedDeviceSet : public virtual BTAdvertisedDevice { int8_t m_rssi; }; -#endif \ No newline at end of file +#endif diff --git a/libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp b/libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp index c8f28e9c39e..8a9e26e4d5a 100644 --- a/libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp +++ b/libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp @@ -25,14 +25,14 @@ BTAdvertisedDeviceSet::BTAdvertisedDeviceSet() { } // BTAdvertisedDeviceSet BTAddress BTAdvertisedDeviceSet::getAddress() { return m_address; } -uint32_t BTAdvertisedDeviceSet::getCOD() { return m_cod; } -std::string BTAdvertisedDeviceSet::getName() { return m_name; } -int8_t BTAdvertisedDeviceSet::getRSSI() { return m_rssi; } +uint32_t BTAdvertisedDeviceSet::getCOD() const { return m_cod; } +std::string BTAdvertisedDeviceSet::getName() const { return m_name; } +int8_t BTAdvertisedDeviceSet::getRSSI() const { return m_rssi; } -bool BTAdvertisedDeviceSet::haveCOD() { return m_haveCOD; } -bool BTAdvertisedDeviceSet::haveName() { return m_haveName; } -bool BTAdvertisedDeviceSet::haveRSSI() { return m_haveRSSI; } +bool BTAdvertisedDeviceSet::haveCOD() const { return m_haveCOD; } +bool BTAdvertisedDeviceSet::haveName() const { return m_haveName; } +bool BTAdvertisedDeviceSet::haveRSSI() const { return m_haveRSSI; } /** * @brief Create a string representation of this device. diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index b20452c186a..ea72f787ebf 100644 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -72,18 +72,30 @@ static esp_bt_pin_code_t _pin_code; static int _pin_len; static bool _isPinSet; static bool _enableSSP; +static esp_spp_sec_t _sec_mask; +static esp_spp_role_t _role; +// start connect on ESP_SPP_DISCOVERY_COMP_EVT or save entry for getChannels +static bool _doConnect; +static std::map sdpRecords; static BTScanResultsSet scanResults; static BTAdvertisedDeviceCb advertisedDeviceCb = nullptr; +// _spp_event_group #define SPP_RUNNING 0x01 #define SPP_CONNECTED 0x02 #define SPP_CONGESTED 0x04 +// true until OPEN successful, changes to false on CLOSE #define SPP_DISCONNECTED 0x08 +// true until connect(), changes to true on CLOSE +#define SPP_CLOSED 0x10 +// _bt_event_group #define BT_DISCOVERY_RUNNING 0x01 #define BT_DISCOVERY_COMPLETED 0x02 +#define BT_SDP_RUNNING 0x04 +#define BT_SDP_COMPLETED 0x08 typedef struct { size_t len; @@ -98,7 +110,7 @@ static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) } uint8_t *p = bda; - sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], p[4], p[5]); return str; } @@ -280,13 +292,15 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) case ESP_SPP_CLOSE_EVT://Client connection closed if ((param->close.async == false && param->close.status == ESP_SPP_SUCCESS) || param->close.async) { - log_i("ESP_SPP_CLOSE_EVT: %u", secondConnectionAttempt); + log_i("ESP_SPP_CLOSE_EVT status:%d handle:%d close_by_remote:%d attempt %u", param->close.status, + param->close.handle, param->close.async, secondConnectionAttempt); if(secondConnectionAttempt) { secondConnectionAttempt = false; } else { _spp_client = 0; xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED); xEventGroupSetBits(_spp_event_group, SPP_CONGESTED); + xEventGroupSetBits(_spp_event_group, SPP_CLOSED); } xEventGroupClearBits(_spp_event_group, SPP_CONNECTED); } else { @@ -333,13 +347,37 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) break; case ESP_SPP_DISCOVERY_COMP_EVT://discovery complete - log_i("ESP_SPP_DISCOVERY_COMP_EVT"); + log_i("ESP_SPP_DISCOVERY_COMP_EVT num=%d", param->disc_comp.scn_num); if (param->disc_comp.status == ESP_SPP_SUCCESS) { - log_i("ESP_SPP_DISCOVERY_COMP_EVT: spp connect to remote"); - esp_spp_connect(ESP_SPP_SEC_AUTHENTICATE, ESP_SPP_ROLE_MASTER, param->disc_comp.scn[0], _peer_bd_addr); + for(int i=0; i < param->disc_comp.scn_num; i++) { + log_d("ESP_SPP_DISCOVERY_COMP_EVT: spp [%d] channel: %d service name:%s", i, param->disc_comp.scn[i], param->disc_comp.service_name[0]); + } + if(_doConnect) { + if(param->disc_comp.scn_num > 0) { +#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) + char bda_str[18]; + log_i("ESP_SPP_DISCOVERY_COMP_EVT: spp connect to remote %s channel %d", + bda2str(_peer_bd_addr, bda_str, sizeof(bda_str)), + param->disc_comp.scn[0]); +#endif + xEventGroupClearBits(_spp_event_group, SPP_CLOSED); + if(esp_spp_connect(_sec_mask, _role, param->disc_comp.scn[0], _peer_bd_addr) != ESP_OK) { + log_e("ESP_SPP_DISCOVERY_COMP_EVT connect failed"); + xEventGroupSetBits(_spp_event_group, SPP_CLOSED); + } + } else { + log_e("ESP_SPP_DISCOVERY_COMP_EVT remote doesn't offer an SPP channel"); + xEventGroupSetBits(_spp_event_group, SPP_CLOSED); + } + } else { + for(int i=0; i < param->disc_comp.scn_num; i++) { + sdpRecords[param->disc_comp.scn[i]] = param->disc_comp.service_name[0]; + } + } } else { log_e("ESP_SPP_DISCOVERY_COMP_EVT failed!, status:%d", param->disc_comp.status); } + xEventGroupSetBits(_bt_event_group, BT_SDP_COMPLETED); break; case ESP_SPP_OPEN_EVT://Client connection open @@ -360,10 +398,15 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) break; case ESP_SPP_CL_INIT_EVT://client initiated a connection - log_i("ESP_SPP_CL_INIT_EVT"); + if (param->cl_init.status == ESP_SPP_SUCCESS) { + log_i("ESP_SPP_CL_INIT_EVT handle:%d sec_id:%d", param->cl_init.handle, param->cl_init.sec_id); + } else { + log_i("ESP_SPP_CL_INIT_EVT status:%d", param->cl_init.status); + } break; default: + log_i("ESP_SPP_* event unhandled %d", event); break; } if(custom_spp_callback)(*custom_spp_callback)(event, param); @@ -377,7 +420,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa { switch(event){ case ESP_BT_GAP_DISC_RES_EVT: { - log_i("ESP_BT_GAP_DISC_RES_EVT"); + log_i("ESP_BT_GAP_DISC_RES_EVT properties=%d", param->disc_res.num_prop); #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) char bda_str[18]; log_i("Scanned device: %s", bda2str(param->disc_res.bda, bda_str, 18)); @@ -417,28 +460,29 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa break; case ESP_BT_GAP_DEV_PROP_COD: - log_d("ESP_BT_GAP_DEV_PROP_COD"); if (param->disc_res.prop[i].len <= sizeof(int)) { uint32_t cod = 0; memcpy(&cod, param->disc_res.prop[i].val, param->disc_res.prop[i].len); advertisedDevice.setCOD(cod); + log_d("ESP_BT_GAP_DEV_PROP_COD 0x%x", cod); } else { - log_d("Value size larger than integer"); + log_d("ESP_BT_GAP_DEV_PROP_COD invalid COD: Value size larger than integer"); } break; case ESP_BT_GAP_DEV_PROP_RSSI: - log_d("ESP_BT_GAP_DEV_PROP_RSSI"); if (param->disc_res.prop[i].len <= sizeof(int)) { uint8_t rssi = 0; memcpy(&rssi, param->disc_res.prop[i].val, param->disc_res.prop[i].len); + log_d("ESP_BT_GAP_DEV_PROP_RSSI %d", rssi); advertisedDevice.setRSSI(rssi); } else { - log_d("Value size larger than integer"); + log_d("ESP_BT_GAP_DEV_PROP_RSSI invalid RSSI: Value size larger than integer"); } break; default: + log_i("ESP_BT_GAP_DISC_RES_EVT unknown property [%d]:type:%d", i, param->disc_res.prop[i].type); break; } if (_isRemoteAddressSet) @@ -455,11 +499,12 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa break; case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: - log_i("ESP_BT_GAP_DISC_STATE_CHANGED_EVT"); if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { + log_i("ESP_BT_GAP_DISC_STATE_CHANGED_EVT stopped"); xEventGroupClearBits(_bt_event_group, BT_DISCOVERY_RUNNING); xEventGroupSetBits(_bt_event_group, BT_DISCOVERY_COMPLETED); } else { // ESP_BT_GAP_DISCOVERY_STARTED + log_i("ESP_BT_GAP_DISC_STATE_CHANGED_EVT started"); xEventGroupClearBits(_bt_event_group, BT_DISCOVERY_COMPLETED); xEventGroupSetBits(_bt_event_group, BT_DISCOVERY_RUNNING); } @@ -522,7 +567,24 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!"); break; + case ESP_BT_GAP_CONFIG_EIR_DATA_EVT: + log_i("ESP_BT_GAP_CONFIG_EIR_DATA_EVT: stat:%d num:%d", param->config_eir_data.stat, param->config_eir_data.eir_type_num); + break; + + case ESP_BT_GAP_READ_REMOTE_NAME_EVT: + if (param->read_rmt_name.stat == ESP_BT_STATUS_SUCCESS ) { + log_i("ESP_BT_GAP_READ_REMOTE_NAME_EVT: %s", param->read_rmt_name.rmt_name); + } else { + log_i("ESP_BT_GAP_READ_REMOTE_NAME_EVT: no success stat:%d", param->read_rmt_name.stat); + } + break; + + case ESP_BT_GAP_MODE_CHG_EVT: + log_i("ESP_BT_GAP_MODE_CHG_EVT: mode: %d", param->mode_chg.mode); + break; + default: + log_i("ESP-BT_GAP_* unknown message: %d", event); break; } } @@ -546,6 +608,7 @@ static bool _init_bt(const char *deviceName) xEventGroupClearBits(_spp_event_group, 0xFFFFFF); xEventGroupSetBits(_spp_event_group, SPP_CONGESTED); xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED); + xEventGroupSetBits(_spp_event_group, SPP_CLOSED); } if (_spp_rx_queue == NULL){ _spp_rx_queue = xQueueCreate(RX_QUEUE_SIZE, sizeof(uint8_t)); //initialize the queue @@ -623,6 +686,7 @@ static bool _init_bt(const char *deviceName) esp_bt_dev_set_device_name(deviceName); if (_isPinSet) { + log_i("pin set"); btSetPin(); } @@ -690,7 +754,16 @@ static bool _stop_bt() static bool waitForConnect(int timeout) { TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; - return (xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) & SPP_CONNECTED) != 0; + // wait for connected or closed + EventBits_t rc = xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED | SPP_CLOSED, pdFALSE, pdFALSE, xTicksToWait); + if((rc & SPP_CONNECTED) != 0) + return true; + else if((rc & SPP_CLOSED) != 0) { + log_d("connection closed!"); + return false; + } + log_d("timeout"); + return false; } static bool waitForDiscovered(int timeout) { @@ -698,6 +771,11 @@ static bool waitForDiscovered(int timeout) { return (xEventGroupWaitBits(_spp_event_group, BT_DISCOVERY_COMPLETED, pdFALSE, pdTRUE, xTicksToWait) & BT_DISCOVERY_COMPLETED) != 0; } +static bool waitForSDPRecord(int timeout) { + TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS; + return (xEventGroupWaitBits(_bt_event_group, BT_SDP_COMPLETED, pdFALSE, pdTRUE, xTicksToWait) & BT_SDP_COMPLETED) != 0; +} + /* * Serial Bluetooth Arduino * @@ -713,6 +791,9 @@ BluetoothSerial::~BluetoothSerial(void) _stop_bt(); } +/** + * @Param isMaster set to true if you want to connect to an other device + */ bool BluetoothSerial::begin(String localName, bool isMaster) { _isMaster = isMaster; @@ -733,7 +814,7 @@ int BluetoothSerial::available(void) int BluetoothSerial::peek(void) { uint8_t c; - if (_spp_rx_queue && xQueuePeek(_spp_rx_queue, &c, 0)){ + if (_spp_rx_queue && xQueuePeek(_spp_rx_queue, &c, this->timeoutTicks)){ return c; } return -1; @@ -744,16 +825,24 @@ bool BluetoothSerial::hasClient(void) return _spp_client > 0; } -int BluetoothSerial::read(void) +int BluetoothSerial::read() { uint8_t c = 0; - if (_spp_rx_queue && xQueueReceive(_spp_rx_queue, &c, 0)){ + if (_spp_rx_queue && xQueueReceive(_spp_rx_queue, &c, this->timeoutTicks)){ return c; } return -1; } +/** + * Set timeout for read / peek + */ +void BluetoothSerial::setTimeout(int timeoutMS) +{ + this->timeoutTicks=timeoutMS / portTICK_PERIOD_MS; +} + size_t BluetoothSerial::write(uint8_t c) { return write(&c, 1); @@ -812,6 +901,7 @@ void BluetoothSerial::enableSSP() { * Use fixed pin code */ bool BluetoothSerial::setPin(const char *pin) { + log_i("pin: %s", pin); bool isEmpty = !(pin && *pin); if (isEmpty && !_isPinSet) { return true; // nothing to do @@ -837,7 +927,10 @@ bool BluetoothSerial::connect(String remoteName) return false; } disconnect(); + _doConnect = true; _isRemoteAddressSet = false; + _sec_mask = ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE; + _role = ESP_SPP_ROLE_MASTER; strncpy(_remote_name, remoteName.c_str(), ESP_BT_GAP_MAX_BDNAME_LEN); _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0; log_i("master : remoteName"); @@ -847,13 +940,23 @@ bool BluetoothSerial::connect(String remoteName) #else esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); #endif + xEventGroupClearBits(_spp_event_group, SPP_CLOSED); if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) { return waitForConnect(SCAN_TIMEOUT); } return false; } -bool BluetoothSerial::connect(uint8_t remoteAddress[]) +/** + * @Param channel: specify channel or 0 for auto-detect + * @Param sec_mask: + * ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE + * ESP_SPP_SEC_NONE + * @Param role: + * ESP_SPP_ROLE_MASTER master can handle up to 7 connections to slaves + * ESP_SPP_ROLE_SLAVE can only have one connection to a master + */ +bool BluetoothSerial::connect(uint8_t remoteAddress[], int channel, esp_spp_sec_t sec_mask, esp_spp_role_t role) { if (!isReady(true, READY_TIMEOUT)) return false; if (!remoteAddress) { @@ -861,10 +964,35 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[]) return false; } disconnect(); + _doConnect = true; _remote_name[0] = 0; _isRemoteAddressSet = true; + _sec_mask = sec_mask; + _role = role; memcpy(_peer_bd_addr, remoteAddress, ESP_BD_ADDR_LEN); log_i("master : remoteAddress"); + xEventGroupClearBits(_spp_event_group, SPP_CLOSED); + if (channel > 0) { + char bda_str[18]; + log_i("spp connect to remote %s channel %d", + bda2str(_peer_bd_addr, bda_str, sizeof(bda_str)), + channel); + if(esp_spp_connect(sec_mask, role, channel, _peer_bd_addr) != ESP_OK ) { + log_e("spp connect failed"); + return false; + } + bool rc=waitForConnect(READY_TIMEOUT); + if(rc) { + log_i("connected"); + } else { + if(this->isClosed()) { + log_e("connect failed"); + } else { + log_e("connect timed out after %dms", READY_TIMEOUT); + } + } + return rc; + } if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) { return waitForConnect(READY_TIMEOUT); } @@ -874,6 +1002,7 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[]) bool BluetoothSerial::connect() { if (!isReady(true, READY_TIMEOUT)) return false; + _doConnect = true; if (_isRemoteAddressSet){ disconnect(); // use resolved or set address first @@ -924,6 +1053,13 @@ bool BluetoothSerial::connected(int timeout) { return waitForConnect(timeout); } +/** + * true if a connection terminated or a connection attempt failed + */ +bool BluetoothSerial::isClosed() { + return xEventGroupGetBits(_spp_event_group) & SPP_CLOSED; +} + bool BluetoothSerial::isReady(bool checkMaster, int timeout) { if (checkMaster && !_isMaster) { log_e("Master mode is not active. Call begin(localName, true) to enable Master mode"); @@ -956,6 +1092,7 @@ BTScanResults* BluetoothSerial::discover(int timeoutMs) { esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, timeout, 0) == ESP_OK) { waitForDiscovered(timeoutMs); + log_i("gap_cancel_discovery()"); esp_bt_gap_cancel_discovery(); } return &scanResults; @@ -1008,4 +1145,31 @@ BluetoothSerial::operator bool() const { return true; } + +/** + * SDP scan address + * esp_spp_start_discovery doesn't tell us the btAddress in the callback, so we have to wait until it's finished + */ +std::map BluetoothSerial::getChannels(const BTAddress &remoteAddress) { + if(xEventGroupGetBits(_bt_event_group) & BT_SDP_RUNNING) { + log_e("getChannels failed - already running"); + } + xEventGroupSetBits(_bt_event_group, BT_SDP_RUNNING); + xEventGroupClearBits(_bt_event_group, BT_SDP_COMPLETED); + _doConnect = false; + sdpRecords.clear(); + log_d("esp_spp_start_discovery"); + if (esp_spp_start_discovery(*remoteAddress.getNative()) != ESP_OK) { + log_e("esp_spp_start_discovery failed"); + } else { + if(! waitForSDPRecord(READY_TIMEOUT)) { + log_e("getChannels failed timeout"); + } + log_d("esp_spp_start_discovery wait for BT_SDP_COMPLETED done (%dms)", READY_TIMEOUT); + } + log_d("esp_spp_start_discovery done, found %d services", sdpRecords.size()); + xEventGroupClearBits(_bt_event_group, BT_SDP_RUNNING); + return sdpRecords; +} + #endif diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index cfb8b823045..0c087b06360 100644 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "BTScan.h" typedef std::function BluetoothSerialDataCb; @@ -50,6 +51,7 @@ class BluetoothSerial: public Stream size_t write(const uint8_t *buffer, size_t size); void flush(); void end(void); + void setTimeout(int timeoutMS); void onData(BluetoothSerialDataCb cb); esp_err_t register_callback(esp_spp_cb_t * callback); @@ -60,9 +62,12 @@ class BluetoothSerial: public Stream void enableSSP(); bool setPin(const char *pin); bool connect(String remoteName); - bool connect(uint8_t remoteAddress[]); + bool connect(uint8_t remoteAddress[], int channel=0, esp_spp_sec_t sec_mask=(ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE), esp_spp_role_t role=ESP_SPP_ROLE_MASTER); + bool connect(const BTAddress &remoteAddress, int channel=0, esp_spp_sec_t sec_mask=(ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE), esp_spp_role_t role=ESP_SPP_ROLE_MASTER) { + return connect(*remoteAddress.getNative(), channel, sec_mask); }; bool connect(); bool connected(int timeout=0); + bool isClosed(); bool isReady(bool checkMaster=false, int timeout=0); bool disconnect(); bool unpairDevice(uint8_t remoteAddress[]); @@ -73,6 +78,8 @@ class BluetoothSerial: public Stream void discoverClear(); BTScanResults* getScanResults(); + std::map getChannels(const BTAddress &remoteAddress); + const int INQ_TIME = 1280; // Inquire Time unit 1280 ms const int MIN_INQ_TIME = (ESP_BT_GAP_MIN_INQ_LEN * INQ_TIME); const int MAX_INQ_TIME = (ESP_BT_GAP_MAX_INQ_LEN * INQ_TIME); @@ -80,7 +87,7 @@ class BluetoothSerial: public Stream operator bool() const; private: String local_name; - + int timeoutTicks=0; }; #endif diff --git a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/platformio.ini b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/platformio.ini index 43e34ec0d34..4d3087a3012 100644 --- a/libraries/LittleFS/examples/LITTLEFS_PlatformIO/platformio.ini +++ b/libraries/LittleFS/examples/LITTLEFS_PlatformIO/platformio.ini @@ -16,17 +16,6 @@ framework = arduino [env:esp32] platform = espressif32 -;platform = https://github.com/platformio/platform-espressif32.git -;board_build.mcu = esp32 -platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git - -build_flags = - ${env.build_flags} - -D=${PIOENV} - ;-D CONFIG_LITTLEFS_FOR_IDF_3_2 - -lib_deps = https://github.com/lorol/LITTLEFS.git - board = esp32dev ;board_build.partitions = partitions_custom.csv monitor_filters = esp32_exception_decoder diff --git a/libraries/RainMaker/examples/README.md b/libraries/RainMaker/examples/README.md index 6c5bded09ac..0b978040085 100644 --- a/libraries/RainMaker/examples/README.md +++ b/libraries/RainMaker/examples/README.md @@ -1,10 +1,13 @@ # ESP RainMaker Examples While building any examples for ESP RainMaker, take care of the following: + 1. Change partition scheme in Arduino IDE to RainMaker (Tools -> Partition Scheme -> RainMaker). 2. Once ESP RainMaker gets started, compulsorily call `WiFi.beginProvision()` which is responsible for user-node mapping. -3. Use appropriate provisioning scheme as per the board. +3. Use the appropriate provisioning scheme as per the board. - ESP32 Board: BLE Provisioning - - ESP32S2 Board: SoftAP Provisioning -4. Set debug level to Info (Tools -> Core Debug Level -> Info). This is recommended, but not mandatory. + - ESP32-C3 Board: BLE Provisioning + - ESP32-S3 Board: BLE Provisioning + - ESP32-S2 Board: SoftAP Provisioning +4. Set debug level to Info (Tools -> Core Debug Level -> Info). This is recommended debug level but not mandatory to run RainMaker. diff --git a/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino b/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino index 55012e413c6..892f285415f 100644 --- a/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino +++ b/libraries/RainMaker/examples/RMakerCustom/RMakerCustom.ino @@ -9,10 +9,15 @@ const char *service_name = "PROV_1234"; const char *pop = "abcd1234"; //GPIO for push button -static int gpio_0 = 0; +#if CONFIG_IDF_TARGET_ESP32C3 +static int gpio_0 = 9; +static int gpio_dimmer = 7; +#else //GPIO for virtual device +static int gpio_0 = 0; static int gpio_dimmer = 16; -/* Variable for reading pin status*/ +#endif + bool dimmer_state = true; // The framework provides some standard device types like switch, lightbulb, fan, temperature sensor. @@ -23,12 +28,12 @@ void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { case ARDUINO_EVENT_PROV_START: -#if CONFIG_IDF_TARGET_ESP32 - Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop); - printQR(service_name, pop, "ble"); -#else +#if CONFIG_IDF_TARGET_ESP32S2 Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop); printQR(service_name, pop, "softap"); +#else + Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop); + printQR(service_name, pop, "ble"); #endif break; } @@ -89,10 +94,10 @@ void setup() RMaker.start(); WiFi.onEvent(sysProvEvent); -#if CONFIG_IDF_TARGET_ESP32 - WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name); -#else +#if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name); +#else + WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name); #endif } diff --git a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino index e486bd200fb..11f11a586bd 100644 --- a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino +++ b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino @@ -8,9 +8,15 @@ const char *service_name = "PROV_1234"; const char *pop = "abcd1234"; //GPIO for push button -static int gpio_0 = 0; +#if CONFIG_IDF_TARGET_ESP32C3 +static int gpio_0 = 9; +static int gpio_switch = 7; +#else //GPIO for virtual device +static int gpio_0 = 0; static int gpio_switch = 16; +#endif + /* Variable for reading pin status*/ bool switch_state = true; @@ -21,13 +27,13 @@ void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event->event_id) { case ARDUINO_EVENT_PROV_START: -#if CONFIG_IDF_TARGET_ESP32 - Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop); - printQR(service_name, pop, "ble"); -#else +#if CONFIG_IDF_TARGET_ESP32S2 Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop); printQR(service_name, pop, "softap"); -#endif +#else + Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop); + printQR(service_name, pop, "ble"); +#endif break; } } @@ -74,10 +80,10 @@ void setup() RMaker.start(); WiFi.onEvent(sysProvEvent); -#if CONFIG_IDF_TARGET_ESP32 - WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name); -#else +#if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name); +#else + WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name); #endif } diff --git a/libraries/Update/src/Updater.cpp b/libraries/Update/src/Updater.cpp index f9ecbfb057f..8d2b68db056 100644 --- a/libraries/Update/src/Updater.cpp +++ b/libraries/Update/src/Updater.cpp @@ -377,6 +377,8 @@ size_t UpdateClass::writeStream(Stream &data) { if((_bufferLen == remaining() || _bufferLen == SPI_FLASH_SEC_SIZE) && !_writeBuffer()) return written; written += toRead; + + delay(1); // Fix solo WDT } return written; } diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/WiFi/src/WiFiClient.cpp index c3e9fc86b29..968140597ae 100644 --- a/libraries/WiFi/src/WiFiClient.cpp +++ b/libraries/WiFi/src/WiFiClient.cpp @@ -175,11 +175,11 @@ class WiFiClientSocketHandle { } }; -WiFiClient::WiFiClient():_connected(false),next(NULL) +WiFiClient::WiFiClient():_connected(false),_timeout(WIFI_CLIENT_DEF_CONN_TIMEOUT_MS),next(NULL) { } -WiFiClient::WiFiClient(int fd):_connected(true),next(NULL) +WiFiClient::WiFiClient(int fd):_connected(true),_timeout(WIFI_CLIENT_DEF_CONN_TIMEOUT_MS),next(NULL) { clientSocketHandle.reset(new WiFiClientSocketHandle(fd)); _rxBuffer.reset(new WiFiClientRxBuffer(fd)); @@ -208,10 +208,11 @@ void WiFiClient::stop() int WiFiClient::connect(IPAddress ip, uint16_t port) { - return connect(ip,port,WIFI_CLIENT_DEF_CONN_TIMEOUT_MS); - } - int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout ) + return connect(ip,port,_timeout); +} +int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout) { + _timeout = timeout; int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { log_e("socket: %d", errno); @@ -230,7 +231,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port) FD_ZERO(&fdset); FD_SET(sockfd, &fdset); tv.tv_sec = 0; - tv.tv_usec = timeout * 1000; + tv.tv_usec = _timeout * 1000; #ifdef ESP_IDF_VERSION_MAJOR int res = lwip_connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); @@ -243,13 +244,13 @@ int WiFiClient::connect(IPAddress ip, uint16_t port) return 0; } - res = select(sockfd + 1, nullptr, &fdset, nullptr, timeout<0 ? nullptr : &tv); + res = select(sockfd + 1, nullptr, &fdset, nullptr, _timeout<0 ? nullptr : &tv); if (res < 0) { log_e("select on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno)); close(sockfd); return 0; } else if (res == 0) { - log_i("select returned due to timeout %d ms for fd %d", timeout, sockfd); + log_i("select returned due to timeout %d ms for fd %d", _timeout, sockfd); close(sockfd); return 0; } else { @@ -270,6 +271,14 @@ int WiFiClient::connect(IPAddress ip, uint16_t port) } } +#define ROE_WIFICLIENT(x,msg) { if (((x)<0)) { log_e("LWIP Socket config of " msg " failed."); return -1; }} + ROE_WIFICLIENT(lwip_setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),"SO_RCVTIMEO"); + ROE_WIFICLIENT(lwip_setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),"SO_SNDTIMEO"); + + // These are also set in WiFiClientSecure, should be set here too? + //ROE_WIFICLIENT(lwip_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)),"TCP_NODELAY"); + //ROE_WIFICLIENT (lwip_setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)),"SO_KEEPALIVE"); + fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) & (~O_NONBLOCK) ); clientSocketHandle.reset(new WiFiClientSocketHandle(sockfd)); _rxBuffer.reset(new WiFiClientRxBuffer(sockfd)); @@ -279,9 +288,10 @@ int WiFiClient::connect(IPAddress ip, uint16_t port) int WiFiClient::connect(const char *host, uint16_t port) { - return connect(host,port,WIFI_CLIENT_DEF_CONN_TIMEOUT_MS); - } - int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout ) + return connect(host,port,_timeout); +} + +int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout) { IPAddress srv((uint32_t)0); if(!WiFiGenericClass::hostByName(host, srv)){ @@ -301,14 +311,20 @@ int WiFiClient::setSocketOption(int option, char* value, size_t len) int WiFiClient::setTimeout(uint32_t seconds) { - Client::setTimeout(seconds * 1000); - struct timeval tv; - tv.tv_sec = seconds; - tv.tv_usec = 0; - if(setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { - return -1; + Client::setTimeout(seconds * 1000); // This should be here? + _timeout = seconds * 1000; + if(fd() >= 0) { + struct timeval tv; + tv.tv_sec = seconds; + tv.tv_usec = 0; + if(setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { + return -1; + } + return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); + } + else { + return 0; } - return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); } int WiFiClient::setOption(int option, int *value) diff --git a/libraries/WiFi/src/WiFiClient.h b/libraries/WiFi/src/WiFiClient.h index 4915cfd5203..5aaa6ba115e 100644 --- a/libraries/WiFi/src/WiFiClient.h +++ b/libraries/WiFi/src/WiFiClient.h @@ -42,6 +42,7 @@ class WiFiClient : public ESPLwIPClient std::shared_ptr clientSocketHandle; std::shared_ptr _rxBuffer; bool _connected; + int _timeout; public: WiFiClient *next; diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp b/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp index 4f7bc80263d..cf22082af06 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp +++ b/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp @@ -32,6 +32,7 @@ WiFiClientSecure::WiFiClientSecure() { _connected = false; + _timeout = 30000; // Same default as ssl_client sslclient = new sslclient_context; ssl_init(sslclient); @@ -52,7 +53,7 @@ WiFiClientSecure::WiFiClientSecure() WiFiClientSecure::WiFiClientSecure(int sock) { _connected = false; - _timeout = 0; + _timeout = 30000; // Same default as ssl_client sslclient = new sslclient_context; ssl_init(sslclient); @@ -128,9 +129,6 @@ int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *CA_cert, int WiFiClientSecure::connect(const char *host, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) { - if(_timeout > 0){ - sslclient->handshake_timeout = _timeout; - } int ret = start_ssl_client(sslclient, host, port, _timeout, CA_cert, _use_ca_bundle, cert, private_key, NULL, NULL, _use_insecure, _alpn_protos); _lastError = ret; if (ret < 0) { @@ -148,9 +146,6 @@ int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *pskIdent, int WiFiClientSecure::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) { log_v("start_ssl_client with PSK"); - if(_timeout > 0){ - sslclient->handshake_timeout = _timeout; - } int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, false, NULL, NULL, pskIdent, psKey, _use_insecure, _alpn_protos); _lastError = ret; if (ret < 0) { @@ -315,6 +310,7 @@ char *WiFiClientSecure::_streamLoad(Stream& stream, size_t size) { } bool WiFiClientSecure::loadCACert(Stream& stream, size_t size) { + if (_CA_cert != NULL) free(const_cast(_CA_cert)); char *dest = _streamLoad(stream, size); bool ret = false; if (dest) { @@ -325,6 +321,7 @@ bool WiFiClientSecure::loadCACert(Stream& stream, size_t size) { } bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size) { + if (_cert != NULL) free(const_cast(_cert)); char *dest = _streamLoad(stream, size); bool ret = false; if (dest) { @@ -335,6 +332,7 @@ bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size) { } bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size) { + if (_private_key != NULL) free(const_cast(_private_key)); char *dest = _streamLoad(stream, size); bool ret = false; if (dest) { @@ -362,3 +360,27 @@ void WiFiClientSecure::setAlpnProtocols(const char **alpn_protos) { _alpn_protos = alpn_protos; } +int WiFiClientSecure::setTimeout(uint32_t seconds) +{ + _timeout = seconds * 1000; + if (sslclient->socket >= 0) { + struct timeval tv; + tv.tv_sec = seconds; + tv.tv_usec = 0; + if(setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { + return -1; + } + return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); + } + else { + return 0; + } +} +int WiFiClientSecure::setSocketOption(int option, char* value, size_t len) +{ + int res = setsockopt(sslclient->socket, SOL_SOCKET, option, value, len); + if(res < 0) { + log_e("%X : %d", option, errno); + } + return res; +} diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.h b/libraries/WiFiClientSecure/src/WiFiClientSecure.h index 3a36b2fb9a8..9ea0c04eb4e 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.h +++ b/libraries/WiFiClientSecure/src/WiFiClientSecure.h @@ -32,7 +32,7 @@ class WiFiClientSecure : public WiFiClient int _lastError = 0; int _peek = -1; - int _timeout = 0; + int _timeout; bool _use_insecure; const char *_CA_cert; const char *_cert; @@ -79,7 +79,8 @@ class WiFiClientSecure : public WiFiClient void setAlpnProtocols(const char **alpn_protos); const mbedtls_x509_crt* getPeerCertificate() { return mbedtls_ssl_get_peer_cert(&sslclient->ssl_ctx); }; bool getFingerprintSHA256(uint8_t sha256_result[32]) { return get_peer_fingerprint(sslclient, sha256_result); }; - int setTimeout(uint32_t seconds){ return 0; } + int setTimeout(uint32_t seconds); + int setSocketOption(int option, char* value, size_t len); operator bool() { diff --git a/tools/platformio-build-esp32.py b/tools/platformio-build-esp32.py index a77e7a079ad..10890a1b3a0 100644 --- a/tools/platformio-build-esp32.py +++ b/tools/platformio-build-esp32.py @@ -24,7 +24,7 @@ # Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py -from os.path import abspath, isdir, isfile, join, basename +from os.path import abspath, isdir, isfile, join from SCons.Script import DefaultEnvironment @@ -331,6 +331,12 @@ ("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")), ("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")) ] + + [ + (offset, join(FRAMEWORK_DIR, img)) + for offset, img in env.BoardConfig().get( + "upload.arduino.flash_extra_images", [] + ) + ], ) # diff --git a/tools/platformio-build-esp32c3.py b/tools/platformio-build-esp32c3.py index 721666c9059..cddc251fc08 100644 --- a/tools/platformio-build-esp32c3.py +++ b/tools/platformio-build-esp32c3.py @@ -24,7 +24,7 @@ # Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py -from os.path import abspath, isdir, isfile, join, basename +from os.path import abspath, isdir, isfile, join from SCons.Script import DefaultEnvironment @@ -324,6 +324,12 @@ ("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")), ("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")) ] + + [ + (offset, join(FRAMEWORK_DIR, img)) + for offset, img in env.BoardConfig().get( + "upload.arduino.flash_extra_images", [] + ) + ], ) # diff --git a/tools/platformio-build-esp32s2.py b/tools/platformio-build-esp32s2.py index 9bafa646689..4e015b6aec2 100644 --- a/tools/platformio-build-esp32s2.py +++ b/tools/platformio-build-esp32s2.py @@ -24,7 +24,7 @@ # Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py -from os.path import abspath, isdir, isfile, join, basename +from os.path import abspath, isdir, isfile, join from SCons.Script import DefaultEnvironment @@ -326,6 +326,12 @@ ("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")), ("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")) ] + + [ + (offset, join(FRAMEWORK_DIR, img)) + for offset, img in env.BoardConfig().get( + "upload.arduino.flash_extra_images", [] + ) + ], ) # diff --git a/tools/platformio-build-esp32s3.py b/tools/platformio-build-esp32s3.py index a200a78b0b5..660fd4ef28d 100644 --- a/tools/platformio-build-esp32s3.py +++ b/tools/platformio-build-esp32s3.py @@ -24,7 +24,7 @@ # Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py -from os.path import abspath, isdir, isfile, join, basename +from os.path import abspath, isdir, isfile, join from SCons.Script import DefaultEnvironment @@ -343,6 +343,12 @@ ("0x8000", join(env.subst("$BUILD_DIR"), "partitions.bin")), ("0xe000", join(FRAMEWORK_DIR, "tools", "partitions", "boot_app0.bin")) ] + + [ + (offset, join(FRAMEWORK_DIR, img)) + for offset, img in env.BoardConfig().get( + "upload.arduino.flash_extra_images", [] + ) + ], ) # diff --git a/variants/AirM2M_CORE_ESP32C3/pins_arduino.h b/variants/AirM2M_CORE_ESP32C3/pins_arduino.h new file mode 100644 index 00000000000..d0510fe8326 --- /dev/null +++ b/variants/AirM2M_CORE_ESP32C3/pins_arduino.h @@ -0,0 +1,32 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define EXTERNAL_NUM_INTERRUPTS 22 +#define NUM_DIGITAL_PINS 22 +#define NUM_ANALOG_INPUTS 6 + +#define analogInputToDigitalPin(p) (((p) + +#define USB_VID 0x303A +#define USB_PID 0x8001 +#define USB_MANUFACTURER "Unexpected Maker" +#define USB_PRODUCT "RM Pro" +#define USB_SERIAL "" + +#define EXTERNAL_NUM_INTERRUPTS 46 +#define NUM_DIGITAL_PINS 48 +#define NUM_ANALOG_INPUTS 20 + +#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1) +#define digitalPinToInterrupt(p) (((p)<48)?(p):-1) +#define digitalPinHasPWM(p) (p < 46) + +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 SS = 14; +static const uint8_t MOSI = 35; +static const uint8_t MISO = 37; +static const uint8_t SDO = 35; +static const uint8_t SDI = 37; +static const uint8_t SCK = 36; + +static const uint8_t A0 = 1; +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +static const uint8_t A3 = 4; +static const uint8_t A4 = 5; +static const uint8_t A5 = 6; +static const uint8_t A6 = 7; +static const uint8_t A7 = 8; +static const uint8_t A8 = 9; +static const uint8_t A9 = 10; +static const uint8_t A10 = 11; +static const uint8_t A11 = 12; +static const uint8_t A12 = 13; +static const uint8_t A13 = 14; +static const uint8_t A14 = 15; +static const uint8_t A15 = 16; +static const uint8_t A16 = 17; +static const uint8_t A17 = 18; +static const uint8_t A18 = 19; +static const uint8_t A19 = 20; + +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 T7 = 7; +static const uint8_t T8 = 8; +static const uint8_t T9 = 9; +static const uint8_t T10 = 10; +static const uint8_t T11 = 11; +static const uint8_t T12 = 12; +static const uint8_t T13 = 13; +static const uint8_t T14 = 14; + +static const uint8_t DAC1 = 17; +static const uint8_t DAC2 = 18; + +static const uint8_t VBAT_SENSE = 3; +static const uint8_t VBUS_SENSE = 21; + +static const uint8_t RGB_DATA = 1; +static const uint8_t RGB_PWR = 2; + +#endif /* Pins_Arduino_h */ diff --git a/variants/um_tinys2/pins_arduino.h b/variants/um_tinys2/pins_arduino.h index 53197f6f6ee..a493a3fd78b 100644 --- a/variants/um_tinys2/pins_arduino.h +++ b/variants/um_tinys2/pins_arduino.h @@ -25,10 +25,10 @@ static const uint8_t SCL = 9; static const uint8_t SS = 14; static const uint8_t MOSI = 35; -static const uint8_t MISO = 36; +static const uint8_t MISO = 37; static const uint8_t SDO = 35; -static const uint8_t SDI = 36; -static const uint8_t SCK = 37; +static const uint8_t SDI = 37; +static const uint8_t SCK = 36; static const uint8_t A0 = 1; static const uint8_t A1 = 2;