From c6feed989a9c84e94b1d0a39a9c6781a38f0252e Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 19 Jan 2023 18:39:55 +0200 Subject: [PATCH 01/60] Initial changes to compile under ESP-IDF v5.1 --- CMakeLists.txt | 9 +- cores/esp32/Arduino.h | 4 +- cores/esp32/Esp.cpp | 13 +- cores/esp32/Esp.h | 3 +- cores/esp32/FirmwareMSC.cpp | 2 + cores/esp32/HWCDC.cpp | 1 + cores/esp32/USB.cpp | 2 + cores/esp32/USBCDC.cpp | 1 + cores/esp32/WMath.cpp | 1 + cores/esp32/esp32-hal-adc.c | 10 +- cores/esp32/esp32-hal-adc.h | 5 - cores/esp32/esp32-hal-dac.c | 2 +- cores/esp32/esp32-hal-i2c-slave.c | 75 +++--- cores/esp32/esp32-hal-i2c.c | 31 ++- cores/esp32/esp32-hal-ledc.c | 2 +- cores/esp32/esp32-hal-sigmadelta.c | 2 + cores/esp32/esp32-hal-tinyusb.c | 4 +- cores/esp32/esp32-hal-uart.c | 16 +- libraries/ArduinoOTA/src/ArduinoOTA.cpp | 4 +- libraries/AsyncUDP/src/AsyncUDP.cpp | 22 ++ libraries/AsyncUDP/src/AsyncUDP.h | 10 + libraries/BLE/src/BLEEddystoneTLM.cpp | 12 +- libraries/BLE/src/BLEUUID.cpp | 2 +- libraries/BLE/src/FreeRTOS.cpp | 2 +- libraries/BLE/src/GeneralUtils.cpp | 1 + .../src/BTAdvertisedDeviceSet.cpp | 2 +- .../BluetoothSerial/src/BluetoothSerial.cpp | 4 +- .../BluetoothSerial/src/BluetoothSerial.h | 2 +- .../ExampleTemplate/ExampleTemplate.ino | 16 -- .../Template/ExampleTemplate/README.md | 122 ---------- .../examples/Touch/TouchRead/TouchRead.ino | 2 +- libraries/ESPmDNS/src/ESPmDNS.cpp | 24 +- libraries/ESPmDNS/src/ESPmDNS.h | 3 +- libraries/Ethernet/src/ETH.cpp | 97 ++++---- libraries/Ethernet/src/ETH.h | 2 + libraries/SD/src/sd_diskio.cpp | 4 +- libraries/Update/src/HttpsOTAUpdate.cpp | 9 +- libraries/WebServer/src/WebServer.cpp | 8 +- libraries/WiFi/src/WiFiGeneric.cpp | 2 + libraries/WiFi/src/WiFiGeneric.h | 2 + libraries/WiFi/src/WiFiSTA.cpp | 1 + .../WiFiClientSecure/src/WiFiClientSecure.cpp | 4 +- .../WiFiClientSecure/src/esp_crt_bundle.c | 216 ------------------ .../WiFiClientSecure/src/esp_crt_bundle.h | 68 ------ libraries/WiFiClientSecure/src/ssl_client.cpp | 20 +- libraries/WiFiClientSecure/src/ssl_client.h | 2 +- 46 files changed, 265 insertions(+), 581 deletions(-) delete mode 100644 libraries/ESP32/examples/Template/ExampleTemplate/ExampleTemplate.ino delete mode 100644 libraries/ESP32/examples/Template/ExampleTemplate/README.md delete mode 100644 libraries/WiFiClientSecure/src/esp_crt_bundle.c delete mode 100644 libraries/WiFiClientSecure/src/esp_crt_bundle.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 851d1488eca..1a5c45c9d7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,8 @@ # export ARDUINO_SKIP_IDF_VERSION_CHECK=1 # idf.py build -set(min_supported_idf_version "4.4.0") -set(max_supported_idf_version "4.4.99") +set(min_supported_idf_version "5.1.0") +set(max_supported_idf_version "5.1.99") set(idf_version "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}") if ("${idf_version}" AND NOT "$ENV{ARDUINO_SKIP_IDF_VERSION_CHECK}") @@ -121,7 +121,6 @@ set(LIBRARY_SRCS libraries/WebServer/src/Parsing.cpp libraries/WebServer/src/detail/mimetable.cpp libraries/WiFiClientSecure/src/ssl_client.cpp - libraries/WiFiClientSecure/src/esp_crt_bundle.c libraries/WiFiClientSecure/src/WiFiClientSecure.cpp libraries/WiFi/src/WiFiAP.cpp libraries/WiFi/src/WiFiClient.cpp @@ -207,8 +206,8 @@ set(includedirs set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS}) set(priv_includes cores/esp32/libb64) -set(requires spi_flash mbedtls mdns esp_adc_cal wifi_provisioning nghttp wpa_supplicant) -set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support openssl bt esp_ipc esp_hid) +set(requires spi_flash mbedtls mdns wifi_provisioning wpa_supplicant esp_adc esp_eth http_parser) +set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support bt esp_hid esp_insights) idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires}) diff --git a/cores/esp32/Arduino.h b/cores/esp32/Arduino.h index 8b0aa220d98..112b244c12a 100644 --- a/cores/esp32/Arduino.h +++ b/cores/esp32/Arduino.h @@ -173,7 +173,6 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); #include "Udp.h" #include "HardwareSerial.h" #include "Esp.h" -#include "esp32/spiram.h" // Use float-compatible stl abs() and round(), we don't use Arduino macros to avoid issues with the C++ libraries using std::abs; @@ -192,7 +191,8 @@ size_t getArduinoLoopTaskStackSize(void); #define SET_LOOP_TASK_STACK_SIZE(sz) size_t getArduinoLoopTaskStackSize() { return sz;} // allows user to bypass esp_spiram_test() -#define BYPASS_SPIRAM_TEST(bypass) bool testSPIRAM(void) { if (bypass) return true; else return esp_spiram_test(); } +bool esp_psram_extram_test(void); +#define BYPASS_SPIRAM_TEST(bypass) bool testSPIRAM(void) { if (bypass) return true; else return esp_psram_extram_test(); } unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); diff --git a/cores/esp32/Esp.cpp b/cores/esp32/Esp.cpp index 4825b0d931c..37612300cd0 100644 --- a/cores/esp32/Esp.cpp +++ b/cores/esp32/Esp.cpp @@ -20,7 +20,7 @@ #include "Arduino.h" #include "Esp.h" #include "esp_sleep.h" -#include "esp_spi_flash.h" +#include "spi_flash_mmap.h" #include #include #include @@ -32,6 +32,9 @@ extern "C" { #include "soc/spi_reg.h" #include "esp_system.h" +#include "esp_chip_info.h" +#include "esp_mac.h" +#include "esp_flash.h" #ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ #if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 #include "esp32/rom/spi_flash.h" @@ -330,7 +333,7 @@ uint32_t EspClass::getFlashChipSize(void) uint32_t EspClass::getFlashChipSpeed(void) { esp_image_header_t fhdr; - if(flashRead(ESP_FLASH_IMAGE_BASE, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) { + if(esp_flash_read(esp_flash_default_chip, (void*)&fhdr, ESP_FLASH_IMAGE_BASE, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) { return 0; } return magicFlashChipSpeed(fhdr.spi_speed); @@ -405,18 +408,18 @@ FlashMode_t EspClass::magicFlashChipMode(uint8_t byte) bool EspClass::flashEraseSector(uint32_t sector) { - return spi_flash_erase_sector(sector) == ESP_OK; + return esp_flash_erase_region(esp_flash_default_chip, sector * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE) == ESP_OK; } // Warning: These functions do not work with encrypted flash bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) { - return spi_flash_write(offset, (uint32_t*) data, size) == ESP_OK; + return esp_flash_write(esp_flash_default_chip, (const void*) data, offset, size) == ESP_OK; } bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size) { - return spi_flash_read(offset, (uint32_t*) data, size) == ESP_OK; + return esp_flash_read(esp_flash_default_chip, (void*) data, offset, size) == ESP_OK; } bool EspClass::partitionEraseRange(const esp_partition_t *partition, uint32_t offset, size_t size) diff --git a/cores/esp32/Esp.h b/cores/esp32/Esp.h index 34ddb3bde11..7f4427c883e 100644 --- a/cores/esp32/Esp.h +++ b/cores/esp32/Esp.h @@ -23,6 +23,7 @@ #include #include #include +#include "esp_cpu.h" /** * AVR macros for WDT managment @@ -111,7 +112,7 @@ class EspClass uint32_t ARDUINO_ISR_ATTR EspClass::getCycleCount() { - return cpu_hal_get_cycle_count(); + return (uint32_t)esp_cpu_get_cycle_count(); } extern EspClass ESP; diff --git a/cores/esp32/FirmwareMSC.cpp b/cores/esp32/FirmwareMSC.cpp index e869cbef01c..638f1823499 100644 --- a/cores/esp32/FirmwareMSC.cpp +++ b/cores/esp32/FirmwareMSC.cpp @@ -18,9 +18,11 @@ #include #include "esp_partition.h" #include "esp_ota_ops.h" +#include "esp_image_format.h" #include "esp32-hal.h" #include "pins_arduino.h" #include "firmware_msc_fat.h" +#include "spi_flash_mmap.h" #ifndef USB_FW_MSC_VENDOR_ID #define USB_FW_MSC_VENDOR_ID "ESP32" //max 8 chars diff --git a/cores/esp32/HWCDC.cpp b/cores/esp32/HWCDC.cpp index 25744f0b0a3..fac4530f33a 100644 --- a/cores/esp32/HWCDC.cpp +++ b/cores/esp32/HWCDC.cpp @@ -23,6 +23,7 @@ #include "esp_intr_alloc.h" #include "soc/periph_defs.h" #include "hal/usb_serial_jtag_ll.h" +#include "rom/ets_sys.h" ESP_EVENT_DEFINE_BASE(ARDUINO_HW_CDC_EVENTS); diff --git a/cores/esp32/USB.cpp b/cores/esp32/USB.cpp index d82659ebbcf..60dcf3dc943 100644 --- a/cores/esp32/USB.cpp +++ b/cores/esp32/USB.cpp @@ -20,6 +20,8 @@ #include "esp32-hal-tinyusb.h" #include "common/tusb_common.h" #include "StreamString.h" +#include "rom/ets_sys.h" +#include "esp_mac.h" #ifndef USB_VID #define USB_VID USB_ESPRESSIF_VID diff --git a/cores/esp32/USBCDC.cpp b/cores/esp32/USBCDC.cpp index ccf5180d7c7..0eb7b0fde67 100644 --- a/cores/esp32/USBCDC.cpp +++ b/cores/esp32/USBCDC.cpp @@ -16,6 +16,7 @@ #include "USBCDC.h" #include "esp32-hal-tinyusb.h" +#include "rom/ets_sys.h" ESP_EVENT_DEFINE_BASE(ARDUINO_USB_CDC_EVENTS); esp_err_t arduino_usb_event_post(esp_event_base_t event_base, int32_t event_id, void *event_data, size_t event_data_size, TickType_t ticks_to_wait); diff --git a/cores/esp32/WMath.cpp b/cores/esp32/WMath.cpp index 078e18a8767..4632cf9d6fa 100644 --- a/cores/esp32/WMath.cpp +++ b/cores/esp32/WMath.cpp @@ -28,6 +28,7 @@ extern "C" { #include "esp_system.h" } #include "esp32-hal-log.h" +#include "esp_random.h" void randomSeed(unsigned long seed) { diff --git a/cores/esp32/esp32-hal-adc.c b/cores/esp32/esp32-hal-adc.c index 0fe73d14cbd..50a3d5e676e 100644 --- a/cores/esp32/esp32-hal-adc.c +++ b/cores/esp32/esp32-hal-adc.c @@ -26,7 +26,7 @@ static uint8_t __analogAttenuation = 3;//11db static uint8_t __analogWidth = ADC_WIDTH_MAX - 1; //3 for ESP32/ESP32C3; 4 for ESP32S2 -static uint8_t __analogReturnedWidth = SOC_ADC_MAX_BITWIDTH; //12 for ESP32/ESP32C3; 13 for ESP32S2 +static uint8_t __analogReturnedWidth = SOC_ADC_RTC_MAX_BITWIDTH; //12 for ESP32/ESP32C3; 13 for ESP32S2 static uint8_t __analogClockDiv = 1; static adc_attenuation_t __pin_attenuation[SOC_GPIO_PIN_COUNT]; @@ -256,13 +256,6 @@ void __analogSetVRefPin(uint8_t pin){ __analogVRefPin = pin; } -int __hallRead() //hall sensor using idf read -{ - pinMode(36, ANALOG); - pinMode(39, ANALOG); - __analogSetWidth(12); - return hall_sensor_read(); -} #endif extern uint16_t analogRead(uint8_t pin) __attribute__ ((weak, alias("__analogRead"))); @@ -277,5 +270,4 @@ extern bool adcAttachPin(uint8_t pin) __attribute__ ((weak, alias("__adcAttachPi #if CONFIG_IDF_TARGET_ESP32 extern void analogSetVRefPin(uint8_t pin) __attribute__ ((weak, alias("__analogSetVRefPin"))); extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth"))); -extern int hallRead() __attribute__ ((weak, alias("__hallRead"))); #endif diff --git a/cores/esp32/esp32-hal-adc.h b/cores/esp32/esp32-hal-adc.h index 1b094d8ebd0..c226384a422 100644 --- a/cores/esp32/esp32-hal-adc.h +++ b/cores/esp32/esp32-hal-adc.h @@ -90,11 +90,6 @@ void analogSetWidth(uint8_t bits); * */ void analogSetVRefPin(uint8_t pin); -/* - * Get value for HALL sensor (without LNA) - * connected to pins 36(SVP) and 39(SVN) - * */ -int hallRead(); #endif #ifdef __cplusplus diff --git a/cores/esp32/esp32-hal-dac.c b/cores/esp32/esp32-hal-dac.c index db1bb74b4d8..70a0e15e7d0 100644 --- a/cores/esp32/esp32-hal-dac.c +++ b/cores/esp32/esp32-hal-dac.c @@ -19,7 +19,7 @@ #define NODAC #else #include "soc/dac_channel.h" -#include "driver/dac_common.h" +#include "driver/dac.h" void ARDUINO_ISR_ATTR __dacWrite(uint8_t pin, uint8_t value) { diff --git a/cores/esp32/esp32-hal-i2c-slave.c b/cores/esp32/esp32-hal-i2c-slave.c index 16dc050e58d..5205df0410d 100644 --- a/cores/esp32/esp32-hal-i2c-slave.c +++ b/cores/esp32/esp32-hal-i2c-slave.c @@ -320,7 +320,7 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t } i2c_ll_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK); - i2c_ll_clr_intsts_mask(i2c->dev, I2C_LL_INTR_MASK); + i2c_ll_clear_intr_mask(i2c->dev, I2C_LL_INTR_MASK); i2c_ll_set_fifo_mode(i2c->dev, true); if (!i2c->intr_handle) { @@ -377,7 +377,7 @@ size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t tim log_e("Invalid port num: %u", num); return 0; } - size_t to_queue = 0, to_fifo = 0; + uint32_t to_queue = 0, to_fifo = 0; i2c_slave_struct_t * i2c = &_i2c_bus_array[num]; #if !CONFIG_DISABLE_HAL_LOCKS if(!i2c->lock){ @@ -391,35 +391,39 @@ size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t tim I2C_SLAVE_MUTEX_LOCK(); #if CONFIG_IDF_TARGET_ESP32 i2c_ll_slave_disable_tx_it(i2c->dev); - if (i2c_ll_get_txfifo_len(i2c->dev) < SOC_I2C_FIFO_LEN) { + uint32_t txfifo_len = 0; + i2c_ll_get_txfifo_len(i2c->dev, &txfifo_len); + if (txfifo_len < SOC_I2C_FIFO_LEN) { i2c_ll_txfifo_rst(i2c->dev); } #endif - to_fifo = i2c_ll_get_txfifo_len(i2c->dev); - if(len < to_fifo){ - to_fifo = len; - } - i2c_ll_write_txfifo(i2c->dev, (uint8_t*)buf, to_fifo); - buf += to_fifo; - len -= to_fifo; - //reset tx_queue - xQueueReset(i2c->tx_queue); - //write the rest of the bytes to the queue - if(len){ - to_queue = uxQueueSpacesAvailable(i2c->tx_queue); - if(len < to_queue){ - to_queue = len; + i2c_ll_get_txfifo_len(i2c->dev, &to_fifo); + if(to_fifo){ + if(len < to_fifo){ + to_fifo = len; } - for (size_t i = 0; i < to_queue; i++) { - if (xQueueSend(i2c->tx_queue, &buf[i], timeout_ms / portTICK_RATE_MS) != pdTRUE) { - xQueueReset(i2c->tx_queue); - to_queue = 0; - break; + i2c_ll_write_txfifo(i2c->dev, (uint8_t*)buf, to_fifo); + buf += to_fifo; + len -= to_fifo; + //reset tx_queue + xQueueReset(i2c->tx_queue); + //write the rest of the bytes to the queue + if(len){ + to_queue = uxQueueSpacesAvailable(i2c->tx_queue); + if(len < to_queue){ + to_queue = len; + } + for (size_t i = 0; i < to_queue; i++) { + if (xQueueSend(i2c->tx_queue, &buf[i], timeout_ms / portTICK_RATE_MS) != pdTRUE) { + xQueueReset(i2c->tx_queue); + to_queue = 0; + break; + } + } + //no need to enable TX_EMPTY if tx_queue is empty + if(to_queue){ + i2c_ll_slave_enable_tx_it(i2c->dev); } - } - //no need to enable TX_EMPTY if tx_queue is empty - if(to_queue){ - i2c_ll_slave_enable_tx_it(i2c->dev); } } I2C_SLAVE_MUTEX_UNLOCK(); @@ -434,7 +438,7 @@ static void i2c_slave_free_resources(i2c_slave_struct_t * i2c){ i2c_slave_detach_gpio(i2c); i2c_ll_set_slave_addr(i2c->dev, 0, false); i2c_ll_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK); - i2c_ll_clr_intsts_mask(i2c->dev, I2C_LL_INTR_MASK); + i2c_ll_clear_intr_mask(i2c->dev, I2C_LL_INTR_MASK); if (i2c->intr_handle) { esp_intr_free(i2c->intr_handle); @@ -485,13 +489,13 @@ static bool i2c_slave_set_frequency(i2c_slave_struct_t * i2c, uint32_t clk_speed uint32_t a = (clk_speed / 50000L) + 2; log_d("Fifo thresholds: rx_fifo_full = %d, tx_fifo_empty = %d", SOC_I2C_FIFO_LEN - a, a); - i2c_clk_cal_t clk_cal; + i2c_hal_clk_config_t clk_cal; #if SOC_I2C_SUPPORT_APB i2c_ll_cal_bus_clk(APB_CLK_FREQ, clk_speed, &clk_cal); - i2c_ll_set_source_clk(i2c->dev, I2C_SCLK_APB); /*!< I2C source clock from APB, 80M*/ + i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_APB); /*!< I2C source clock from APB, 80M*/ #elif SOC_I2C_SUPPORT_XTAL i2c_ll_cal_bus_clk(XTAL_CLK_FREQ, clk_speed, &clk_cal); - i2c_ll_set_source_clk(i2c->dev, I2C_SCLK_XTAL); /*!< I2C source clock from XTAL, 40M */ + i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_XTAL); /*!< I2C source clock from XTAL, 40M */ #endif i2c_ll_set_txfifo_empty_thr(i2c->dev, a); i2c_ll_set_rxfifo_full_thr(i2c->dev, SOC_I2C_FIFO_LEN - a); @@ -630,7 +634,8 @@ static bool i2c_slave_send_event(i2c_slave_struct_t * i2c, i2c_slave_queue_event static bool i2c_slave_handle_tx_fifo_empty(i2c_slave_struct_t * i2c) { bool pxHigherPriorityTaskWoken = false; - uint32_t d = 0, moveCnt = i2c_ll_get_txfifo_len(i2c->dev); + uint32_t d = 0, moveCnt = 0; + i2c_ll_get_txfifo_len(i2c->dev, &moveCnt); while (moveCnt > 0) { // read tx queue until Fifo is full or queue is empty if(xQueueReceiveFromISR(i2c->tx_queue, &d, (BaseType_t * const)&pxHigherPriorityTaskWoken) == pdTRUE){ i2c_ll_write_txfifo(i2c->dev, (uint8_t*)&d, 1); @@ -680,9 +685,11 @@ static void i2c_slave_isr_handler(void* arg) bool pxHigherPriorityTaskWoken = false; i2c_slave_struct_t * i2c = (i2c_slave_struct_t *) arg; // recover data - uint32_t activeInt = i2c_ll_get_intsts_mask(i2c->dev); - i2c_ll_clr_intsts_mask(i2c->dev, activeInt); - uint8_t rx_fifo_len = i2c_ll_get_rxfifo_cnt(i2c->dev); + uint32_t activeInt = 0; + i2c_ll_get_intr_mask(i2c->dev, &activeInt); + i2c_ll_clear_intr_mask(i2c->dev, activeInt); + uint32_t rx_fifo_len = 0; + i2c_ll_get_rxfifo_cnt(i2c->dev, &rx_fifo_len); bool slave_rw = i2c_ll_slave_rw(i2c->dev); if(activeInt & I2C_RXFIFO_WM_INT_ENA){ // RX FiFo Full diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index 4538a7ef076..c3f98e517bb 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -276,24 +276,41 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency){ #define I2C_CLK_LIMIT_XTAL (40 * 1000 * 1000 / 20) /*!< Limited by RTC, no more than XTAL/20*/ typedef struct { - uint8_t character; /*!< I2C source clock characteristic */ + soc_module_clk_t clk; /*!< I2C source clock */ uint32_t clk_freq; /*!< I2C source clock frequency */ } i2c_clk_alloc_t; + typedef enum { + I2C_SCLK_DEFAULT = 0, /*!< I2C source clock not selected*/ + #if SOC_I2C_SUPPORT_APB + I2C_SCLK_APB, /*!< I2C source clock from APB, 80M*/ + #endif + #if SOC_I2C_SUPPORT_XTAL + I2C_SCLK_XTAL, /*!< I2C source clock from XTAL, 40M */ + #endif + #if SOC_I2C_SUPPORT_RTC + I2C_SCLK_RTC, /*!< I2C source clock from 8M RTC, 8M */ + #endif + #if SOC_I2C_SUPPORT_REF_TICK + I2C_SCLK_REF_TICK, /*!< I2C source clock from REF_TICK, 1M */ + #endif + I2C_SCLK_MAX, + } i2c_sclk_t; + // i2c clock characteristic, The order is the same as i2c_sclk_t. static i2c_clk_alloc_t i2c_clk_alloc[I2C_SCLK_MAX] = { {0, 0}, #if SOC_I2C_SUPPORT_APB - {0, I2C_CLK_LIMIT_APB}, /*!< I2C APB clock characteristic*/ + {SOC_MOD_CLK_APB, I2C_CLK_LIMIT_APB}, /*!< I2C APB clock characteristic*/ #endif #if SOC_I2C_SUPPORT_XTAL - {0, I2C_CLK_LIMIT_XTAL}, /*!< I2C XTAL characteristic*/ + {SOC_MOD_CLK_XTAL, I2C_CLK_LIMIT_XTAL}, /*!< I2C XTAL characteristic*/ #endif #if SOC_I2C_SUPPORT_RTC - {I2C_SCLK_SRC_FLAG_LIGHT_SLEEP | I2C_SCLK_SRC_FLAG_AWARE_DFS, I2C_CLK_LIMIT_RTC}, /*!< I2C 20M RTC characteristic*/ + {SOC_MOD_CLK_RC_FAST, I2C_CLK_LIMIT_RTC}, /*!< I2C 20M RTC characteristic*/ #endif #if SOC_I2C_SUPPORT_REF_TICK - {I2C_SCLK_SRC_FLAG_AWARE_DFS, I2C_CLK_LIMIT_REF_TICK}, /*!< I2C REF_TICK characteristic*/ + {SOC_MOD_CLK_REF_TICK, I2C_CLK_LIMIT_REF_TICK},/*!< I2C REF_TICK characteristic*/ #endif }; @@ -310,13 +327,13 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency){ break; } } - if(src_clk == I2C_SCLK_MAX){ + if(src_clk == I2C_SCLK_DEFAULT || src_clk == I2C_SCLK_MAX){ log_e("clock source could not be selected"); ret = ESP_FAIL; } else { i2c_hal_context_t hal; hal.dev = I2C_LL_GET_HW(i2c_num); - i2c_hal_set_bus_timing(&(hal), frequency, src_clk); + i2c_hal_set_bus_timing(&(hal), frequency, i2c_clk_alloc[src_clk].clk, i2c_clk_alloc[src_clk].clk_freq); 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); diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c index a02431b58fb..22c996ff75b 100644 --- a/cores/esp32/esp32-hal-ledc.c +++ b/cores/esp32/esp32-hal-ledc.c @@ -30,7 +30,7 @@ #define LEDC_DEFAULT_CLK LEDC_AUTO_CLK #endif -#define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM +#define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDTH /* * LEDC Chan to Group/Channel/Timer Mapping diff --git a/cores/esp32/esp32-hal-sigmadelta.c b/cores/esp32/esp32-hal-sigmadelta.c index 82ba1a289fb..8ee648373ba 100644 --- a/cores/esp32/esp32-hal-sigmadelta.c +++ b/cores/esp32/esp32-hal-sigmadelta.c @@ -18,6 +18,8 @@ #include "soc/soc_caps.h" #include "driver/sigmadelta.h" +#define SOC_SIGMADELTA_CHANNEL_NUM (SOC_SDM_GROUPS * SOC_SDM_CHANNELS_PER_GROUP) + static uint8_t duty_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0}; static uint32_t prescaler_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0}; diff --git a/cores/esp32/esp32-hal-tinyusb.c b/cores/esp32/esp32-hal-tinyusb.c index 8bf9932d2e4..449b86755df 100644 --- a/cores/esp32/esp32-hal-tinyusb.c +++ b/cores/esp32/esp32-hal-tinyusb.c @@ -18,6 +18,8 @@ #include "soc/timer_group_struct.h" #include "soc/system_reg.h" +#include "rom/gpio.h" + #include "hal/usb_hal.h" #include "hal/gpio_ll.h" @@ -27,8 +29,6 @@ #include "driver/gpio.h" #include "driver/periph_ctrl.h" -#include "esp_efuse.h" -#include "esp_efuse_table.h" #include "esp_rom_gpio.h" #include "esp32-hal.h" diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index e6247bc893c..2cd8e340cbb 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -23,6 +23,8 @@ #include "soc/soc_caps.h" #include "soc/uart_struct.h" #include "soc/uart_periph.h" +#include "rom/ets_sys.h" +#include "rom/gpio.h" #include "driver/gpio.h" #include "hal/gpio_hal.h" @@ -458,18 +460,26 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) return; } UART_MUTEX_LOCK(); - uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate)); + uint32_t sclk_freq; + if(uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq) == ESP_OK){ + uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate), sclk_freq); + } UART_MUTEX_UNLOCK(); } uint32_t uartGetBaudRate(uart_t* uart) { + uint32_t baud_rate = 0; + uint32_t sclk_freq; + if(uart == NULL) { return 0; } UART_MUTEX_LOCK(); - uint32_t baud_rate = uart_ll_get_baudrate(UART_LL_GET_HW(uart->num)); + if(uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq) == ESP_OK){ + baud_rate = uart_ll_get_baudrate(UART_LL_GET_HW(uart->num), sclk_freq); + } UART_MUTEX_UNLOCK(); return baud_rate; } @@ -786,7 +796,7 @@ void uart_send_break(uint8_t uartNum) // This is very sensetive timing... it works fine for SERIAL_8N1 uint32_t breakTime = (uint32_t) (10.0 * (1000000.0 / currentBaudrate)); uart_set_line_inverse(uartNum, UART_SIGNAL_TXD_INV); - ets_delay_us(breakTime); + esp_rom_delay_us(breakTime); uart_set_line_inverse(uartNum, UART_SIGNAL_INV_DISABLE); } diff --git a/libraries/ArduinoOTA/src/ArduinoOTA.cpp b/libraries/ArduinoOTA/src/ArduinoOTA.cpp index fe85580f566..f7ad9105813 100644 --- a/libraries/ArduinoOTA/src/ArduinoOTA.cpp +++ b/libraries/ArduinoOTA/src/ArduinoOTA.cpp @@ -287,7 +287,7 @@ void ArduinoOTAClass::_runUpdate() { if (!waited){ if(written && tried++ < 3){ log_i("Try[%u]: %u", tried, written); - if(!client.printf("%u", written)){ + if(!client.printf("%lu", written)){ log_e("failed to respond"); _state = OTA_IDLE; break; @@ -322,7 +322,7 @@ void ArduinoOTAClass::_runUpdate() { if(written != r){ log_w("didn't write enough! %u != %u", written, r); } - if(!client.printf("%u", written)){ + if(!client.printf("%lu", written)){ log_w("failed to respond"); } total += written; diff --git a/libraries/AsyncUDP/src/AsyncUDP.cpp b/libraries/AsyncUDP/src/AsyncUDP.cpp index 069cce7ba82..92f9e2a827b 100644 --- a/libraries/AsyncUDP/src/AsyncUDP.cpp +++ b/libraries/AsyncUDP/src/AsyncUDP.cpp @@ -15,6 +15,28 @@ extern "C" { #include "lwip/priv/tcpip_priv.h" +static const char * netif_ifkeys[TCPIP_ADAPTER_IF_MAX] = { + "WIFI_STA_DEF", "WIFI_AP_DEF", "ETH_DEF", "PPP_DEF" +}; + +static esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif){ + *netif = NULL; + if(tcpip_if < TCPIP_ADAPTER_IF_MAX){ + esp_netif_t *esp_netif = esp_netif_get_handle_from_ifkey(netif_ifkeys[tcpip_if]); + if(esp_netif == NULL){ + return ESP_FAIL; + } + int netif_index = esp_netif_get_netif_impl_index(esp_netif); + if(netif_index < 0){ + return ESP_FAIL; + } + *netif = (void*)netif_get_by_index(netif_index); + } else { + *netif = netif_default; + } + return (*netif != NULL)?ESP_OK:ESP_FAIL; +} + typedef struct { struct tcpip_api_call_data call; udp_pcb * pcb; diff --git a/libraries/AsyncUDP/src/AsyncUDP.h b/libraries/AsyncUDP/src/AsyncUDP.h index be04c01ffaa..963a67e3a6c 100644 --- a/libraries/AsyncUDP/src/AsyncUDP.h +++ b/libraries/AsyncUDP/src/AsyncUDP.h @@ -8,10 +8,20 @@ #include extern "C" { #include "esp_netif.h" +#include "lwip/ip_addr.h" #include "freertos/queue.h" #include "freertos/semphr.h" } +// This enum and it's uses are copied and adapted for compatibility from ESP-IDF 4- +typedef enum { + TCPIP_ADAPTER_IF_STA = 0, /**< Wi-Fi STA (station) interface */ + TCPIP_ADAPTER_IF_AP, /**< Wi-Fi soft-AP interface */ + TCPIP_ADAPTER_IF_ETH, /**< Ethernet interface */ + TCPIP_ADAPTER_IF_PPP, /**< PPP interface */ + TCPIP_ADAPTER_IF_MAX +} tcpip_adapter_if_t; + class AsyncUDP; class AsyncUDPPacket; class AsyncUDPMessage; diff --git a/libraries/BLE/src/BLEEddystoneTLM.cpp b/libraries/BLE/src/BLEEddystoneTLM.cpp index 10cc657a23c..4469e4d5ca5 100644 --- a/libraries/BLE/src/BLEEddystoneTLM.cpp +++ b/libraries/BLE/src/BLEEddystoneTLM.cpp @@ -78,30 +78,30 @@ std::string BLEEddystoneTLM::toString() { out += " C\n"; out += "Adv. Count "; - snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U32(m_eddystoneData.advCount)); + snprintf(val, sizeof(val), "%ld", ENDIAN_CHANGE_U32(m_eddystoneData.advCount)); out += val; out += "\n"; out += "Time in seconds "; - snprintf(val, sizeof(val), "%d", rawsec/10); + snprintf(val, sizeof(val), "%ld", rawsec/10); out += val; out += "\n"; out += "Time "; - snprintf(val, sizeof(val), "%04d", rawsec / 864000); + snprintf(val, sizeof(val), "%04ld", rawsec / 864000); out += val; out += "."; - snprintf(val, sizeof(val), "%02d", (rawsec / 36000) % 24); + snprintf(val, sizeof(val), "%02ld", (rawsec / 36000) % 24); out += val; out += ":"; - snprintf(val, sizeof(val), "%02d", (rawsec / 600) % 60); + snprintf(val, sizeof(val), "%02ld", (rawsec / 600) % 60); out += val; out += ":"; - snprintf(val, sizeof(val), "%02d", (rawsec / 10) % 60); + snprintf(val, sizeof(val), "%02ld", (rawsec / 10) % 60); out += val; out += "\n"; diff --git a/libraries/BLE/src/BLEUUID.cpp b/libraries/BLE/src/BLEUUID.cpp index 45f698afb3a..3cbb34a5271 100644 --- a/libraries/BLE/src/BLEUUID.cpp +++ b/libraries/BLE/src/BLEUUID.cpp @@ -359,7 +359,7 @@ std::string BLEUUID::toString() { if (m_uuid.len == ESP_UUID_LEN_32) { // If the UUID is 32bit, pad correctly. char hex[9]; - snprintf(hex, sizeof(hex), "%08x", m_uuid.uuid.uuid32); + snprintf(hex, sizeof(hex), "%08lx", m_uuid.uuid.uuid32); return std::string(hex) + "-0000-1000-8000-00805f9b34fb"; } // End 32bit UUID diff --git a/libraries/BLE/src/FreeRTOS.cpp b/libraries/BLE/src/FreeRTOS.cpp index 115ef272c19..bab471dc44a 100644 --- a/libraries/BLE/src/FreeRTOS.cpp +++ b/libraries/BLE/src/FreeRTOS.cpp @@ -236,7 +236,7 @@ bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) { std::string FreeRTOS::Semaphore::toString() { char hex[9]; std::string res = "name: " + m_name + " (0x"; - snprintf(hex, sizeof(hex), "%08x", (uint32_t)m_semaphore); + snprintf(hex, sizeof(hex), "%08lx", (uint32_t)m_semaphore); res += hex; res += "), owner: " + m_owner; return res; diff --git a/libraries/BLE/src/GeneralUtils.cpp b/libraries/BLE/src/GeneralUtils.cpp index e1e5cca879f..8eef970faff 100644 --- a/libraries/BLE/src/GeneralUtils.cpp +++ b/libraries/BLE/src/GeneralUtils.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "esp_chip_info.h" #include "esp32-hal-log.h" static const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp b/libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp index 8a9e26e4d5a..94d3dc1de73 100644 --- a/libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp +++ b/libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp @@ -42,7 +42,7 @@ std::string BTAdvertisedDeviceSet::toString() { std::string res = "Name: " + getName() + ", Address: " + getAddress().toString(); if (haveCOD()) { char val[6]; - snprintf(val, sizeof(val), "%d", getCOD()); + snprintf(val, sizeof(val), "%ld", getCOD()); res += ", cod: "; res += val; } diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index 800ef97e68c..e430fe7255e 100644 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -54,7 +54,7 @@ static TaskHandle_t _spp_task_handle = NULL; static EventGroupHandle_t _spp_event_group = NULL; static EventGroupHandle_t _bt_event_group = NULL; static boolean secondConnectionAttempt; -static esp_spp_cb_t custom_spp_callback = NULL; +static esp_spp_cb_t * custom_spp_callback = NULL; static BluetoothSerialDataCb custom_data_callback = NULL; static esp_bd_addr_t current_bd_addr; static ConfirmRequestCb confirm_request_callback = NULL; @@ -886,7 +886,7 @@ void BluetoothSerial::confirmReply(boolean confirm) } -esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t callback) +esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback) { custom_spp_callback = callback; return ESP_OK; diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index 4b225239333..0c087b06360 100644 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -53,7 +53,7 @@ class BluetoothSerial: public Stream void end(void); void setTimeout(int timeoutMS); void onData(BluetoothSerialDataCb cb); - esp_err_t register_callback(esp_spp_cb_t callback); + esp_err_t register_callback(esp_spp_cb_t * callback); void onConfirmRequest(ConfirmRequestCb cb); void onAuthComplete(AuthCompleteCb cb); diff --git a/libraries/ESP32/examples/Template/ExampleTemplate/ExampleTemplate.ino b/libraries/ESP32/examples/Template/ExampleTemplate/ExampleTemplate.ino deleted file mode 100644 index ff9733d1cd4..00000000000 --- a/libraries/ESP32/examples/Template/ExampleTemplate/ExampleTemplate.ino +++ /dev/null @@ -1,16 +0,0 @@ -/* Arduino Example Template - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -void setup() { - -} - -void loop() { - -} diff --git a/libraries/ESP32/examples/Template/ExampleTemplate/README.md b/libraries/ESP32/examples/Template/ExampleTemplate/README.md deleted file mode 100644 index 9819880d4f4..00000000000 --- a/libraries/ESP32/examples/Template/ExampleTemplate/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Arduino-ESP32 Example/Library Name ==(REQUIRED)== - -==*Add a brief description of this example/library here!*== - -This example/library demonstrates how to create a new example README file. - -# Supported Targets ==(REQUIRED)== - -==*Add the supported devices here!*== - -Currently, this example supports the following targets. - -| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | -| ----------------- | ----- | -------- | -------- | - -## How to Use Example/Library ==(OPTIONAL)== - -==*Add a brief description of how to use this example.*== - -* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). - -### Hardware Connection ==(OPTIONAL)== - -==*Add a brief description of wiring or any other hardware-specific connection.*== - -To use this example, you need to connect the LED to the `GPIOx`. - -SDCard GPIO connection scheme: - -| SDCard Pin | Function | GPIO | -| ----------- | -------- | ------ | -| 1 | CS | GPIO5 | -| 2 | DI/MOSI | GPIO23 | -| 3 | VSS/GND | GND | -| 4 | VDD/3V3 | 3V3 | -| 5 | SCLK | GPIO18 | -| 6 | VSS/GND | GND | -| 7 | DO/MISO | GPIO19 | - -To add images, please create a folder `_asset` inside the example folder to add the relevant images. - -### Configure the Project ==(OPTIONAL)== - -==*Add a brief description of this example here!*== - -Set the LED GPIO by changing the `LED_BUILTIN` value in the function `pinMode(LED_BUILTIN, OUTPUT);`. By default, the GPIO is: `GPIOx`. - -#### Example for the GPIO4: - -==*Add some code explanation if relevant to the example.*== - -```cpp -// the setup function runs once when you press reset or power the board -void setup() { -// initialize digital pin 4 as an output. -pinMode(4, OUTPUT); -} -``` - -#### Using Arduino IDE - -To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). - -* Before Compile/Verify, select the correct board: `Tools -> Board`. -* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. - -#### Using Platform IO - -* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. - -## Example/Log Output ==(OPTIONAL)== - -==*Add the log/serial output here!*== - -``` -ets Jul 29 2019 12:21:46 - -rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) -configsip: 0, SPIWP:0xee -clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 -mode:DIO, clock div:1 -load:0x3fff0030,len:1412 -load:0x40078000,len:13400 -load:0x40080400,len:3672 -entry 0x400805f8 -ESP32 Chip model = ESP32-D0WDQ5 Rev 3 -This chip has 2 cores -Chip ID: 3957392 -``` - -## Troubleshooting ==(REQUIRED)== - -==*Add specific issues you may find by using this example here!*== - -***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** - -* **LED not blinking:** Check the wiring connection and the IO selection. -* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. -* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. - -If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). - -## Contribute ==(REQUIRED)== - -==*Do not change! Keep it as is.*== - -To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) - -If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! - -Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. - -## Resources ==(REQUIRED)== - -==*Do not change here! Keep it as is or add only relevant documents/info for this example. Do not add any purchase link/marketing stuff*== - -* Official ESP32 Forum: [Link](https://esp32.com) -* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) -* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) -* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) -* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) -* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino b/libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino index 27b1480b0de..57312c62587 100644 --- a/libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino +++ b/libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino @@ -10,6 +10,6 @@ void setup() void loop() { - Serial.println(touchRead(T1)); // get value using T1 + Serial.println(touchRead(T1)); // get value using T0 delay(1000); } diff --git a/libraries/ESPmDNS/src/ESPmDNS.cpp b/libraries/ESPmDNS/src/ESPmDNS.cpp index 77ab313a08f..36a4043b084 100644 --- a/libraries/ESPmDNS/src/ESPmDNS.cpp +++ b/libraries/ESPmDNS/src/ESPmDNS.cpp @@ -111,18 +111,18 @@ void MDNSResponder::disableArduino(){ } } -void MDNSResponder::enableWorkstation(esp_interface_t interface){ - char winstance[21+_hostname.length()]; - uint8_t mac[6]; - esp_wifi_get_mac((wifi_interface_t)interface, mac); - sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", _hostname.c_str(), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - if(mdns_service_add(NULL, "_workstation", "_tcp", 9, NULL, 0)) { - log_e("Failed adding Workstation service"); - } else if(mdns_service_instance_name_set("_workstation", "_tcp", winstance)) { - log_e("Failed setting Workstation service instance name"); - } -} +// void MDNSResponder::enableWorkstation(esp_interface_t interface){ +// char winstance[21+_hostname.length()]; +// uint8_t mac[6]; +// esp_wifi_get_mac((wifi_interface_t)interface, mac); +// sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", _hostname.c_str(), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + +// if(mdns_service_add(NULL, "_workstation", "_tcp", 9, NULL, 0)) { +// log_e("Failed adding Workstation service"); +// } else if(mdns_service_instance_name_set("_workstation", "_tcp", winstance)) { +// log_e("Failed setting Workstation service instance name"); +// } +// } void MDNSResponder::disableWorkstation(){ if(mdns_service_remove("_workstation", "_tcp")) { diff --git a/libraries/ESPmDNS/src/ESPmDNS.h b/libraries/ESPmDNS/src/ESPmDNS.h index 16c590d4a87..240fda0b1ed 100644 --- a/libraries/ESPmDNS/src/ESPmDNS.h +++ b/libraries/ESPmDNS/src/ESPmDNS.h @@ -84,7 +84,8 @@ class MDNSResponder { void enableArduino(uint16_t port=3232, bool auth=false); void disableArduino(); - void enableWorkstation(esp_interface_t interface=ESP_IF_WIFI_STA); + #warning This needs fixing for IDF 5.1 + //void enableWorkstation(esp_interface_t interface=ESP_IF_WIFI_STA); void disableWorkstation(); IPAddress queryHost(char *host, uint32_t timeout=2000); diff --git a/libraries/Ethernet/src/ETH.cpp b/libraries/Ethernet/src/ETH.cpp index a9be448e6ac..2dd2c1f9a30 100644 --- a/libraries/Ethernet/src/ETH.cpp +++ b/libraries/Ethernet/src/ETH.cpp @@ -39,6 +39,11 @@ #endif #include "lwip/err.h" #include "lwip/dns.h" +#include "esp_mac.h" +#include "esp_netif.h" +#include "esp_netif_types.h" +#include "esp_netif_defaults.h" +#include "esp_eth_phy.h" extern void tcpipInit(); @@ -229,6 +234,10 @@ ETHClass::~ETHClass() bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode, bool use_mac_from_efuse) { #if ESP_IDF_VERSION_MAJOR > 3 + if(esp_netif != NULL){ + return true; + } + eth_clock_mode = clock_mode; tcpipInit(); @@ -239,10 +248,10 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ esp_base_mac_addr_set(p); } - tcpip_adapter_set_default_eth_handlers(); + //tcpip_adapter_set_default_eth_handlers(); esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); - esp_netif_t *eth_netif = esp_netif_new(&cfg); + esp_netif = esp_netif_new(&cfg); esp_eth_mac_t *eth_mac = NULL; #if CONFIG_ETH_SPI_ETHERNET_DM9051 @@ -251,13 +260,16 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ } else { #endif #if CONFIG_ETH_USE_ESP32_EMAC - eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); + eth_esp32_emac_config_t mac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); mac_config.clock_config.rmii.clock_mode = (eth_clock_mode) ? EMAC_CLK_OUT : EMAC_CLK_EXT_IN; mac_config.clock_config.rmii.clock_gpio = (1 == eth_clock_mode) ? EMAC_APPL_CLK_OUT_GPIO : (2 == eth_clock_mode) ? EMAC_CLK_OUT_GPIO : (3 == eth_clock_mode) ? EMAC_CLK_OUT_180_GPIO : EMAC_CLK_IN_GPIO; mac_config.smi_mdc_gpio_num = mdc; mac_config.smi_mdio_gpio_num = mdio; - mac_config.sw_reset_timeout_ms = 1000; - eth_mac = esp_eth_mac_new_esp32(&mac_config); + + eth_mac_config_t eth_mac_config = ETH_MAC_DEFAULT_CONFIG(); + eth_mac_config.sw_reset_timeout_ms = 1000; + + eth_mac = esp_eth_mac_new_esp32(&mac_config, ð_mac_config); #endif #if CONFIG_ETH_SPI_ETHERNET_DM9051 } @@ -274,7 +286,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ esp_eth_phy_t *eth_phy = NULL; switch(type){ case ETH_PHY_LAN8720: - eth_phy = esp_eth_phy_new_lan8720(&phy_config); + eth_phy = esp_eth_phy_new_lan87xx(&phy_config); break; case ETH_PHY_TLK110: eth_phy = esp_eth_phy_new_ip101(&phy_config); @@ -292,14 +304,14 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ #endif case ETH_PHY_KSZ8041: #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4,4,0) - eth_phy = esp_eth_phy_new_ksz8041(&phy_config); + eth_phy = esp_eth_phy_new_ksz80xx(&phy_config); #else log_e("unsupported ethernet type 'ETH_PHY_KSZ8041'"); #endif break; case ETH_PHY_KSZ8081: #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4,4,0) - eth_phy = esp_eth_phy_new_ksz8081(&phy_config); + eth_phy = esp_eth_phy_new_ksz80xx(&phy_config); #else log_e("unsupported ethernet type 'ETH_PHY_KSZ8081'"); #endif @@ -322,7 +334,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ } /* attach Ethernet driver to TCP/IP stack */ - if(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)) != ESP_OK){ + if(esp_netif_attach(esp_netif, esp_eth_new_netif_glue(eth_handle)) != ESP_OK){ log_e("esp_netif_attach failed"); return false; } @@ -402,7 +414,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) { esp_err_t err = ESP_OK; - tcpip_adapter_ip_info_t info; + esp_netif_ip_info_t info; if(static_cast(local_ip) != 0){ info.ip.addr = static_cast(local_ip); @@ -414,42 +426,42 @@ bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, I info.netmask.addr = 0; } - err = tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_ETH); - if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED){ + err = esp_netif_dhcpc_stop(esp_netif); + if(err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED){ log_e("DHCP could not be stopped! Error: %d", err); return false; } - err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_ETH, &info); + err = esp_netif_set_ip_info(esp_netif, &info); if(err != ERR_OK){ - log_e("STA IP could not be configured! Error: %d", err); + log_e("ETH IP could not be configured! Error: %d", err); return false; } if(info.ip.addr){ staticIP = true; } else { - err = tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH); - if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED){ + err = esp_netif_dhcpc_start(esp_netif); + if(err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED){ log_w("DHCP could not be started! Error: %d", err); return false; } staticIP = false; } - ip_addr_t d; - d.type = IPADDR_TYPE_V4; + esp_netif_dns_info_t d; + d.ip.type = IPADDR_TYPE_V4; if(static_cast(dns1) != 0) { // Set DNS1-Server - d.u_addr.ip4.addr = static_cast(dns1); - dns_setserver(0, &d); + d.ip.u_addr.ip4.addr = static_cast(dns1); + esp_netif_set_dns_info(esp_netif, ESP_NETIF_DNS_MAIN, &d); } if(static_cast(dns2) != 0) { // Set DNS2-Server - d.u_addr.ip4.addr = static_cast(dns2); - dns_setserver(1, &d); + d.ip.u_addr.ip4.addr = static_cast(dns2); + esp_netif_set_dns_info(esp_netif, ESP_NETIF_DNS_BACKUP, &d); } return true; @@ -457,8 +469,8 @@ bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, I IPAddress ETHClass::localIP() { - tcpip_adapter_ip_info_t ip; - if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(esp_netif, &ip)){ return IPAddress(); } return IPAddress(ip.ip.addr); @@ -466,8 +478,8 @@ IPAddress ETHClass::localIP() IPAddress ETHClass::subnetMask() { - tcpip_adapter_ip_info_t ip; - if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(esp_netif, &ip)){ return IPAddress(); } return IPAddress(ip.netmask.addr); @@ -475,8 +487,8 @@ IPAddress ETHClass::subnetMask() IPAddress ETHClass::gatewayIP() { - tcpip_adapter_ip_info_t ip; - if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(esp_netif, &ip)){ return IPAddress(); } return IPAddress(ip.gw.addr); @@ -484,14 +496,17 @@ IPAddress ETHClass::gatewayIP() IPAddress ETHClass::dnsIP(uint8_t dns_no) { - const ip_addr_t * dns_ip = dns_getserver(dns_no); - return IPAddress(dns_ip->u_addr.ip4.addr); + esp_netif_dns_info_t d; + if(esp_netif_get_dns_info(esp_netif, dns_no?ESP_NETIF_DNS_BACKUP:ESP_NETIF_DNS_MAIN, &d) != ESP_OK){ + return IPAddress(); + } + return IPAddress(d.ip.u_addr.ip4.addr); } IPAddress ETHClass::broadcastIP() { - tcpip_adapter_ip_info_t ip; - if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(esp_netif, &ip)){ return IPAddress(); } return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); @@ -499,8 +514,8 @@ IPAddress ETHClass::broadcastIP() IPAddress ETHClass::networkID() { - tcpip_adapter_ip_info_t ip; - if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(esp_netif, &ip)){ return IPAddress(); } return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); @@ -508,8 +523,8 @@ IPAddress ETHClass::networkID() uint8_t ETHClass::subnetCIDR() { - tcpip_adapter_ip_info_t ip; - if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(esp_netif, &ip)){ return (uint8_t)0; } return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr)); @@ -518,7 +533,7 @@ uint8_t ETHClass::subnetCIDR() const char * ETHClass::getHostname() { const char * hostname; - if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_ETH, &hostname)){ + if(esp_netif_get_hostname(esp_netif, &hostname)){ return NULL; } return hostname; @@ -526,7 +541,7 @@ const char * ETHClass::getHostname() bool ETHClass::setHostname(const char * hostname) { - return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, hostname) == 0; + return esp_netif_set_hostname(esp_netif, hostname) == 0; } bool ETHClass::fullDuplex() @@ -562,13 +577,13 @@ uint8_t ETHClass::linkSpeed() bool ETHClass::enableIpV6() { - return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH) == 0; + return esp_netif_create_ip6_linklocal(esp_netif) == 0; } IPv6Address ETHClass::localIPv6() { - static ip6_addr_t addr; - if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_ETH, &addr)){ + static esp_ip6_addr_t addr; + if(esp_netif_get_ip6_linklocal(esp_netif, &addr)){ return IPv6Address(); } return IPv6Address(addr.addr); diff --git a/libraries/Ethernet/src/ETH.h b/libraries/Ethernet/src/ETH.h index 7fc14f59cb3..c811ddbf103 100644 --- a/libraries/Ethernet/src/ETH.h +++ b/libraries/Ethernet/src/ETH.h @@ -24,6 +24,7 @@ #include "WiFi.h" #include "esp_system.h" #include "esp_eth.h" +#include "esp_netif.h" #ifndef ETH_PHY_ADDR #define ETH_PHY_ADDR 0 @@ -62,6 +63,7 @@ class ETHClass { bool staticIP; #if ESP_IDF_VERSION_MAJOR > 3 esp_eth_handle_t eth_handle; + esp_netif_t *esp_netif; protected: bool started; diff --git a/libraries/SD/src/sd_diskio.cpp b/libraries/SD/src/sd_diskio.cpp index 4d690135594..d83bd020481 100644 --- a/libraries/SD/src/sd_diskio.cpp +++ b/libraries/SD/src/sd_diskio.cpp @@ -806,7 +806,9 @@ bool sdcard_mount(uint8_t pdrv, const char* path, uint8_t max_files, bool format log_e("alloc for f_mkfs failed"); return false; } - res = f_mkfs(drv, FM_ANY, 0, work, sizeof(work)); + //FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); + const MKFS_PARM opt = {(BYTE)FM_ANY, 0, 0, 0, 0}; + res = f_mkfs(drv, &opt, work, sizeof(work)); free(work); if (res != FR_OK) { log_e("f_mkfs failed: %s", fferr2str[res]); diff --git a/libraries/Update/src/HttpsOTAUpdate.cpp b/libraries/Update/src/HttpsOTAUpdate.cpp index 106559bd3a4..07133fd403b 100644 --- a/libraries/Update/src/HttpsOTAUpdate.cpp +++ b/libraries/Update/src/HttpsOTAUpdate.cpp @@ -44,7 +44,14 @@ void https_ota_task(void *param) xEventGroupSetBits(ota_status, OTA_UPDATING_BIT); xEventGroupClearBits(ota_status, OTA_IDLE_BIT); } - esp_err_t ret = esp_https_ota((const esp_http_client_config_t *)param); + esp_https_ota_config_t cfg; + cfg.http_config = (const esp_http_client_config_t *)param; + cfg.http_client_init_cb = NULL; + cfg.bulk_flash_erase = false; //Erase entire flash partition during initialization + cfg.partial_http_download = false; //Enable Firmware image to be downloaded over multiple HTTP requests + cfg.max_http_request_size = 0; //Maximum request size for partial HTTP download + + esp_err_t ret = esp_https_ota((const esp_https_ota_config_t *)&cfg); if(ret == ESP_OK) { if(ota_status) { xEventGroupClearBits(ota_status, OTA_UPDATING_BIT); diff --git a/libraries/WebServer/src/WebServer.cpp b/libraries/WebServer/src/WebServer.cpp index 66c01198fc9..a5117c985c1 100644 --- a/libraries/WebServer/src/WebServer.cpp +++ b/libraries/WebServer/src/WebServer.cpp @@ -127,9 +127,9 @@ static String md5str(String &in){ return String(out); memset(_buf, 0x00, 16); mbedtls_md5_init(&_ctx); - mbedtls_md5_starts_ret(&_ctx); - mbedtls_md5_update_ret(&_ctx, (const uint8_t *)in.c_str(), in.length()); - mbedtls_md5_finish_ret(&_ctx, _buf); + mbedtls_md5_starts(&_ctx); + mbedtls_md5_update(&_ctx, (const uint8_t *)in.c_str(), in.length()); + mbedtls_md5_finish(&_ctx, _buf); for(i = 0; i < 16; i++) { sprintf(out + (i * 2), "%02x", _buf[i]); } @@ -230,7 +230,7 @@ String WebServer::_getRandomHexString() { char buffer[33]; // buffer to hold 32 Hex Digit + /0 int i; for(i = 0; i < 4; i++) { - sprintf (buffer + (i*8), "%08x", esp_random()); + sprintf (buffer + (i*8), "%08lx", esp_random()); } return String(buffer); } diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index 1b74d322739..1489376bb83 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -36,10 +36,12 @@ extern "C" { #include #include #include +#include #include "lwip/ip_addr.h" #include "lwip/opt.h" #include "lwip/err.h" #include "lwip/dns.h" +#include "dhcpserver/dhcpserver.h" #include "dhcpserver/dhcpserver_options.h" } //extern "C" diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h index 2f670a34d05..3c51fc8e8c5 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -29,6 +29,8 @@ #include "WiFiType.h" #include "IPAddress.h" #include "esp_smartconfig.h" +#include "esp_netif_types.h" +#include "esp_eth_driver.h" #include "wifi_provisioning/manager.h" ESP_EVENT_DECLARE_BASE(ARDUINO_EVENTS); diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp index 7bcafea1d3e..06543485573 100644 --- a/libraries/WiFi/src/WiFiSTA.cpp +++ b/libraries/WiFi/src/WiFiSTA.cpp @@ -43,6 +43,7 @@ extern "C" { #include #include #include "esp_wpa2.h" +#include "esp_mac.h" } // ----------------------------------------------------------------------------------------------------------------------- diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp b/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp index a6814b0a60b..c7ee7e1cf83 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp +++ b/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp @@ -264,10 +264,10 @@ void WiFiClientSecure::setCACert (const char *rootCA) { if (bundle != NULL) { - arduino_esp_crt_bundle_set(bundle); + esp_crt_bundle_set(bundle, sizeof(bundle)); _use_ca_bundle = true; } else { - arduino_esp_crt_bundle_detach(NULL); + esp_crt_bundle_detach(NULL); _use_ca_bundle = false; } } diff --git a/libraries/WiFiClientSecure/src/esp_crt_bundle.c b/libraries/WiFiClientSecure/src/esp_crt_bundle.c deleted file mode 100644 index 82a0708662c..00000000000 --- a/libraries/WiFiClientSecure/src/esp_crt_bundle.c +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -#include -#include -#include -#include "esp_crt_bundle.h" -#include "esp_err.h" - -#define BUNDLE_HEADER_OFFSET 2 -#define CRT_HEADER_OFFSET 4 - -/* a dummy certificate so that - * cacert_ptr passes non-NULL check during handshake */ -static mbedtls_x509_crt s_dummy_crt; - - -typedef struct crt_bundle_t { - const uint8_t **crts; - uint16_t num_certs; - size_t x509_crt_bundle_len; -} crt_bundle_t; - -static crt_bundle_t s_crt_bundle; - -static int esp_crt_verify_callback(void *buf, mbedtls_x509_crt *crt, int data, uint32_t *flags); -static int esp_crt_check_signature(mbedtls_x509_crt *child, const uint8_t *pub_key_buf, size_t pub_key_len); - - -static int esp_crt_check_signature(mbedtls_x509_crt *child, const uint8_t *pub_key_buf, size_t pub_key_len) -{ - int ret = 0; - mbedtls_x509_crt parent; - const mbedtls_md_info_t *md_info; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - - mbedtls_x509_crt_init(&parent); - - if ( (ret = mbedtls_pk_parse_public_key(&parent.pk, pub_key_buf, pub_key_len) ) != 0) { - log_e("PK parse failed with error %X", ret); - goto cleanup; - } - - - // Fast check to avoid expensive computations when not necessary - if (!mbedtls_pk_can_do(&parent.pk, child->sig_pk)) { - log_e("Simple compare failed"); - ret = -1; - goto cleanup; - } - - md_info = mbedtls_md_info_from_type(child->sig_md); - if ( (ret = mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash )) != 0 ) { - log_e("Internal mbedTLS error %X", ret); - goto cleanup; - } - - if ( (ret = mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent.pk, - child->sig_md, hash, mbedtls_md_get_size( md_info ), - child->sig.p, child->sig.len )) != 0 ) { - - log_e("PK verify failed with error %X", ret); - goto cleanup; - } -cleanup: - mbedtls_x509_crt_free(&parent); - - return ret; -} - - -/* This callback is called for every certificate in the chain. If the chain - * is proper each intermediate certificate is validated through its parent - * in the x509_crt_verify_chain() function. So this callback should - * only verify the first untrusted link in the chain is signed by the - * root certificate in the trusted bundle -*/ -int esp_crt_verify_callback(void *buf, mbedtls_x509_crt *crt, int depth, uint32_t *flags) -{ - mbedtls_x509_crt *child = crt; - - /* It's OK for a trusted cert to have a weak signature hash alg. - as we already trust this certificate */ - uint32_t flags_filtered = *flags & ~(MBEDTLS_X509_BADCERT_BAD_MD); - - if (flags_filtered != MBEDTLS_X509_BADCERT_NOT_TRUSTED) { - return 0; - } - - - if (s_crt_bundle.crts == NULL) { - log_e("No certificates in bundle"); - return MBEDTLS_ERR_X509_FATAL_ERROR; - } - - log_d("%d certificates in bundle", s_crt_bundle.num_certs); - - size_t name_len = 0; - const uint8_t *crt_name; - - bool crt_found = false; - int start = 0; - int end = s_crt_bundle.num_certs - 1; - int middle = (end - start) / 2; - - /* Look for the certificate using binary search on subject name */ - while (start <= end) { - name_len = s_crt_bundle.crts[middle][0] << 8 | s_crt_bundle.crts[middle][1]; - crt_name = s_crt_bundle.crts[middle] + CRT_HEADER_OFFSET; - - int cmp_res = memcmp(child->issuer_raw.p, crt_name, name_len ); - if (cmp_res == 0) { - crt_found = true; - break; - } else if (cmp_res < 0) { - end = middle - 1; - } else { - start = middle + 1; - } - middle = (start + end) / 2; - } - - int ret = MBEDTLS_ERR_X509_FATAL_ERROR; - if (crt_found) { - size_t key_len = s_crt_bundle.crts[middle][2] << 8 | s_crt_bundle.crts[middle][3]; - ret = esp_crt_check_signature(child, s_crt_bundle.crts[middle] + CRT_HEADER_OFFSET + name_len, key_len); - } - - if (ret == 0) { - log_i("Certificate validated"); - *flags = 0; - return 0; - } - - log_e("Failed to verify certificate"); - return MBEDTLS_ERR_X509_FATAL_ERROR; -} - - -/* Initialize the bundle into an array so we can do binary search for certs, - the bundle generated by the python utility is already presorted by subject name - */ -static esp_err_t esp_crt_bundle_init(const uint8_t *x509_bundle) -{ - s_crt_bundle.num_certs = (x509_bundle[0] << 8) | x509_bundle[1]; - s_crt_bundle.crts = calloc(s_crt_bundle.num_certs, sizeof(x509_bundle)); - - if (s_crt_bundle.crts == NULL) { - log_e("Unable to allocate memory for bundle"); - return ESP_ERR_NO_MEM; - } - - const uint8_t *cur_crt; - cur_crt = x509_bundle + BUNDLE_HEADER_OFFSET; - - for (int i = 0; i < s_crt_bundle.num_certs; i++) { - s_crt_bundle.crts[i] = cur_crt; - - size_t name_len = cur_crt[0] << 8 | cur_crt[1]; - size_t key_len = cur_crt[2] << 8 | cur_crt[3]; - cur_crt = cur_crt + CRT_HEADER_OFFSET + name_len + key_len; - } - - return ESP_OK; -} - -esp_err_t arduino_esp_crt_bundle_attach(void *conf) -{ - esp_err_t ret = ESP_OK; - // If no bundle has been set by the user then use the bundle embedded in the binary - if (s_crt_bundle.crts == NULL) { - log_e("Failed to attach bundle"); - return ret; - } - - if (conf) { - /* point to a dummy certificate - * This is only required so that the - * cacert_ptr passes non-NULL check during handshake - */ - mbedtls_ssl_config *ssl_conf = (mbedtls_ssl_config *)conf; - mbedtls_x509_crt_init(&s_dummy_crt); - mbedtls_ssl_conf_ca_chain(ssl_conf, &s_dummy_crt, NULL); - mbedtls_ssl_conf_verify(ssl_conf, esp_crt_verify_callback, NULL); - } - - return ret; -} - -void arduino_esp_crt_bundle_detach(mbedtls_ssl_config *conf) -{ - free(s_crt_bundle.crts); - s_crt_bundle.crts = NULL; - if (conf) { - mbedtls_ssl_conf_verify(conf, NULL, NULL); - } -} - -void arduino_esp_crt_bundle_set(const uint8_t *x509_bundle) -{ - // Free any previously used bundle - free(s_crt_bundle.crts); - esp_crt_bundle_init(x509_bundle); -} diff --git a/libraries/WiFiClientSecure/src/esp_crt_bundle.h b/libraries/WiFiClientSecure/src/esp_crt_bundle.h deleted file mode 100644 index a1d95194af4..00000000000 --- a/libraries/WiFiClientSecure/src/esp_crt_bundle.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -#ifndef _ESP_CRT_BUNDLE_H_ -#define _ESP_CRT_BUNDLE_H_ - -#include "mbedtls/ssl.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @brief Attach and enable use of a bundle for certificate verification - * - * Attach and enable use of a bundle for certificate verification through a verification callback. - * If no specific bundle has been set through esp_crt_bundle_set() it will default to the - * bundle defined in menuconfig and embedded in the binary. - * - * @param[in] conf The config struct for the SSL connection. - * - * @return - * - ESP_OK if adding certificates was successful. - * - Other if an error occured or an action must be taken by the calling process. - */ -esp_err_t arduino_esp_crt_bundle_attach(void *conf); - - -/** - * @brief Disable and dealloc the certification bundle - * - * Removes the certificate verification callback and deallocates used resources - * - * @param[in] conf The config struct for the SSL connection. - */ -void arduino_esp_crt_bundle_detach(mbedtls_ssl_config *conf); - - -/** - * @brief Set the default certificate bundle used for verification - * - * Overrides the default certificate bundle. In most use cases the bundle should be - * set through menuconfig. The bundle needs to be sorted by subject name since binary search is - * used to find certificates. - * - * @param[in] x509_bundle A pointer to the certificate bundle. - */ -void arduino_esp_crt_bundle_set(const uint8_t *x509_bundle); - - -#ifdef __cplusplus -} -#endif - -#endif //_ESP_CRT_BUNDLE_H_ diff --git a/libraries/WiFiClientSecure/src/ssl_client.cpp b/libraries/WiFiClientSecure/src/ssl_client.cpp index 299c47beaf1..571cccbeb92 100644 --- a/libraries/WiFiClientSecure/src/ssl_client.cpp +++ b/libraries/WiFiClientSecure/src/ssl_client.cpp @@ -53,6 +53,14 @@ void ssl_init(sslclient_context *ssl_client) mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx); } +#warning This needs to be properly filled +static int ssl_rng(void *ctx, unsigned char *data, size_t len) +{ + // while (len-- != 0) { + // *data++ = random(); + // } + return 0; +} int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, bool useRootCABundle, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure, const char **alpn_protos) { @@ -193,7 +201,7 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p } } else if (useRootCABundle) { log_v("Attaching root CA cert bundle"); - ret = arduino_esp_crt_bundle_attach(&ssl_client->ssl_conf); + ret = esp_crt_bundle_attach(&ssl_client->ssl_conf); if (ret < 0) { return handle_error(ret); @@ -246,7 +254,7 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p } log_v("Loading private key"); - ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0); + ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0, ssl_rng, NULL); if (ret != 0) { mbedtls_x509_crt_free(&ssl_client->client_cert); // cert+key are free'd in pair @@ -331,13 +339,13 @@ void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, cons } // avoid memory leak if ssl connection attempt failed - if (ssl_client->ssl_conf.ca_chain != NULL) { + //if (ssl_client->ssl_conf.ca_chain != NULL) { mbedtls_x509_crt_free(&ssl_client->ca_cert); - } - if (ssl_client->ssl_conf.key_cert != NULL) { + //} + //if (ssl_client->ssl_conf.key_cert != NULL) { mbedtls_x509_crt_free(&ssl_client->client_cert); mbedtls_pk_free(&ssl_client->client_key); - } + //} mbedtls_ssl_free(&ssl_client->ssl_ctx); mbedtls_ssl_config_free(&ssl_client->ssl_conf); mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx); diff --git a/libraries/WiFiClientSecure/src/ssl_client.h b/libraries/WiFiClientSecure/src/ssl_client.h index 1f4179c98dd..9690caafddf 100644 --- a/libraries/WiFiClientSecure/src/ssl_client.h +++ b/libraries/WiFiClientSecure/src/ssl_client.h @@ -5,7 +5,7 @@ #ifndef ARD_SSL_H #define ARD_SSL_H #include "mbedtls/platform.h" -#include "mbedtls/net.h" +#include "mbedtls/net_sockets.h" #include "mbedtls/debug.h" #include "mbedtls/ssl.h" #include "mbedtls/entropy.h" From 14a67be98c5f1f71f8a58946b6755c0ebc5910f3 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 19 Jan 2023 19:46:52 +0200 Subject: [PATCH 02/60] Update esp32-hal-psram.c --- cores/esp32/esp32-hal-psram.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/cores/esp32/esp32-hal-psram.c b/cores/esp32/esp32-hal-psram.c index 424499e0058..1e8a681a9ee 100644 --- a/cores/esp32/esp32-hal-psram.c +++ b/cores/esp32/esp32-hal-psram.c @@ -19,21 +19,17 @@ #include "esp_heap_caps.h" #include "esp_system.h" -#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ +#include "esp_psram.h" +#include "esp_private/esp_psram_extram.h" #if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 -#include "esp32/spiram.h" +#include "esp32/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32S2 -#include "esp32s2/spiram.h" #include "esp32s2/rom/cache.h" #elif CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/spiram.h" #include "esp32s3/rom/cache.h" #else #error Target CONFIG_IDF_TARGET is not supported #endif -#else // ESP32 Before IDF 4.0 -#include "esp_spiram.h" -#endif static volatile bool spiramDetected = false; static volatile bool spiramFailed = false; @@ -41,7 +37,7 @@ static volatile bool spiramFailed = false; //allows user to bypass SPI RAM test routine __attribute__((weak)) bool testSPIRAM(void) { - return esp_spiram_test(); + return esp_psram_extram_test(); } @@ -66,7 +62,7 @@ bool psramInit(){ esp_config_data_cache_mode(); Cache_Enable_DCache(0); #endif - if (esp_spiram_init() != ESP_OK) { + if (esp_psram_init() != ESP_OK) { spiramFailed = true; log_w("PSRAM init failed!"); #if CONFIG_IDF_TARGET_ESP32 @@ -77,14 +73,14 @@ bool psramInit(){ #endif return false; } - esp_spiram_init_cache(); + //testSPIRAM() allows user to bypass SPI RAM test routine if (!testSPIRAM()) { spiramFailed = true; log_e("PSRAM test failed!"); return false; } - if (esp_spiram_add_to_heapalloc() != ESP_OK) { + if (esp_psram_extram_add_to_heap_allocator() != ESP_OK) { spiramFailed = true; log_e("PSRAM could not be added to the heap!"); return false; From 18d228328de82d26290ad5245fe562172ac08f8c Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 19 Jan 2023 19:27:05 +0200 Subject: [PATCH 03/60] Update toolchain --- package/package_esp32_index.template.json | 240 +++++++++++----------- tools/get.py | 4 + 2 files changed, 124 insertions(+), 120 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index 09dddcd3316..5ec92b01d30 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -39,22 +39,22 @@ { "packager": "esp32", "name": "riscv32-esp-elf-gcc", - "version": "gcc8_4_0-esp-2021r2-patch5" + "version": "gcc11_2_0-esp-2022r1" }, { "packager": "esp32", "name": "xtensa-esp32-elf-gcc", - "version": "gcc8_4_0-esp-2021r2-patch5" + "version": "gcc11_2_0-esp-2022r1" }, { "packager": "esp32", "name": "xtensa-esp32s2-elf-gcc", - "version": "gcc8_4_0-esp-2021r2-patch5" + "version": "gcc11_2_0-esp-2022r1" }, { "packager": "esp32", "name": "xtensa-esp32s3-elf-gcc", - "version": "gcc8_4_0-esp-2021r2-patch5" + "version": "gcc11_2_0-esp-2022r1" }, { "packager": "esp32", @@ -82,221 +82,221 @@ "tools": [ { "name": "riscv32-esp-elf-gcc", - "version": "gcc8_4_0-esp-2021r2-patch5", + "version": "gcc11_2_0-esp-2022r1", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-linux-amd64.tar.gz", - "archiveFileName": "riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-linux-amd64.tar.gz", - "checksum": "SHA-256:f7d73e5f9e2df3ea6ca8e2c95d6ca6d23d6b38fd101ea5d3012f3cb3cd59f39f", - "size": "192388486" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "checksum": "SHA-256:52710f804df4a033a2b621cc16cfa21023b42052819a51e35a2a164140bbf665", + "size": "110107900" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-linux-arm64.tar.gz", - "archiveFileName": "riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-linux-arm64.tar.gz", - "checksum": "SHA-256:cf520ae3a72f65b9758ea187524b105b8b7546566d738c32e60a0df9846ef1af", - "size": "188626914" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "checksum": "SHA-256:812a18f2ecdc3f72c1d098c4e8baa968841099ce9d9ecf95baea85ff71e11013", + "size": "104279292" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-linux-armel.tar.gz", - "archiveFileName": "riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-linux-armel.tar.gz", - "checksum": "SHA-256:2dc3536214caa1697f6834bb4701d05894ca55b53589fc5b54064b050ef93799", - "size": "188624050" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "checksum": "SHA-256:bc6e3ff8323d1f8b137374788b5615152281aab9e7561c55ab1504145677b6c7", + "size": "102802824" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-linux-i686.tar.gz", - "archiveFileName": "riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-linux-i686.tar.gz", - "checksum": "SHA-256:165d6d53e76d79f5ade7e2b7ade54b2b495ecfda0d1184d84d6343659d0e3bdb", - "size": "194606113" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "checksum": "SHA-256:39d7295c30a23b5ea91baf61c207718ce86d4b1589014b030e121300370f696d", + "size": "111505972" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-macos.tar.gz", - "archiveFileName": "riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-macos.tar.gz", - "checksum": "SHA-256:d6d4cef216cbf28d6fbb88f3e127d4f42a376d9497c260bf8c1ad9cef440f839", - "size": "199411930" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "checksum": "SHA-256:d3a6f42b02a5f1485ba3fa92b8a9d9f307f643420e22b3765e88bbe4570aee01", + "size": "112060920" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-win32.zip", - "archiveFileName": "riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-win32.zip", - "checksum": "SHA-256:1e0cfcfbc8f82c441261cadd21742f66d716ec18c18bf10ed7c7d5b0bee6752f", - "size": "257844437" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-win32.zip", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-win32.zip", + "checksum": "SHA-256:3e677ef068d7f154d33b0d3788b5f985c5066d110028eac44e0f76b3bda4429b", + "size": "268053767" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-win64.zip", - "archiveFileName": "riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch5-win64.zip", - "checksum": "SHA-256:b08f568e8fe5069dd521b87da21b8e56117e5c2c3b492f73a51966a46d3379a4", - "size": "259712666" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-win64.zip", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-win64.zip", + "checksum": "SHA-256:324a5c679fef75313766cc48d3433c48bf23985a11b5070c5d19144538c6357b", + "size": "271158759" } ] }, { "name": "xtensa-esp32-elf-gcc", - "version": "gcc8_4_0-esp-2021r2-patch5", + "version": "gcc11_2_0-esp-2022r1", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-linux-amd64.tar.gz", - "archiveFileName": "xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-linux-amd64.tar.gz", - "checksum": "SHA-256:8ef14e0409c2011b41e504a30f70d3e35287313a795d1f2462ad2cd0e2052d37", - "size": "94397702" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "archiveFileName": "xtensa-esp32-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "checksum": "SHA-256:698d8407e18275d18feb7d1afdb68800b97904fbe39080422fb8609afa49df30", + "size": "64781328" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-linux-arm64.tar.gz", - "archiveFileName": "xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-linux-arm64.tar.gz", - "checksum": "SHA-256:e7d217ac2ef52c746a41f8647840b2717edcd8afc15f081bc1c4505e10a189b7", - "size": "90684219" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "archiveFileName": "xtensa-esp32-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "checksum": "SHA-256:48ed01abff1e89e6fe1c3ebe4e00df6a0a67e53ae24979970464a4a3b64aa622", + "size": "60675980" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-linux-armel.tar.gz", - "archiveFileName": "xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-linux-armel.tar.gz", - "checksum": "SHA-256:ea6631f8a5105ae90d7fc462c10ed4f9049924ea8c2f9391d90b339d5f881dac", - "size": "89954866" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "archiveFileName": "xtensa-esp32-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "checksum": "SHA-256:0e6131a9ab4e3da0a153ee75097012823ccf21f90c69368c3bf53c8a086736f8", + "size": "59117264" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-linux-i686.tar.gz", - "archiveFileName": "xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-linux-i686.tar.gz", - "checksum": "SHA-256:ecb90af9cede0982672234da0b1bd7b7f76eadde60aa5c82eefdf37d64ffe49f", - "size": "96354023" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "archiveFileName": "xtensa-esp32-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "checksum": "SHA-256:d06511bb18057d72b555d6c5b62b0686f19e9f8c7d7eae218b712eed0907dbb2", + "size": "65914276" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-macos.tar.gz", - "archiveFileName": "xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-macos.tar.gz", - "checksum": "SHA-256:19af109fda024a3a4c989f7ccaa104f9b1b74cfd6c9363e730bb8cb9b50d5dc4", - "size": "101712946" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "archiveFileName": "xtensa-esp32-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "checksum": "SHA-256:1c9d873c56469e3abec1e4214b7200d36804a605d4f0991e539b1577415409bf", + "size": "68189688" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-win32.zip", - "archiveFileName": "xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-win32.zip", - "checksum": "SHA-256:9851c2cfa355e1fad8abfb643a1c945d27385b1851f3ae468915ea78fcbec940", - "size": "118610020" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-win32.zip", + "archiveFileName": "xtensa-esp32-elf-gcc11_2_0-esp-2022r1-win32.zip", + "checksum": "SHA-256:858ee049d6d8de730ed3e30285c4adc1a9cdfe077b591ed0b6f2bfa5e3564f53", + "size": "129786756" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-win64.zip", - "archiveFileName": "xtensa-esp32-elf-gcc8_4_0-esp-2021r2-patch5-win64.zip", - "checksum": "SHA-256:a328b3c55631846241bbe7999a309b20b797c8dc50b6e8dccf463e66a2da5fb4", - "size": "121846722" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-win64.zip", + "archiveFileName": "xtensa-esp32-elf-gcc11_2_0-esp-2022r1-win64.zip", + "checksum": "SHA-256:f469aff6a71113e3a145466d814184339e02248b158357766970646f5d2a3da7", + "size": "133936844" } ] }, { "name": "xtensa-esp32s2-elf-gcc", - "version": "gcc8_4_0-esp-2021r2-patch5", + "version": "gcc11_2_0-esp-2022r1", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-linux-amd64.tar.gz", - "archiveFileName": "xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-linux-amd64.tar.gz", - "checksum": "SHA-256:19c77bd91fefab7c8c40a6334f9b985e2d9a1c7fac6d424b692110930dd3682f", - "size": "67849099" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "archiveFileName": "xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "checksum": "SHA-256:56e5913b6662b8eec7d6b46780e668bc7e7cebef239e326a74f764c92a3cc841", + "size": "51546516" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-linux-arm64.tar.gz", - "archiveFileName": "xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-linux-arm64.tar.gz", - "checksum": "SHA-256:bdcd24676ef2a65b670ca9e0a01768ece47f4dfcfb545a3307f76a054c33b522", - "size": "64154532" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "archiveFileName": "xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "checksum": "SHA-256:2f0ccc9d40279d6407ed9547250fb0434f16060faa94460c52b74614a38a1e21", + "size": "46338036" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-linux-armel.tar.gz", - "archiveFileName": "xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-linux-armel.tar.gz", - "checksum": "SHA-256:b26723b6ce1c35b90f204eb39e5ab06a6f80fb7895f000e16b6962e4c176ae32", - "size": "63448105" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "archiveFileName": "xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "checksum": "SHA-256:f71974c4aaf3f637f6adaa28bbbdf3a911db3385e0ab1544844513ec65185cc5", + "size": "43326084" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-linux-i686.tar.gz", - "archiveFileName": "xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-linux-i686.tar.gz", - "checksum": "SHA-256:da3b5c45e4997d14269df1814c92dd7004902bb810608341bc3819c3e506fa0b", - "size": "69656104" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "archiveFileName": "xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "checksum": "SHA-256:504efe97ce24561537bd442494b1046fc8fb9cc43a1c06ef1afa4652b7517201", + "size": "53807024" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-macos.tar.gz", - "archiveFileName": "xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-macos.tar.gz", - "checksum": "SHA-256:8eb63745b44083edef7cc6fdf3b06999f576b75134bc5e8b0ef881ca439b72d7", - "size": "75154138" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "archiveFileName": "xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "checksum": "SHA-256:f53da9423490001727c5b6c3b8e1602b887783f0ed68e5defbb3c7712ada9631", + "size": "53568496" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-win32.zip", - "archiveFileName": "xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-win32.zip", - "checksum": "SHA-256:c758062295804b082fbd77fcd59a356f62d4e76372aaa29589cc871603309cba", - "size": "82338511" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-win32.zip", + "archiveFileName": "xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-win32.zip", + "checksum": "SHA-256:96b873210438713a84ea6e39e591cdbbeef453cb431d8392ac3fa2e68a48bc97", + "size": "94981372" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-win64.zip", - "archiveFileName": "xtensa-esp32s2-elf-gcc8_4_0-esp-2021r2-patch5-win64.zip", - "checksum": "SHA-256:1c1e168ff8bc460a9719f3b216d3c1125d29040389786d738244838499362c74", - "size": "85579252" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-win64.zip", + "archiveFileName": "xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-win64.zip", + "checksum": "SHA-256:9ab0387e08047916bbf7ff0d2eb974c710bcf2e042cb04037b4dd93c9186f676", + "size": "99074758" } ] }, { "name": "xtensa-esp32s3-elf-gcc", - "version": "gcc8_4_0-esp-2021r2-patch5", + "version": "gcc11_2_0-esp-2022r1", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-linux-amd64.tar.gz", - "archiveFileName": "xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-linux-amd64.tar.gz", - "checksum": "SHA-256:8aa17a6adf01efa5b1628c8ac578063a44d26ae9581d39486b92223a41ef262f", - "size": "68099473" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "archiveFileName": "xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "checksum": "SHA-256:5058b2e724166c34ca09ec2d5377350252de8bce5039b06c00352f9a8151f76e", + "size": "51899328" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-linux-arm64.tar.gz", - "archiveFileName": "xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-linux-arm64.tar.gz", - "checksum": "SHA-256:b218c11122e5565b6442376ebd21a652abdfcbf90981afa3e177ce978710225d", - "size": "64233211" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "archiveFileName": "xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "checksum": "SHA-256:d2c6fb98a5018139a9f5af6eb808e968f1381a5b34547a185f4dec142b0fa44e", + "size": "45458872" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-linux-armel.tar.gz", - "archiveFileName": "xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-linux-armel.tar.gz", - "checksum": "SHA-256:967477434ad5483718915936a77ce915a10c5972a6b3fd02688a5c4e14182bfb", - "size": "63530586" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "archiveFileName": "xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "checksum": "SHA-256:9944e67d95a5de9875670c5cd5cb0bb282ebac235a38b5fd6d53069813fead9e", + "size": "44532116" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-linux-i686.tar.gz", - "archiveFileName": "xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-linux-i686.tar.gz", - "checksum": "SHA-256:07671d01a63ebd389912787efb2b263677c7b351c07fe430ded733cdae95e81d", - "size": "70025439" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "archiveFileName": "xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "checksum": "SHA-256:0feccf884e36b6e93c27c793729199b18df22a409557b16c90b2883a6748e041", + "size": "53956012" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-macos.tar.gz", - "archiveFileName": "xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-macos.tar.gz", - "checksum": "SHA-256:99b6d44cea5aebbedc8b6965e7bf551aa4a40ed83ddbe1c0e9b7cb255564ded5", - "size": "75719772" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "archiveFileName": "xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "checksum": "SHA-256:2b46730adc6afd8115e0be9365050a87f9523617e5e58ee35cb85ff1ddf2756c", + "size": "54256036" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-win32.zip", - "archiveFileName": "xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-win32.zip", - "checksum": "SHA-256:658d3036ffdf11ddad6f0a784c8829f6ffd4dbd7c252d7f61722256d0ad43975", - "size": "82665716" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-win32.zip", + "archiveFileName": "xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-win32.zip", + "checksum": "SHA-256:0c9ec6d296b66523e3990b195b6597dfc4030f2335bf904b614f990ad6dabbde", + "size": "95241895" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2021r2-patch5/xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-win64.zip", - "archiveFileName": "xtensa-esp32s3-elf-gcc8_4_0-esp-2021r2-patch5-win64.zip", - "checksum": "SHA-256:9000be38d44bf79c39b93a2aeb99b42e956c593ccbc02fe31cb9c71ae1bbcb22", - "size": "86022563" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-win64.zip", + "archiveFileName": "xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-win64.zip", + "checksum": "SHA-256:7213a0bf22607e9c70febaabef37822c2ae5e071ac53d6467e6031b02bb0b2bf", + "size": "99495535" } ] }, diff --git a/tools/get.py b/tools/get.py index 088e2f67139..8836e4cc6cc 100755 --- a/tools/get.py +++ b/tools/get.py @@ -75,6 +75,10 @@ def unpack(filename, destination): tfile = tarfile.open(filename, 'r:gz') tfile.extractall(destination) dirname = tfile.getnames()[0] + elif filename.endswith('tar.xz'): + tfile = tarfile.open(filename, 'r:xz') + tfile.extractall(destination) + dirname = tfile.getnames()[0] elif filename.endswith('zip'): zfile = zipfile.ZipFile(filename) zfile.extractall(destination) From 5cf83b1ff158ae19dc37d0aacc3d9714c3b83400 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 19 Jan 2023 22:58:57 +0200 Subject: [PATCH 04/60] Stop some CI jobs, because they will always fail --- .github/workflows/push.yml | 82 +++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index fecf743dfc9..5b2521b414a 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -63,46 +63,46 @@ jobs: - name: Build Sketches run: bash ./.github/scripts/on-push.sh - # PlatformIO on Windows, Ubuntu and Mac - build-platformio: - name: PlatformIO on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] + # # PlatformIO on Windows, Ubuntu and Mac + # build-platformio: + # name: PlatformIO on ${{ matrix.os }} + # runs-on: ${{ matrix.os }} + # strategy: + # matrix: + # os: [ubuntu-latest, windows-latest, macOS-latest] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - name: Build Sketches - run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO + # steps: + # - uses: actions/checkout@v3 + # - uses: actions/setup-python@v4 + # with: + # python-version: '3.x' + # - name: Build Sketches + # run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO - build-esp-idf-component: - name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }} - runs-on: ubuntu-20.04 - strategy: - matrix: - # The version names here correspond to the versions of espressif/idf Docker image. - # See https://hub.docker.com/r/espressif/idf/tags and - # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html - # for details. - idf_ver: ["release-v4.4"] - idf_target: ["esp32", "esp32s2", "esp32s3", "esp32c3"] - container: espressif/idf:${{ matrix.idf_ver }} - steps: - - name: Check out arduino-esp32 as a component - uses: actions/checkout@v3 - with: - submodules: recursive - path: components/arduino-esp32 - - name: Build - env: - IDF_TARGET: ${{ matrix.idf_target }} - shell: bash - run: | - . ${IDF_PATH}/export.sh - idf.py create-project test - echo CONFIG_FREERTOS_HZ=1000 > test/sdkconfig.defaults - idf.py -C test -DEXTRA_COMPONENT_DIRS=$PWD/components build + # build-esp-idf-component: + # name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }} + # runs-on: ubuntu-20.04 + # strategy: + # matrix: + # # The version names here correspond to the versions of espressif/idf Docker image. + # # See https://hub.docker.com/r/espressif/idf/tags and + # # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html + # # for details. + # idf_ver: ["release-v4.4"] + # idf_target: ["esp32", "esp32s2", "esp32s3", "esp32c3"] + # container: espressif/idf:${{ matrix.idf_ver }} + # steps: + # - name: Check out arduino-esp32 as a component + # uses: actions/checkout@v3 + # with: + # submodules: recursive + # path: components/arduino-esp32 + # - name: Build + # env: + # IDF_TARGET: ${{ matrix.idf_target }} + # shell: bash + # run: | + # . ${IDF_PATH}/export.sh + # idf.py create-project test + # echo CONFIG_FREERTOS_HZ=1000 > test/sdkconfig.defaults + # idf.py -C test -DEXTRA_COMPONENT_DIRS=$PWD/components build From 0846a4180fbe19b8495f49a8f010510b488077cf Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 20 Jan 2023 01:39:19 +0200 Subject: [PATCH 05/60] Fix examples --- .../BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino | 4 ++-- .../BLE_EddystoneTLM_Beacon.ino | 4 ++-- .../BLE_EddystoneURL_Beacon.ino | 4 ++-- .../EEPROM/examples/eeprom_extra/eeprom_extra.ino | 8 ++++---- .../AnalogOut/ledcFrequency/ledcFrequency.ino | 12 ++++++------ .../examples/Camera/CameraWebServer/app_httpd.cpp | 4 ++-- .../SmoothBlink_ULP_Code/SmoothBlink_ULP_Code.ino | 3 ++- .../ESP32/examples/ESPNow/Basic/Slave/Slave.ino | 4 ++-- .../examples/ESPNow/Multi-Slave/Slave/Slave.ino | 4 ++-- .../FunctionalInterrupt/FunctionalInterrupt.ino | 2 +- .../examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino | 4 ++-- libraries/ESP32/examples/HallSensor/.skip.esp32c3 | 0 libraries/ESP32/examples/HallSensor/.skip.esp32s2 | 0 libraries/ESP32/examples/HallSensor/.skip.esp32s3 | 0 .../ESP32/examples/HallSensor/HallSensor.ino | 15 --------------- .../ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino | 2 +- .../examples/RMT/RMTCallback/RMTCallback.ino | 2 +- .../examples/RMT/RMTLoopback/RMTLoopback.ino | 2 +- .../ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino | 2 +- .../Serial/RxFIFOFull_Demo/RxFIFOFull_Demo.ino | 4 ++-- .../Serial/RxTimeout_Demo/RxTimeout_Demo.ino | 2 +- .../examples/TWAI/TWAIreceive/TWAIreceive.ino | 10 +++++----- .../Timer/WatchdogTimer/WatchdogTimer.ino | 1 + libraries/FFat/examples/FFat_Test/FFat_Test.ino | 4 ++-- libraries/I2S/examples/SimpleTone/SimpleTone.ino | 2 +- .../examples/LITTLEFS_test/LITTLEFS_test.ino | 4 ++-- .../RMakerSonoffDualR3/RMakerSonoffDualR3.ino | 2 +- libraries/SD/examples/SD_Test/SD_Test.ino | 4 ++-- .../SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino | 4 ++-- .../SPIFFS/examples/SPIFFS_Test/SPIFFS_Test.ino | 4 ++-- .../examples/CompositeDevice/CompositeDevice.ino | 2 +- libraries/USB/examples/USBMSC/USBMSC.ino | 4 ++-- libraries/USB/examples/USBSerial/USBSerial.ino | 2 +- libraries/USB/examples/USBVendor/USBVendor.ino | 2 +- .../HTTPS_OTA_Update/HTTPS_OTA_Update.ino | 3 +++ .../examples/FTM/FTM_Initiator/FTM_Initiator.ino | 2 +- libraries/WiFi/examples/WiFiScan/WiFiScan.ino | 4 ++-- libraries/Wire/examples/WireMaster/WireMaster.ino | 2 +- libraries/Wire/examples/WireSlave/WireSlave.ino | 2 +- 39 files changed, 65 insertions(+), 75 deletions(-) delete mode 100644 libraries/ESP32/examples/HallSensor/.skip.esp32c3 delete mode 100644 libraries/ESP32/examples/HallSensor/.skip.esp32s2 delete mode 100644 libraries/ESP32/examples/HallSensor/.skip.esp32s3 delete mode 100644 libraries/ESP32/examples/HallSensor/HallSensor.ino diff --git a/libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino b/libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino index b46baa7c84e..d7d00abb729 100644 --- a/libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino +++ b/libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino @@ -118,8 +118,8 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks int temp = (int)payLoad[16] + (int)(payLoad[15] << 8); float calcTemp = temp / 256.0f; Serial.printf("Reported temperature from data: %.2fC\n", calcTemp); - Serial.printf("Reported advertise count: %d\n", foundEddyURL.getCount()); - Serial.printf("Reported time since last reboot: %ds\n", foundEddyURL.getTime()); + Serial.printf("Reported advertise count: %lu\n", foundEddyURL.getCount()); + Serial.printf("Reported time since last reboot: %lus\n", foundEddyURL.getTime()); Serial.println("\n"); Serial.print(foundEddyURL.toString().c_str()); Serial.println("\n"); diff --git a/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino b/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino index 96be28cd588..ea6d5ca0b72 100644 --- a/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino +++ b/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino @@ -86,9 +86,9 @@ void setup() Serial.begin(115200); gettimeofday(&nowTimeStruct, NULL); - Serial.printf("start ESP32 %d\n", bootcount++); + Serial.printf("start ESP32 %lu\n", bootcount++); - Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n", nowTimeStruct.tv_sec, nowTimeStruct.tv_sec - last); + Serial.printf("deep sleep (%llds since last reset, %llds since last boot)\n", nowTimeStruct.tv_sec, nowTimeStruct.tv_sec - last); last = nowTimeStruct.tv_sec; lastTenth = nowTimeStruct.tv_sec * 10; // Time since last reset as 0.1 second resolution counter diff --git a/libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino b/libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino index 335ea1ffbe6..d3938ee02fa 100644 --- a/libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino +++ b/libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino @@ -160,9 +160,9 @@ void setup() Serial.begin(115200); gettimeofday(&now, NULL); - Serial.printf("start ESP32 %d\n", bootcount++); + Serial.printf("start ESP32 %lu\n", bootcount++); - Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n", now.tv_sec, now.tv_sec - last); + Serial.printf("deep sleep (%llds since last reset, %llds since last boot)\n", now.tv_sec, now.tv_sec - last); last = now.tv_sec; diff --git a/libraries/EEPROM/examples/eeprom_extra/eeprom_extra.ino b/libraries/EEPROM/examples/eeprom_extra/eeprom_extra.ino index 5ae01fb2268..ba062bca046 100644 --- a/libraries/EEPROM/examples/eeprom_extra/eeprom_extra.ino +++ b/libraries/EEPROM/examples/eeprom_extra/eeprom_extra.ino @@ -107,14 +107,14 @@ void setup() { value = 0; value = EEPROM.readLong64(value); - Serial.printf("0x%08X", (uint32_t)(value >> 32)); // Print High 4 bytes in HEX - Serial.printf("%08X\n", (uint32_t)value); // Print Low 4 bytes in HEX + Serial.printf("0x%08lX", (uint32_t)(value >> 32)); // Print High 4 bytes in HEX + Serial.printf("%08lX\n", (uint32_t)value); // Print Low 4 bytes in HEX address += sizeof(int64_t); Value = 0; // Clear Value Value = EEPROM.readULong64(Value); - Serial.printf("0x%08X", (uint32_t)(Value >> 32)); // Print High 4 bytes in HEX - Serial.printf("%08X\n", (uint32_t)Value); // Print Low 4 bytes in HEX + Serial.printf("0x%08lX", (uint32_t)(Value >> 32)); // Print High 4 bytes in HEX + Serial.printf("%08lX\n", (uint32_t)Value); // Print Low 4 bytes in HEX address += sizeof(uint64_t); Serial.println(EEPROM.readFloat(address), 4); diff --git a/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino b/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino index ced1b4dcef3..12e3a3e8cdc 100644 --- a/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino +++ b/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino @@ -19,11 +19,11 @@ void setup() { uint32_t max_frequency; uint32_t frequency; uint32_t successful_frequency; - uint32_t max_freq_array[SOC_LEDC_TIMER_BIT_WIDE_NUM]; - uint32_t min_freq_array[SOC_LEDC_TIMER_BIT_WIDE_NUM]; + uint32_t max_freq_array[SOC_LEDC_TIMER_BIT_WIDTH]; + uint32_t min_freq_array[SOC_LEDC_TIMER_BIT_WIDTH]; // Find Max Frequency - for(uint8_t resolution = 1; resolution <= SOC_LEDC_TIMER_BIT_WIDE_NUM; ++resolution){ + for(uint8_t resolution = 1; resolution <= SOC_LEDC_TIMER_BIT_WIDTH; ++resolution){ max_freq_array[resolution-1] = 0; min_frequency = 0; max_frequency = UINT32_MAX; @@ -41,7 +41,7 @@ void setup() { } // for all resolutions // Find Min Frequency - for(uint8_t resolution = 1; resolution <= SOC_LEDC_TIMER_BIT_WIDE_NUM; ++resolution){ + for(uint8_t resolution = 1; resolution <= SOC_LEDC_TIMER_BIT_WIDTH; ++resolution){ min_freq_array[resolution-1] = 0; min_frequency = 0; max_frequency = max_freq_array[resolution-1]; @@ -59,9 +59,9 @@ void setup() { } // for all resolutions printf("Bit resolution | Min Frequency [Hz] | Max Frequency [Hz]\n"); - for(uint8_t r = 1; r <= SOC_LEDC_TIMER_BIT_WIDE_NUM; ++r){ + for(uint8_t r = 1; r <= SOC_LEDC_TIMER_BIT_WIDTH; ++r){ size_t max_len = std::to_string(UINT32_MAX).length(); - printf(" %s%d | %s%u | %s%u\n", + printf(" %s%d | %s%lu | %s%lu\n", std::string (2 - std::to_string(r).length(), ' ').c_str(), r, std::string (max_len - std::to_string(min_freq_array[r-1]).length(), ' ').c_str(), min_freq_array[r-1], diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index 01da91fb3b4..5629c6a81f1 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp +++ b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp @@ -313,7 +313,7 @@ static esp_err_t bmp_handler(httpd_req_t *req) httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); char ts[32]; - snprintf(ts, 32, "%ld.%06ld", fb->timestamp.tv_sec, fb->timestamp.tv_usec); + snprintf(ts, 32, "%lld.%06ld", fb->timestamp.tv_sec, fb->timestamp.tv_usec); httpd_resp_set_hdr(req, "X-Timestamp", (const char *)ts); @@ -379,7 +379,7 @@ static esp_err_t capture_handler(httpd_req_t *req) httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); char ts[32]; - snprintf(ts, 32, "%ld.%06ld", fb->timestamp.tv_sec, fb->timestamp.tv_usec); + snprintf(ts, 32, "%lld.%06ld", fb->timestamp.tv_sec, fb->timestamp.tv_usec); httpd_resp_set_hdr(req, "X-Timestamp", (const char *)ts); #if CONFIG_ESP_FACE_DETECT_ENABLED diff --git a/libraries/ESP32/examples/DeepSleep/SmoothBlink_ULP_Code/SmoothBlink_ULP_Code.ino b/libraries/ESP32/examples/DeepSleep/SmoothBlink_ULP_Code/SmoothBlink_ULP_Code.ino index 77a886209df..28f9ffbccf8 100644 --- a/libraries/ESP32/examples/DeepSleep/SmoothBlink_ULP_Code/SmoothBlink_ULP_Code.ino +++ b/libraries/ESP32/examples/DeepSleep/SmoothBlink_ULP_Code/SmoothBlink_ULP_Code.ino @@ -8,6 +8,7 @@ #include #include "esp32/ulp.h" #include "driver/rtc_io.h" +#include "soc/rtc_io_reg.h" // RTC Memory used for ULP internal variable and Sketch interfacing #define RTC_dutyMeter 0 @@ -143,7 +144,7 @@ void setup() { while (!Serial) {} // wait for Serial to start ulp_setup(); // it really only runs on the first ESP32 boot - Serial.printf("\nStarted smooth blink with delay %d\n", *fadeCycleDelay); + Serial.printf("\nStarted smooth blink with delay %ld\n", *fadeCycleDelay); // *fadeCycleDelay resides in RTC_SLOW_MEM and persists along deep sleep waking up // it is used as a delay time parameter for smooth blinking, in the ULP processing code diff --git a/libraries/ESP32/examples/ESPNow/Basic/Slave/Slave.ino b/libraries/ESP32/examples/ESPNow/Basic/Slave/Slave.ino index d2b5b09b10c..50711b18fd5 100644 --- a/libraries/ESP32/examples/ESPNow/Basic/Slave/Slave.ino +++ b/libraries/ESP32/examples/ESPNow/Basic/Slave/Slave.ino @@ -78,10 +78,10 @@ void setup() { } // callback when data is recv from Master -void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) { +void OnDataRecv(const esp_now_recv_info_t * info, const uint8_t *data, int data_len) { char macStr[18]; snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", - mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + info->src_addr[0], info->src_addr[1], info->src_addr[2], info->src_addr[3], info->src_addr[4], info->src_addr[5]); Serial.print("Last Packet Recv from: "); Serial.println(macStr); Serial.print("Last Packet Recv Data: "); Serial.println(*data); Serial.println(""); diff --git a/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino b/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino index 42ce40ba0d1..ad3b94037c3 100644 --- a/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino +++ b/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino @@ -80,10 +80,10 @@ void setup() { } // callback when data is recv from Master -void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) { +void OnDataRecv(const esp_now_recv_info_t * info, const uint8_t *data, int data_len) { char macStr[18]; snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", - mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + info->src_addr[0], info->src_addr[1], info->src_addr[2], info->src_addr[3], info->src_addr[4], info->src_addr[5]); Serial.print("Last Packet Recv from: "); Serial.println(macStr); Serial.print("Last Packet Recv Data: "); Serial.println(*data); Serial.println(""); diff --git a/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino b/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino index f18db753342..753ac2b745f 100644 --- a/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino +++ b/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino @@ -22,7 +22,7 @@ public: void checkPressed() { if (pressed) { - Serial.printf("Button on pin %u has been pressed %u times\n", PIN, numberKeyPresses); + Serial.printf("Button on pin %u has been pressed %lu times\n", PIN, numberKeyPresses); pressed = false; } } diff --git a/libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino b/libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino index 8d9d8d3b1a0..f208024256f 100644 --- a/libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino +++ b/libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino @@ -30,11 +30,11 @@ void setup() { void loop() { if (button1.pressed) { - Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses); + Serial.printf("Button 1 has been pressed %lu times\n", button1.numberKeyPresses); button1.pressed = false; } if (button2.pressed) { - Serial.printf("Button 2 has been pressed %u times\n", button2.numberKeyPresses); + Serial.printf("Button 2 has been pressed %lu times\n", button2.numberKeyPresses); button2.pressed = false; } static uint32_t lastMillis = 0; diff --git a/libraries/ESP32/examples/HallSensor/.skip.esp32c3 b/libraries/ESP32/examples/HallSensor/.skip.esp32c3 deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libraries/ESP32/examples/HallSensor/.skip.esp32s2 b/libraries/ESP32/examples/HallSensor/.skip.esp32s2 deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libraries/ESP32/examples/HallSensor/.skip.esp32s3 b/libraries/ESP32/examples/HallSensor/.skip.esp32s3 deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libraries/ESP32/examples/HallSensor/HallSensor.ino b/libraries/ESP32/examples/HallSensor/HallSensor.ino deleted file mode 100644 index 8045ac918da..00000000000 --- a/libraries/ESP32/examples/HallSensor/HallSensor.ino +++ /dev/null @@ -1,15 +0,0 @@ -//Simple sketch to access the internal hall effect detector on the esp32. -//values can be quite low. -//Brian Degger / @sctv -int val = 0; -void setup() { - Serial.begin(9600); - } - -void loop() { - // put your main code here, to run repeatedly: - val = hallRead(); - // print the results to the serial monitor: - //Serial.print("sensor = "); - Serial.println(val);//to graph -} diff --git a/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino b/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino index e3b40d2c8d5..94c61809a3e 100644 --- a/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino +++ b/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino @@ -120,7 +120,7 @@ void loop(){ if(read_counter == AVERAGE_EVERY_N_SAMPLES){ averaged_reading = read_sum / AVERAGE_EVERY_N_SAMPLES; //Serial.printf("averaged_reading = %d over %d samples\n", averaged_reading, read_counter); // Print with additional info - Serial.printf("Averaged_signal:%d", averaged_reading); // Print compatible with Arduino Plotter + Serial.printf("Averaged_signal:%ld", averaged_reading); // Print compatible with Arduino Plotter read_counter = 0; read_sum = 0; } diff --git a/libraries/ESP32/examples/RMT/RMTCallback/RMTCallback.ino b/libraries/ESP32/examples/RMT/RMTCallback/RMTCallback.ino index de28da6c85d..61e6b55abcc 100644 --- a/libraries/ESP32/examples/RMT/RMTCallback/RMTCallback.ino +++ b/libraries/ESP32/examples/RMT/RMTCallback/RMTCallback.ino @@ -62,6 +62,6 @@ void setup() void loop() { - Serial.printf("GPIO 4: %08x 5: %08x 10: %08x\n", mp1.val(), mp2.val(), mp3.val()); + Serial.printf("GPIO 4: %08lx 5: %08lx 10: %08lx\n", mp1.val(), mp2.val(), mp3.val()); delay(500); } \ No newline at end of file diff --git a/libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino b/libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino index 6b1ee2fa55d..851ced04131 100644 --- a/libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino +++ b/libraries/ESP32/examples/RMT/RMTLoopback/RMTLoopback.ino @@ -65,7 +65,7 @@ void loop() // Printout the received data plus the original values for (i=0; i<60; i++) { - Serial.printf("%08x=%08x ", my_data[i].val, data[i].val ); + Serial.printf("%08lx=%08lx ", my_data[i].val, data[i].val ); if (!((i+1)%4)) Serial.println("\n"); } Serial.println("\n"); diff --git a/libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino b/libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino index f87dd220513..1dcd8542da1 100644 --- a/libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino +++ b/libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino @@ -198,6 +198,6 @@ void setup() void loop() { // printout some of the channels - Serial.printf("%04x %04x %04x %04x\n", channels[0], channels[1], channels[2], channels[3]); + Serial.printf("%04lx %04lx %04lx %04lx\n", channels[0], channels[1], channels[2], channels[3]); delay(500); } diff --git a/libraries/ESP32/examples/Serial/RxFIFOFull_Demo/RxFIFOFull_Demo.ino b/libraries/ESP32/examples/Serial/RxFIFOFull_Demo/RxFIFOFull_Demo.ino index f5c8dabaf39..878150264da 100644 --- a/libraries/ESP32/examples/Serial/RxFIFOFull_Demo/RxFIFOFull_Demo.ino +++ b/libraries/ESP32/examples/Serial/RxFIFOFull_Demo/RxFIFOFull_Demo.ino @@ -91,10 +91,10 @@ void testAndReport(uint8_t fifoFull) { uint32_t pastTime = millis() - now; Serial.printf("\nIt has sent %d bytes from Serial1 TX to Serial1 RX\n", sentBytes); - Serial.printf("It took %d milliseconds to read %d bytes\n", pastTime, bytesReceived); + Serial.printf("It took %lu milliseconds to read %d bytes\n", pastTime, bytesReceived); Serial.printf("Per execution Serial.read() number of bytes data and time information:\n"); for (i = 0; i < DATA_SIZE; i++) { - Serial.printf("#%03d - Received %03d bytes after %d ms.\n", i, bytesJustReceived[i], i > 0 ? timeStamp[i] - timeStamp[i - 1] : timeStamp[i] - now); + Serial.printf("#%03d - Received %03lu bytes after %lu ms.\n", i, bytesJustReceived[i], i > 0 ? timeStamp[i] - timeStamp[i - 1] : timeStamp[i] - now); if (i != DATA_SIZE - 1 && bytesJustReceived[i + 1] == 0) break; } diff --git a/libraries/ESP32/examples/Serial/RxTimeout_Demo/RxTimeout_Demo.ino b/libraries/ESP32/examples/Serial/RxTimeout_Demo/RxTimeout_Demo.ino index 35a94bd2747..b4592f8249d 100644 --- a/libraries/ESP32/examples/Serial/RxTimeout_Demo/RxTimeout_Demo.ino +++ b/libraries/ESP32/examples/Serial/RxTimeout_Demo/RxTimeout_Demo.ino @@ -87,7 +87,7 @@ void testAndReport(uint8_t rxTimeout) { uint32_t pastTime = millis() - now; Serial.printf("\nIt has sent %d bytes from Serial1 TX to Serial1 RX\n", sentBytes); - Serial.printf("It took %d milliseconds to read %d bytes\n", pastTime, bytesReceived); + Serial.printf("It took %lu milliseconds to read %d bytes\n", pastTime, bytesReceived); Serial.print("Received data: ["); Serial.write(dataReceived, DATA_SIZE); Serial.println("]"); diff --git a/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino b/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino index e0fd8864596..0438d26daa8 100644 --- a/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino +++ b/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino @@ -80,7 +80,7 @@ static void handle_rx_message(twai_message_t& message) { } else { Serial.println("Message is in Standard Format"); } - Serial.printf("ID: %x\nByte:", message.identifier); + Serial.printf("ID: %lx\nByte:", message.identifier); if (!(message.rtr)) { for (int i = 0; i < message.data_length_code; i++) { Serial.printf(" %d = %02x,", i, message.data[i]); @@ -107,13 +107,13 @@ void loop() { } if (alerts_triggered & TWAI_ALERT_BUS_ERROR) { Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus."); - Serial.printf("Bus error count: %d\n", twaistatus.bus_error_count); + Serial.printf("Bus error count: %lu\n", twaistatus.bus_error_count); } if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) { Serial.println("Alert: The RX queue is full causing a received frame to be lost."); - Serial.printf("RX buffered: %d\t", twaistatus.msgs_to_rx); - Serial.printf("RX missed: %d\t", twaistatus.rx_missed_count); - Serial.printf("RX overrun %d\n", twaistatus.rx_overrun_count); + Serial.printf("RX buffered: %lu\t", twaistatus.msgs_to_rx); + Serial.printf("RX missed: %lu\t", twaistatus.rx_missed_count); + Serial.printf("RX overrun %lu\n", twaistatus.rx_overrun_count); } // Check if message is received diff --git a/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino b/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino index e157dae3ad7..25163dafeb2 100644 --- a/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino +++ b/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino @@ -1,4 +1,5 @@ #include "esp_system.h" +#include "rom/ets_sys.h" const int button = 0; //gpio to use to trigger delay const int wdtTimeout = 3000; //time in ms to trigger the watchdog diff --git a/libraries/FFat/examples/FFat_Test/FFat_Test.ino b/libraries/FFat/examples/FFat_Test/FFat_Test.ino index 9ae55a8c5e4..d31637af0eb 100644 --- a/libraries/FFat/examples/FFat_Test/FFat_Test.ino +++ b/libraries/FFat/examples/FFat_Test/FFat_Test.ino @@ -127,7 +127,7 @@ void testFileIO(fs::FS &fs, const char * path){ } Serial.println(""); uint32_t end = millis() - start; - Serial.printf(" - %u bytes written in %u ms\r\n", 2048 * 512, end); + Serial.printf(" - %u bytes written in %lu ms\r\n", 2048 * 512, end); file.close(); file = fs.open(path); @@ -152,7 +152,7 @@ void testFileIO(fs::FS &fs, const char * path){ } Serial.println(""); end = millis() - start; - Serial.printf("- %u bytes read in %u ms\r\n", flen, end); + Serial.printf("- %u bytes read in %lu ms\r\n", flen, end); file.close(); } else { Serial.println("- failed to open file for reading"); diff --git a/libraries/I2S/examples/SimpleTone/SimpleTone.ino b/libraries/I2S/examples/SimpleTone/SimpleTone.ino index dd312cf8a82..49cae77238f 100644 --- a/libraries/I2S/examples/SimpleTone/SimpleTone.ino +++ b/libraries/I2S/examples/SimpleTone/SimpleTone.ino @@ -35,7 +35,7 @@ const int bps = 16; const int halfWavelength = (sampleRate / frequency); // half wavelength of square wave -short sample = amplitude; // current sample value +int32_t sample = amplitude; // current sample value int count = 0; i2s_mode_t mode = I2S_PHILIPS_MODE; // I2S decoder is needed diff --git a/libraries/LittleFS/examples/LITTLEFS_test/LITTLEFS_test.ino b/libraries/LittleFS/examples/LITTLEFS_test/LITTLEFS_test.ino index a3b0145385a..5c3ca4b2f9c 100644 --- a/libraries/LittleFS/examples/LITTLEFS_test/LITTLEFS_test.ino +++ b/libraries/LittleFS/examples/LITTLEFS_test/LITTLEFS_test.ino @@ -208,7 +208,7 @@ void testFileIO(fs::FS &fs, const char * path){ } Serial.println(""); uint32_t end = millis() - start; - Serial.printf(" - %u bytes written in %u ms\r\n", 2048 * 512, end); + Serial.printf(" - %u bytes written in %lu ms\r\n", 2048 * 512, end); file.close(); file = fs.open(path); @@ -233,7 +233,7 @@ void testFileIO(fs::FS &fs, const char * path){ } Serial.println(""); end = millis() - start; - Serial.printf("- %u bytes read in %u ms\r\n", flen, end); + Serial.printf("- %u bytes read in %lu ms\r\n", flen, end); file.close(); } else { Serial.println("- failed to open file for reading"); diff --git a/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino b/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino index 8ae1e5434f9..1b6abc7f49e 100644 --- a/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino +++ b/libraries/RainMaker/examples/RMakerSonoffDualR3/RMakerSonoffDualR3.ino @@ -151,7 +151,7 @@ void setup() chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; } - Serial.printf("\nChip ID: %d Service Name: %s\n", chipId, service_name); + Serial.printf("\nChip ID: %lu Service Name: %s\n", chipId, service_name); Serial.printf("\nStarting ESP-RainMaker\n"); RMaker.start(); diff --git a/libraries/SD/examples/SD_Test/SD_Test.ino b/libraries/SD/examples/SD_Test/SD_Test.ino index 8084ee17dae..5ecabaeea89 100644 --- a/libraries/SD/examples/SD_Test/SD_Test.ino +++ b/libraries/SD/examples/SD_Test/SD_Test.ino @@ -150,7 +150,7 @@ void testFileIO(fs::FS &fs, const char * path){ len -= toRead; } end = millis() - start; - Serial.printf("%u bytes read for %u ms\n", flen, end); + Serial.printf("%u bytes read for %lu ms\n", flen, end); file.close(); } else { Serial.println("Failed to open file for reading"); @@ -169,7 +169,7 @@ void testFileIO(fs::FS &fs, const char * path){ file.write(buf, 512); } end = millis() - start; - Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end); + Serial.printf("%u bytes written for %lu ms\n", 2048 * 512, end); file.close(); } diff --git a/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino b/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino index 024ea4bfdea..2ec9f663fd9 100644 --- a/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino +++ b/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino @@ -147,7 +147,7 @@ void testFileIO(fs::FS &fs, const char * path){ len -= toRead; } end = millis() - start; - Serial.printf("%u bytes read for %u ms\n", flen, end); + Serial.printf("%u bytes read for %lu ms\n", flen, end); file.close(); } else { Serial.println("Failed to open file for reading"); @@ -166,7 +166,7 @@ void testFileIO(fs::FS &fs, const char * path){ file.write(buf, 512); } end = millis() - start; - Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end); + Serial.printf("%u bytes written for %lu ms\n", 2048 * 512, end); file.close(); } diff --git a/libraries/SPIFFS/examples/SPIFFS_Test/SPIFFS_Test.ino b/libraries/SPIFFS/examples/SPIFFS_Test/SPIFFS_Test.ino index 9ee67e6c12f..3b19be5eaee 100644 --- a/libraries/SPIFFS/examples/SPIFFS_Test/SPIFFS_Test.ino +++ b/libraries/SPIFFS/examples/SPIFFS_Test/SPIFFS_Test.ino @@ -125,7 +125,7 @@ void testFileIO(fs::FS &fs, const char * path){ } Serial.println(""); uint32_t end = millis() - start; - Serial.printf(" - %u bytes written in %u ms\r\n", 2048 * 512, end); + Serial.printf(" - %u bytes written in %lu ms\r\n", 2048 * 512, end); file.close(); file = fs.open(path); @@ -150,7 +150,7 @@ void testFileIO(fs::FS &fs, const char * path){ } Serial.println(""); end = millis() - start; - Serial.printf("- %u bytes read in %u ms\r\n", flen, end); + Serial.printf("- %u bytes read in %lu ms\r\n", flen, end); file.close(); } else { Serial.println("- failed to open file for reading"); diff --git a/libraries/USB/examples/CompositeDevice/CompositeDevice.ino b/libraries/USB/examples/CompositeDevice/CompositeDevice.ino index 4c1021bc57b..587720ab85e 100644 --- a/libraries/USB/examples/CompositeDevice/CompositeDevice.ino +++ b/libraries/USB/examples/CompositeDevice/CompositeDevice.ino @@ -67,7 +67,7 @@ static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t eve HWSerial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts); break; case ARDUINO_USB_CDC_LINE_CODING_EVENT: - HWSerial.printf("CDC LINE CODING: bit_rate: %u, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity); + HWSerial.printf("CDC LINE CODING: bit_rate: %lu, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity); break; case ARDUINO_USB_CDC_RX_EVENT: HWSerial.printf("CDC RX [%u]:", data->rx.len); diff --git a/libraries/USB/examples/USBMSC/USBMSC.ino b/libraries/USB/examples/USBMSC/USBMSC.ino index 67378109985..bf836cad087 100644 --- a/libraries/USB/examples/USBMSC/USBMSC.ino +++ b/libraries/USB/examples/USBMSC/USBMSC.ino @@ -136,13 +136,13 @@ static uint8_t msc_disk[DISK_SECTOR_COUNT][DISK_SECTOR_SIZE] = }; static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize){ - HWSerial.printf("MSC WRITE: lba: %u, offset: %u, bufsize: %u\n", lba, offset, bufsize); + HWSerial.printf("MSC WRITE: lba: %lu, offset: %lu, bufsize: %lu\n", lba, offset, bufsize); memcpy(msc_disk[lba] + offset, buffer, bufsize); return bufsize; } static int32_t onRead(uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize){ - HWSerial.printf("MSC READ: lba: %u, offset: %u, bufsize: %u\n", lba, offset, bufsize); + HWSerial.printf("MSC READ: lba: %lu, offset: %lu, bufsize: %lu\n", lba, offset, bufsize); memcpy(buffer, msc_disk[lba] + offset, bufsize); return bufsize; } diff --git a/libraries/USB/examples/USBSerial/USBSerial.ino b/libraries/USB/examples/USBSerial/USBSerial.ino index 0f57e2b1b1d..e9cd317d9c9 100644 --- a/libraries/USB/examples/USBSerial/USBSerial.ino +++ b/libraries/USB/examples/USBSerial/USBSerial.ino @@ -46,7 +46,7 @@ static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t eve HWSerial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts); break; case ARDUINO_USB_CDC_LINE_CODING_EVENT: - HWSerial.printf("CDC LINE CODING: bit_rate: %u, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity); + HWSerial.printf("CDC LINE CODING: bit_rate: %lu, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity); break; case ARDUINO_USB_CDC_RX_EVENT: HWSerial.printf("CDC RX [%u]:", data->rx.len); diff --git a/libraries/USB/examples/USBVendor/USBVendor.ino b/libraries/USB/examples/USBVendor/USBVendor.ino index 9dbb54fb6e2..7336b4a55ab 100644 --- a/libraries/USB/examples/USBVendor/USBVendor.ino +++ b/libraries/USB/examples/USBVendor/USBVendor.ino @@ -113,7 +113,7 @@ bool vendorRequestCallback(uint8_t rhport, uint8_t requestStage, arduino_usb_con result = Vendor.sendResponse(rhport, request, (void*) &vendor_line_coding, sizeof(request_line_coding_t)); } else if (requestStage == REQUEST_STAGE_ACK) { //In the ACK stage the response is complete - HWSerial.printf("Vendor Line Coding: bit_rate: %u, data_bits: %u, stop_bits: %u, parity: %u\n", vendor_line_coding.bit_rate, vendor_line_coding.data_bits, vendor_line_coding.stop_bits, vendor_line_coding.parity); + HWSerial.printf("Vendor Line Coding: bit_rate: %lu, data_bits: %u, stop_bits: %u, parity: %u\n", vendor_line_coding.bit_rate, vendor_line_coding.data_bits, vendor_line_coding.stop_bits, vendor_line_coding.parity); } result = true; break; diff --git a/libraries/Update/examples/HTTPS_OTA_Update/HTTPS_OTA_Update.ino b/libraries/Update/examples/HTTPS_OTA_Update/HTTPS_OTA_Update.ino index 6e32ee5bd58..dfc6266e2fa 100644 --- a/libraries/Update/examples/HTTPS_OTA_Update/HTTPS_OTA_Update.ino +++ b/libraries/Update/examples/HTTPS_OTA_Update/HTTPS_OTA_Update.ino @@ -62,6 +62,9 @@ void HttpEvent(HttpEvent_t *event) case HTTP_EVENT_DISCONNECTED: Serial.println("Http Event Disconnected"); break; + case HTTP_EVENT_REDIRECT: + Serial.println("Http Event Redirect"); + break; } } diff --git a/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino b/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino index 91c1ba45cb4..6cc8659e3e2 100644 --- a/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino +++ b/libraries/WiFi/examples/FTM/FTM_Initiator/FTM_Initiator.ino @@ -35,7 +35,7 @@ void onFtmReport(arduino_event_t *event) { ftmSuccess = report->status == FTM_STATUS_SUCCESS; if (ftmSuccess) { // The estimated distance in meters may vary depending on some factors (see README file) - Serial.printf("FTM Estimate: Distance: %.2f m, Return Time: %u ns\n", (float)report->dist_est / 100.0, report->rtt_est); + Serial.printf("FTM Estimate: Distance: %.2f m, Return Time: %lu ns\n", (float)report->dist_est / 100.0, report->rtt_est); // Pointer to FTM Report with multiple entries, should be freed after use free(report->ftm_report_data); } else { diff --git a/libraries/WiFi/examples/WiFiScan/WiFiScan.ino b/libraries/WiFi/examples/WiFiScan/WiFiScan.ino index 12827e88ed0..5bef55f878d 100644 --- a/libraries/WiFi/examples/WiFiScan/WiFiScan.ino +++ b/libraries/WiFi/examples/WiFiScan/WiFiScan.ino @@ -36,9 +36,9 @@ void loop() Serial.print(" | "); Serial.printf("%-32.32s", WiFi.SSID(i).c_str()); Serial.print(" | "); - Serial.printf("%4d", WiFi.RSSI(i)); + Serial.printf("%4ld", WiFi.RSSI(i)); Serial.print(" | "); - Serial.printf("%2d", WiFi.channel(i)); + Serial.printf("%2ld", WiFi.channel(i)); Serial.print(" | "); switch (WiFi.encryptionType(i)) { diff --git a/libraries/Wire/examples/WireMaster/WireMaster.ino b/libraries/Wire/examples/WireMaster/WireMaster.ino index e3736bf9fcc..ba5bca5c168 100644 --- a/libraries/Wire/examples/WireMaster/WireMaster.ino +++ b/libraries/Wire/examples/WireMaster/WireMaster.ino @@ -15,7 +15,7 @@ void loop() { //Write message to the slave Wire.beginTransmission(I2C_DEV_ADDR); - Wire.printf("Hello World! %u", i++); + Wire.printf("Hello World! %lu", i++); uint8_t error = Wire.endTransmission(true); Serial.printf("endTransmission: %u\n", error); diff --git a/libraries/Wire/examples/WireSlave/WireSlave.ino b/libraries/Wire/examples/WireSlave/WireSlave.ino index ea5c1995b71..e689e189a7a 100644 --- a/libraries/Wire/examples/WireSlave/WireSlave.ino +++ b/libraries/Wire/examples/WireSlave/WireSlave.ino @@ -27,7 +27,7 @@ void setup() { #if CONFIG_IDF_TARGET_ESP32 char message[64]; - snprintf(message, 64, "%u Packets.", i++); + snprintf(message, 64, "%lu Packets.", i++); Wire.slaveWrite((uint8_t *)message, strlen(message)); #endif } From 777d661af0db7bd59c832c7b1f6e37de4134f643 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 20 Jan 2023 01:54:14 +0200 Subject: [PATCH 06/60] Update app_httpd.cpp --- libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index 5629c6a81f1..113d222ace5 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp +++ b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp @@ -49,9 +49,11 @@ /* very large firmware, very slow, reboots when streaming... From aa2cf45e331956fefeefba4f2c2ea2808bf29d32 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 20 Jan 2023 02:04:39 +0200 Subject: [PATCH 07/60] Update ResetReason.ino --- libraries/ESP32/examples/ResetReason/ResetReason.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/ESP32/examples/ResetReason/ResetReason.ino b/libraries/ESP32/examples/ResetReason/ResetReason.ino index 2ccf7107d03..3da7d400382 100644 --- a/libraries/ESP32/examples/ResetReason/ResetReason.ino +++ b/libraries/ESP32/examples/ResetReason/ResetReason.ino @@ -91,7 +91,11 @@ void setup() { // Set ESP32 to go to deep sleep to see a variation // in the reset reason. Device will sleep for 5 seconds. +#if CONFIG_IDF_TARGET_ESP32C3 + esp_sleep_pd_config(ESP_PD_DOMAIN_RC_FAST, ESP_PD_OPTION_OFF); +#else esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF); +#endif Serial.println("Going to sleep"); esp_deep_sleep(5 * uS_TO_S_FACTOR); } From 27fb23a8e97af586f8453c076efc04a13be7ade2 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 20 Jan 2023 17:33:21 +0200 Subject: [PATCH 08/60] Warnings fixes --- .gitignore | 1 + cores/esp32/HWCDC.cpp | 2 ++ cores/esp32/esp32-hal-gpio.c | 2 +- cores/esp32/esp32-hal-spi.c | 10 +++++----- cores/esp32/esp32-hal-touch.c | 13 ++++++++++--- cores/esp32/wiring_pulse.c | 10 +++++----- .../BLE5_multi_advertising.ino | 12 ++++++++++++ .../BLE5_periodic_advertising.ino | 3 +++ .../BLE5_periodic_sync/BLE5_periodic_sync.ino | 1 + .../BluetoothSerial/src/BluetoothSerial.cpp | 4 +++- .../Camera/CameraWebServer/CameraWebServer.ino | 4 ++-- .../Camera/CameraWebServer/app_httpd.cpp | 2 ++ libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino | 3 +++ .../FunctionalInterrupt.ino | 2 +- .../examples/I2S/HiFreq_ADC/HiFreq_ADC.ino | 4 +++- .../OnReceiveError_BREAK_Demo.ino | 2 +- .../Serial/OnReceive_Demo/OnReceive_Demo.ino | 2 +- .../examples/TWAI/TWAIreceive/TWAIreceive.ino | 1 + .../examples/Timer/RepeatTimer/RepeatTimer.ino | 2 +- libraries/FFat/src/FFat.cpp | 18 ++++++++++-------- libraries/I2S/src/I2S.cpp | 16 +++++++++++++++- libraries/RainMaker/src/RMaker.cpp | 1 + libraries/SD_MMC/src/SD_MMC.cpp | 3 ++- .../examples/SDWebServer/SDWebServer.ino | 1 - libraries/WebServer/src/WebServer.h | 2 +- .../WiFiAccessPoint/WiFiAccessPoint.ino | 2 ++ libraries/WiFi/src/WiFiUdp.cpp | 4 ++-- 27 files changed, 91 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index c9d6a46ba85..4ed76929896 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ _build/ debug.cfg debug.svd debug_custom.json +libraries/Insights/examples/*/*.ino.zip diff --git a/cores/esp32/HWCDC.cpp b/cores/esp32/HWCDC.cpp index fac4530f33a..aacd589e5ec 100644 --- a/cores/esp32/HWCDC.cpp +++ b/cores/esp32/HWCDC.cpp @@ -22,7 +22,9 @@ #include "freertos/ringbuf.h" #include "esp_intr_alloc.h" #include "soc/periph_defs.h" +#pragma GCC diagnostic ignored "-Wvolatile" #include "hal/usb_serial_jtag_ll.h" +#pragma GCC diagnostic warning "-Wvolatile" #include "rom/ets_sys.h" ESP_EVENT_DEFINE_BASE(ARDUINO_HW_CDC_EVENTS); diff --git a/cores/esp32/esp32-hal-gpio.c b/cores/esp32/esp32-hal-gpio.c index f0f99db9abf..5569da5c0f1 100644 --- a/cores/esp32/esp32-hal-gpio.c +++ b/cores/esp32/esp32-hal-gpio.c @@ -98,7 +98,7 @@ extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode) } #endif - if (!GPIO_IS_VALID_GPIO(pin)) { + if (pin >= SOC_GPIO_PIN_COUNT) { log_e("Invalid pin selected"); return; } diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index 16ff3b65d10..4e7643ec4ee 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -1515,11 +1515,11 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq) uint8_t calN = 1; spiClk_t bestReg = { 0 }; - int32_t bestFreq = 0; + uint32_t bestFreq = 0; while(calN <= 0x3F) { spiClk_t reg = { 0 }; - int32_t calFreq; + uint32_t calFreq; int32_t calPre; int8_t calPreVari = -2; @@ -1541,11 +1541,11 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq) } reg.clkcnt_l = ((reg.clkcnt_n + 1) / 2); calFreq = ClkRegToFreq(®); - if(calFreq == (int32_t) freq) { + if(calFreq == freq) { memcpy(&bestReg, ®, sizeof(bestReg)); break; - } else if(calFreq < (int32_t) freq) { - if(abs(freq - calFreq) < abs(freq - bestFreq)) { + } else if(calFreq < freq) { + if((freq - calFreq) < (freq - bestFreq)) { bestFreq = calFreq; memcpy(&bestReg, ®, sizeof(bestReg)); } diff --git a/cores/esp32/esp32-hal-touch.c b/cores/esp32/esp32-hal-touch.c index 476df60850c..3c929de363f 100644 --- a/cores/esp32/esp32-hal-touch.c +++ b/cores/esp32/esp32-hal-touch.c @@ -91,7 +91,12 @@ static void __touchSetCycles(uint16_t measure, uint16_t sleep) { __touchSleepCycles = sleep; __touchMeasureCycles = measure; - touch_pad_set_meas_time(sleep, measure); +#if SOC_TOUCH_VERSION_1 // ESP32 + touch_pad_set_measurement_clock_cycles(measure); +#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3 + touch_pad_set_charge_discharge_times(measure); +#endif + touch_pad_set_measurement_interval(sleep); } @@ -112,7 +117,8 @@ static void __touchInit() } // the next two lines will drive the touch reading values -- both will return ESP_OK touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V); - touch_pad_set_meas_time(__touchMeasureCycles, __touchSleepCycles); + touch_pad_set_measurement_clock_cycles(__touchMeasureCycles); + touch_pad_set_measurement_interval(__touchSleepCycles); // Touch Sensor Timer initiated touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK err = touch_pad_filter_start(10); @@ -131,7 +137,8 @@ static void __touchInit() goto err; } // the next lines will drive the touch reading values -- all os them return ESP_OK - touch_pad_set_meas_time(__touchSleepCycles, __touchMeasureCycles); + touch_pad_set_charge_discharge_times(__touchMeasureCycles); + touch_pad_set_measurement_interval(__touchSleepCycles); touch_pad_set_voltage(TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD); touch_pad_set_idle_channel_connect(TOUCH_PAD_IDLE_CH_CONNECT_DEFAULT); touch_pad_denoise_t denoise = { diff --git a/cores/esp32/wiring_pulse.c b/cores/esp32/wiring_pulse.c index cb3e946d6cc..8c55e7258ef 100644 --- a/cores/esp32/wiring_pulse.c +++ b/cores/esp32/wiring_pulse.c @@ -17,11 +17,11 @@ //#include #include "wiring_private.h" #include "pins_arduino.h" -#include +#include "esp_cpu.h" #define WAIT_FOR_PIN_STATE(state) \ while (digitalRead(pin) != (state)) { \ - if (cpu_hal_get_cycle_count() - start_cycle_count > timeout_cycles) { \ + if (esp_cpu_get_cycle_count() - start_cycle_count > timeout_cycles) { \ return 0; \ } \ } @@ -34,12 +34,12 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) timeout = max_timeout_us; } const uint32_t timeout_cycles = microsecondsToClockCycles(timeout); - const uint32_t start_cycle_count = cpu_hal_get_cycle_count(); + const uint32_t start_cycle_count = esp_cpu_get_cycle_count(); WAIT_FOR_PIN_STATE(!state); WAIT_FOR_PIN_STATE(state); - const uint32_t pulse_start_cycle_count = cpu_hal_get_cycle_count(); + const uint32_t pulse_start_cycle_count = esp_cpu_get_cycle_count(); WAIT_FOR_PIN_STATE(!state); - return clockCyclesToMicroseconds(cpu_hal_get_cycle_count() - pulse_start_cycle_count); + return clockCyclesToMicroseconds(esp_cpu_get_cycle_count() - pulse_start_cycle_count); } unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) diff --git a/libraries/BLE/examples/BLE5_multi_advertising/BLE5_multi_advertising.ino b/libraries/BLE/examples/BLE5_multi_advertising/BLE5_multi_advertising.ino index 217c2ed3bc4..ddd282aea7b 100644 --- a/libraries/BLE/examples/BLE5_multi_advertising/BLE5_multi_advertising.ino +++ b/libraries/BLE/examples/BLE5_multi_advertising/BLE5_multi_advertising.ino @@ -15,7 +15,10 @@ esp_ble_gap_ext_adv_params_t ext_adv_params_1M = { .interval_max = 0x30, .channel_map = ADV_CHNL_ALL, .own_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr = {0,0,0,0,0,0}, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + .tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE, .primary_phy = ESP_BLE_GAP_PHY_CODED, .max_skip = 0, .secondary_phy = ESP_BLE_GAP_PHY_1M, @@ -29,7 +32,10 @@ esp_ble_gap_ext_adv_params_t ext_adv_params_2M = { .interval_max = 0x40, .channel_map = ADV_CHNL_ALL, .own_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr = {0,0,0,0,0,0}, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + .tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE, .primary_phy = ESP_BLE_GAP_PHY_1M, .max_skip = 0, .secondary_phy = ESP_BLE_GAP_PHY_2M, @@ -43,7 +49,10 @@ esp_ble_gap_ext_adv_params_t legacy_adv_params = { .interval_max = 0x45, .channel_map = ADV_CHNL_ALL, .own_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr = {0,0,0,0,0,0}, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + .tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE, .primary_phy = ESP_BLE_GAP_PHY_1M, .max_skip = 0, .secondary_phy = ESP_BLE_GAP_PHY_1M, @@ -57,7 +66,10 @@ esp_ble_gap_ext_adv_params_t ext_adv_params_coded = { .interval_max = 0x50, .channel_map = ADV_CHNL_ALL, .own_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr = {0,0,0,0,0,0}, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + .tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE, .primary_phy = ESP_BLE_GAP_PHY_1M, .max_skip = 0, .secondary_phy = ESP_BLE_GAP_PHY_CODED, diff --git a/libraries/BLE/examples/BLE5_periodic_advertising/BLE5_periodic_advertising.ino b/libraries/BLE/examples/BLE5_periodic_advertising/BLE5_periodic_advertising.ino index 1b36bbb8b54..26f686cd1bd 100644 --- a/libraries/BLE/examples/BLE5_periodic_advertising/BLE5_periodic_advertising.ino +++ b/libraries/BLE/examples/BLE5_periodic_advertising/BLE5_periodic_advertising.ino @@ -15,7 +15,10 @@ esp_ble_gap_ext_adv_params_t ext_adv_params_2M = { .interval_max = 0x40, .channel_map = ADV_CHNL_ALL, .own_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr_type = BLE_ADDR_TYPE_RANDOM, + .peer_addr = {0,0,0,0,0,0}, .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + .tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE, .primary_phy = ESP_BLE_GAP_PHY_1M, .max_skip = 0, .secondary_phy = ESP_BLE_GAP_PHY_2M, diff --git a/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino b/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino index fdc25b394a2..98cb1e8a3bc 100644 --- a/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino +++ b/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino @@ -21,6 +21,7 @@ static esp_ble_gap_periodic_adv_sync_params_t periodic_adv_sync_params = { .filter_policy = 0, .sid = 0, .addr_type = BLE_ADDR_TYPE_RANDOM, + .addr = {0,0,0,0,0,0}, .skip = 10, .sync_timeout = 1000, // timeout: 1000 * 10ms }; diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index e430fe7255e..9ba94f17644 100644 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -673,7 +673,9 @@ static bool _init_bt(const char *deviceName) return false; } - if (esp_spp_init(ESP_SPP_MODE_CB) != ESP_OK){ + esp_spp_cfg_t cfg = BT_SPP_DEFAULT_CONFIG(); + cfg.mode = ESP_SPP_MODE_CB; + if (esp_spp_enhanced_init(&cfg) != ESP_OK){ log_e("spp init failed"); return false; } diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino b/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino index 702a557dde4..40154a0ecd8 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino +++ b/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino @@ -59,8 +59,8 @@ void setup() { config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; - config.pin_sscb_sda = SIOD_GPIO_NUM; - config.pin_sscb_scl = SIOC_GPIO_NUM; + config.pin_sccb_sda = SIOD_GPIO_NUM; + config.pin_sccb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index 113d222ace5..634d8d52a97 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp +++ b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp @@ -50,10 +50,12 @@ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED #pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wstrict-aliasing" #include "face_recognition_tool.hpp" #include "face_recognition_112_v1_s16.hpp" #include "face_recognition_112_v1_s8.hpp" #pragma GCC diagnostic error "-Wformat" +#pragma GCC diagnostic warning "-Wstrict-aliasing" #define QUANT_TYPE 0 //if set to 1 => very large firmware, very slow, reboots when streaming... diff --git a/libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino b/libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino index c9ba0eca6aa..67dde03b0e7 100644 --- a/libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino +++ b/libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino @@ -1,3 +1,6 @@ +#ifdef ARDUINO_RUNNING_CORE +#undef ARDUINO_RUNNING_CORE +#endif #if CONFIG_FREERTOS_UNICORE #define ARDUINO_RUNNING_CORE 0 #else diff --git a/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino b/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino index 753ac2b745f..a32eaf53b8b 100644 --- a/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino +++ b/libraries/ESP32/examples/GPIO/FunctionalInterrupt/FunctionalInterrupt.ino @@ -16,7 +16,7 @@ public: } void ARDUINO_ISR_ATTR isr() { - numberKeyPresses += 1; + numberKeyPresses = numberKeyPresses + 1; pressed = true; } diff --git a/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino b/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino index 94c61809a3e..9edfe32050c 100644 --- a/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino +++ b/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino @@ -51,7 +51,9 @@ void i2sInit(){ .dma_buf_len = I2S_DMA_BUF_LEN, .use_apll = false, .tx_desc_auto_clear = false, - .fixed_mclk = 0 + .fixed_mclk = 0, + .mclk_multiple = esp_i2s::I2S_MCLK_MULTIPLE_128, + .bits_per_chan = esp_i2s::I2S_BITS_PER_CHAN_DEFAULT }; Serial.printf("Attempting to setup I2S ADC with sampling frequency %d Hz\n", I2S_SAMPLE_RATE); if(ESP_OK != i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL)){ diff --git a/libraries/ESP32/examples/Serial/OnReceiveError_BREAK_Demo/OnReceiveError_BREAK_Demo.ino b/libraries/ESP32/examples/Serial/OnReceiveError_BREAK_Demo/OnReceiveError_BREAK_Demo.ino index 5bb53bf90b8..3a712033506 100644 --- a/libraries/ESP32/examples/Serial/OnReceiveError_BREAK_Demo/OnReceiveError_BREAK_Demo.ino +++ b/libraries/ESP32/examples/Serial/OnReceiveError_BREAK_Demo/OnReceiveError_BREAK_Demo.ino @@ -84,7 +84,7 @@ void onReceiveErrorFunction(hardwareSerial_error_t err) { void onReceiveFunction() { // This is a callback function that will be activated on UART RX events size_t available = Serial1.available(); - received_bytes += available; + received_bytes = received_bytes + available; Serial.printf("onReceive Callback:: There are %d bytes available: {", available); while (available --) { Serial.print((char)Serial1.read()); diff --git a/libraries/ESP32/examples/Serial/OnReceive_Demo/OnReceive_Demo.ino b/libraries/ESP32/examples/Serial/OnReceive_Demo/OnReceive_Demo.ino index 192dbd020da..fa16645a64d 100644 --- a/libraries/ESP32/examples/Serial/OnReceive_Demo/OnReceive_Demo.ino +++ b/libraries/ESP32/examples/Serial/OnReceive_Demo/OnReceive_Demo.ino @@ -60,7 +60,7 @@ volatile size_t sent_bytes = 0, received_bytes = 0; void onReceiveFunction(void) { // This is a callback function that will be activated on UART RX events size_t available = Serial1.available(); - received_bytes += available; + received_bytes = received_bytes + available; Serial.printf("onReceive Callback:: There are %d bytes available: ", available); while (available --) { Serial.print((char)Serial1.read()); diff --git a/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino b/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino index 0438d26daa8..ebf9f857e86 100644 --- a/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino +++ b/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino @@ -24,6 +24,7 @@ created 05-11-2022 by Stephan Martin (designer2k2) */ +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" #include "driver/twai.h" // Pins used to connect to CAN bus transceiver: diff --git a/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino b/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino index 0896e1f3e28..c6282429217 100644 --- a/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino +++ b/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino @@ -21,7 +21,7 @@ volatile uint32_t lastIsrAt = 0; void ARDUINO_ISR_ATTR onTimer(){ // Increment the counter and set the time of ISR portENTER_CRITICAL_ISR(&timerMux); - isrCounter++; + isrCounter = isrCounter + 1; lastIsrAt = millis(); portEXIT_CRITICAL_ISR(&timerMux); // Give a semaphore that we can check in the loop diff --git a/libraries/FFat/src/FFat.cpp b/libraries/FFat/src/FFat.cpp index f58bc444c17..e312e7f8f92 100644 --- a/libraries/FFat/src/FFat.cpp +++ b/libraries/FFat/src/FFat.cpp @@ -53,12 +53,13 @@ bool F_Fat::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFiles esp_vfs_fat_mount_config_t conf = { .format_if_mount_failed = formatOnFail, .max_files = maxOpenFiles, - .allocation_unit_size = CONFIG_WL_SECTOR_SIZE + .allocation_unit_size = CONFIG_WL_SECTOR_SIZE, + .disk_status_check_enable = false }; - esp_err_t err = esp_vfs_fat_spiflash_mount(basePath, partitionLabel, &conf, &_wl_handle); + esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(basePath, partitionLabel, &conf, &_wl_handle); if(err){ log_e("Mounting FFat partition failed! Error: %d", err); - esp_vfs_fat_spiflash_unmount(basePath, _wl_handle); + esp_vfs_fat_spiflash_unmount_rw_wl(basePath, _wl_handle); _wl_handle = WL_INVALID_HANDLE; return false; } @@ -69,7 +70,7 @@ bool F_Fat::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFiles void F_Fat::end() { if(_wl_handle != WL_INVALID_HANDLE){ - esp_err_t err = esp_vfs_fat_spiflash_unmount(_impl->mountpoint(), _wl_handle); + esp_err_t err = esp_vfs_fat_spiflash_unmount_rw_wl(_impl->mountpoint(), _wl_handle); if(err){ log_e("Unmounting FFat partition failed! Error: %d", err); return; @@ -109,13 +110,14 @@ bool F_Fat::format(bool full_wipe, char* partitionLabel) esp_vfs_fat_mount_config_t conf = { .format_if_mount_failed = true, .max_files = 1, - .allocation_unit_size = CONFIG_WL_SECTOR_SIZE + .allocation_unit_size = CONFIG_WL_SECTOR_SIZE, + .disk_status_check_enable = false }; - result = esp_vfs_fat_spiflash_mount("/format_ffat", partitionLabel, &conf, &temp_handle); - esp_vfs_fat_spiflash_unmount("/format_ffat", temp_handle); + result = esp_vfs_fat_spiflash_mount_rw_wl("/format_ffat", partitionLabel, &conf, &temp_handle); + esp_vfs_fat_spiflash_unmount_rw_wl("/format_ffat", temp_handle); if (result != ESP_OK){ res = false; - log_w("esp_vfs_fat_spiflash_mount failed!"); + log_w("esp_vfs_fat_spiflash_mount_rw_wl failed!"); } return res; } diff --git a/libraries/I2S/src/I2S.cpp b/libraries/I2S/src/I2S.cpp index 78dc5c202df..7414067eb87 100644 --- a/libraries/I2S/src/I2S.cpp +++ b/libraries/I2S/src/I2S.cpp @@ -144,7 +144,20 @@ int I2SClass::_installDriver(){ .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, .dma_buf_count = _I2S_DMA_BUFFER_COUNT, .dma_buf_len = _i2s_dma_buffer_size, - .use_apll = false + .use_apll = false, + #warning The following values are new and need to be checked + .tx_desc_auto_clear = true, + .fixed_mclk = 0, + .mclk_multiple = esp_i2s::I2S_MCLK_MULTIPLE_128, + .bits_per_chan = esp_i2s::I2S_BITS_PER_CHAN_DEFAULT +#if SOC_I2S_SUPPORTS_TDM + ,.chan_mask = esp_i2s::I2S_CHANNEL_STEREO, + .total_chan = 2, + .left_align = false, + .big_edin = false, + .bit_order_msb = false, + .skip_msk = false +#endif // SOC_I2S_SUPPORTS_TDM }; if(_driveClock == false){ @@ -317,6 +330,7 @@ int I2SClass::begin(int mode, int sampleRate, int bitsPerSample, bool driveClock int I2SClass::_applyPinSetting(){ if(_driverInstalled){ esp_i2s::i2s_pin_config_t pin_config = { + .mck_io_num = I2S_PIN_NO_CHANGE, .bck_io_num = _sckPin, .ws_io_num = _fsPin, .data_out_num = I2S_PIN_NO_CHANGE, diff --git a/libraries/RainMaker/src/RMaker.cpp b/libraries/RainMaker/src/RMaker.cpp index c7e3e921dd5..f8ced7970ff 100644 --- a/libraries/RainMaker/src/RMaker.cpp +++ b/libraries/RainMaker/src/RMaker.cpp @@ -139,6 +139,7 @@ esp_err_t RMakerClass::enableOTA(ota_type_t type, const char *cert) .ota_cb = NULL, .ota_diag = NULL, .server_cert = cert, + .priv = NULL }; err = esp_rmaker_ota_enable(&ota_config, type); if(err != ESP_OK) { diff --git a/libraries/SD_MMC/src/SD_MMC.cpp b/libraries/SD_MMC/src/SD_MMC.cpp index 7365e0df01f..fad63dea2d2 100644 --- a/libraries/SD_MMC/src/SD_MMC.cpp +++ b/libraries/SD_MMC/src/SD_MMC.cpp @@ -123,7 +123,8 @@ bool SDMMCFS::begin(const char * mountpoint, bool mode1bit, bool format_if_mount esp_vfs_fat_sdmmc_mount_config_t mount_config = { .format_if_mount_failed = format_if_mount_failed, .max_files = maxOpenFiles, - .allocation_unit_size = 0 + .allocation_unit_size = 0, + .disk_status_check_enable = false }; esp_err_t ret = esp_vfs_fat_sdmmc_mount(mountpoint, &host, &slot_config, &mount_config, &_card); diff --git a/libraries/WebServer/examples/SDWebServer/SDWebServer.ino b/libraries/WebServer/examples/SDWebServer/SDWebServer.ino index de01610ecec..b9da60c2d60 100644 --- a/libraries/WebServer/examples/SDWebServer/SDWebServer.ino +++ b/libraries/WebServer/examples/SDWebServer/SDWebServer.ino @@ -214,7 +214,6 @@ void printDirectory() { dir.rewindDirectory(); server.setContentLength(CONTENT_LENGTH_UNKNOWN); server.send(200, "text/json", ""); - WiFiClient client = server.client(); server.sendContent("["); for (int cnt = 0; true; ++cnt) { diff --git a/libraries/WebServer/src/WebServer.h b/libraries/WebServer/src/WebServer.h index fc60d16496f..57d8724cccf 100644 --- a/libraries/WebServer/src/WebServer.h +++ b/libraries/WebServer/src/WebServer.h @@ -95,7 +95,7 @@ class WebServer String uri() { return _currentUri; } HTTPMethod method() { return _currentMethod; } - virtual WiFiClient client() { return _currentClient; } + virtual WiFiClient & client() { return _currentClient; } HTTPUpload& upload() { return *_currentUpload; } String pathArg(unsigned int i); // get request path argument by number diff --git a/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino b/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino index 4e654d12c79..f5c4bc2910c 100644 --- a/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino +++ b/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino @@ -15,7 +15,9 @@ #include #include +#ifndef LED_BUILTIN #define LED_BUILTIN 2 // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED +#endif // Set these to your desired credentials. const char *ssid = "yourAP"; diff --git a/libraries/WiFi/src/WiFiUdp.cpp b/libraries/WiFi/src/WiFiUdp.cpp index 476b5a4a8b5..16b0ac2920d 100644 --- a/libraries/WiFi/src/WiFiUdp.cpp +++ b/libraries/WiFi/src/WiFiUdp.cpp @@ -80,7 +80,7 @@ uint8_t WiFiUDP::begin(uint16_t p){ uint8_t WiFiUDP::beginMulticast(IPAddress a, uint16_t p){ if(begin(IPAddress(INADDR_ANY), p)){ - if(a != 0){ + if((uint32_t)a != 0){ struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = (in_addr_t)a; mreq.imr_interface.s_addr = INADDR_ANY; @@ -109,7 +109,7 @@ void WiFiUDP::stop(){ } if(udp_server == -1) return; - if(multicast_ip != 0){ + if((uint32_t)multicast_ip != 0){ struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = (in_addr_t)multicast_ip; mreq.imr_interface.s_addr = (in_addr_t)0; From 4c6f87d6b05e1aa16001761767da50fa1338bc03 Mon Sep 17 00:00:00 2001 From: Pedro Minatel Date: Tue, 17 Jan 2023 14:28:39 +0000 Subject: [PATCH 09/60] Added the example guideline and template (#7665) * Added the example guideline and template * PR review changes with some typos and grammar fixes * Changes according to the PR review --- .../ExampleTemplate/ExampleTemplate.ino | 16 +++ .../Template/ExampleTemplate/README.md | 122 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 libraries/ESP32/examples/Template/ExampleTemplate/ExampleTemplate.ino create mode 100644 libraries/ESP32/examples/Template/ExampleTemplate/README.md diff --git a/libraries/ESP32/examples/Template/ExampleTemplate/ExampleTemplate.ino b/libraries/ESP32/examples/Template/ExampleTemplate/ExampleTemplate.ino new file mode 100644 index 00000000000..ff9733d1cd4 --- /dev/null +++ b/libraries/ESP32/examples/Template/ExampleTemplate/ExampleTemplate.ino @@ -0,0 +1,16 @@ +/* Arduino Example Template + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +void setup() { + +} + +void loop() { + +} diff --git a/libraries/ESP32/examples/Template/ExampleTemplate/README.md b/libraries/ESP32/examples/Template/ExampleTemplate/README.md new file mode 100644 index 00000000000..9819880d4f4 --- /dev/null +++ b/libraries/ESP32/examples/Template/ExampleTemplate/README.md @@ -0,0 +1,122 @@ +# Arduino-ESP32 Example/Library Name ==(REQUIRED)== + +==*Add a brief description of this example/library here!*== + +This example/library demonstrates how to create a new example README file. + +# Supported Targets ==(REQUIRED)== + +==*Add the supported devices here!*== + +Currently, this example supports the following targets. + +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | + +## How to Use Example/Library ==(OPTIONAL)== + +==*Add a brief description of how to use this example.*== + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +### Hardware Connection ==(OPTIONAL)== + +==*Add a brief description of wiring or any other hardware-specific connection.*== + +To use this example, you need to connect the LED to the `GPIOx`. + +SDCard GPIO connection scheme: + +| SDCard Pin | Function | GPIO | +| ----------- | -------- | ------ | +| 1 | CS | GPIO5 | +| 2 | DI/MOSI | GPIO23 | +| 3 | VSS/GND | GND | +| 4 | VDD/3V3 | 3V3 | +| 5 | SCLK | GPIO18 | +| 6 | VSS/GND | GND | +| 7 | DO/MISO | GPIO19 | + +To add images, please create a folder `_asset` inside the example folder to add the relevant images. + +### Configure the Project ==(OPTIONAL)== + +==*Add a brief description of this example here!*== + +Set the LED GPIO by changing the `LED_BUILTIN` value in the function `pinMode(LED_BUILTIN, OUTPUT);`. By default, the GPIO is: `GPIOx`. + +#### Example for the GPIO4: + +==*Add some code explanation if relevant to the example.*== + +```cpp +// the setup function runs once when you press reset or power the board +void setup() { +// initialize digital pin 4 as an output. +pinMode(4, OUTPUT); +} +``` + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. + +## Example/Log Output ==(OPTIONAL)== + +==*Add the log/serial output here!*== + +``` +ets Jul 29 2019 12:21:46 + +rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) +configsip: 0, SPIWP:0xee +clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 +mode:DIO, clock div:1 +load:0x3fff0030,len:1412 +load:0x40078000,len:13400 +load:0x40080400,len:3672 +entry 0x400805f8 +ESP32 Chip model = ESP32-D0WDQ5 Rev 3 +This chip has 2 cores +Chip ID: 3957392 +``` + +## Troubleshooting ==(REQUIRED)== + +==*Add specific issues you may find by using this example here!*== + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute ==(REQUIRED)== + +==*Do not change! Keep it as is.*== + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources ==(REQUIRED)== + +==*Do not change here! Keep it as is or add only relevant documents/info for this example. Do not add any purchase link/marketing stuff*== + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) From 00b89b7d27088a77cc58dd34ad13ffa88bd9686a Mon Sep 17 00:00:00 2001 From: Pedro Minatel Date: Fri, 20 Jan 2023 15:18:51 +0000 Subject: [PATCH 10/60] Added ESP32-S3 link to the datasheet (#7738) --- libraries/ESP32/examples/Template/ExampleTemplate/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/ESP32/examples/Template/ExampleTemplate/README.md b/libraries/ESP32/examples/Template/ExampleTemplate/README.md index 9819880d4f4..f5aa7b35e86 100644 --- a/libraries/ESP32/examples/Template/ExampleTemplate/README.md +++ b/libraries/ESP32/examples/Template/ExampleTemplate/README.md @@ -119,4 +119,5 @@ Before creating a new issue, be sure to try Troubleshooting and check if the sam * ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) * ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) * ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) * Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) From 3454aba2ef066d7190bad78a21daba572c47eaee Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 20 Jan 2023 18:24:12 +0200 Subject: [PATCH 11/60] Update HiFreq_ADC.ino --- libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino b/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino index 9edfe32050c..db94960f205 100644 --- a/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino +++ b/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino @@ -52,8 +52,8 @@ void i2sInit(){ .use_apll = false, .tx_desc_auto_clear = false, .fixed_mclk = 0, - .mclk_multiple = esp_i2s::I2S_MCLK_MULTIPLE_128, - .bits_per_chan = esp_i2s::I2S_BITS_PER_CHAN_DEFAULT + .mclk_multiple = I2S_MCLK_MULTIPLE_128, + .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT }; Serial.printf("Attempting to setup I2S ADC with sampling frequency %d Hz\n", I2S_SAMPLE_RATE); if(ESP_OK != i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL)){ From a619d315e55a066e881cad283c177afe07f8f0a4 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 21 Jan 2023 00:19:47 +0200 Subject: [PATCH 12/60] Replace periph_ctrl.h use because of deprecation --- cores/esp32/esp32-hal-i2c-slave.c | 6 +++--- cores/esp32/esp32-hal-spi.c | 14 +++++++------- cores/esp32/esp32-hal-tinyusb.c | 16 ++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cores/esp32/esp32-hal-i2c-slave.c b/cores/esp32/esp32-hal-i2c-slave.c index 5205df0410d..9b54cce9b1d 100644 --- a/cores/esp32/esp32-hal-i2c-slave.c +++ b/cores/esp32/esp32-hal-i2c-slave.c @@ -36,10 +36,10 @@ #include "freertos/ringbuf.h" #include "esp_intr_alloc.h" -#include "driver/periph_ctrl.h" #include "soc/i2c_reg.h" #include "soc/i2c_struct.h" #include "hal/i2c_ll.h" +#include "hal/clk_gate_ll.h" #include "esp32-hal-log.h" #include "esp32-hal-i2c-slave.h" @@ -292,10 +292,10 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t frequency = (frequency * 5) / 4; if (i2c->num == 0) { - periph_module_enable(PERIPH_I2C0_MODULE); + periph_ll_enable_clk_clear_rst(PERIPH_I2C0_MODULE); #if SOC_I2C_NUM > 1 } else { - periph_module_enable(PERIPH_I2C1_MODULE); + periph_ll_enable_clk_clear_rst(PERIPH_I2C1_MODULE); #endif } diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index 4e7643ec4ee..7eb475c5e73 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -23,7 +23,7 @@ #include "soc/io_mux_reg.h" #include "soc/gpio_sig_map.h" #include "soc/rtc.h" -#include "driver/periph_ctrl.h" +#include "hal/clk_gate_ll.h" #include "esp_system.h" #ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ @@ -729,11 +729,11 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ } #elif CONFIG_IDF_TARGET_ESP32S3 if(spi_num == FSPI) { - periph_module_reset( PERIPH_SPI2_MODULE ); - periph_module_enable( PERIPH_SPI2_MODULE ); + periph_ll_reset( PERIPH_SPI2_MODULE ); + periph_ll_enable_clk_clear_rst( PERIPH_SPI2_MODULE ); } else if(spi_num == HSPI) { - periph_module_reset( PERIPH_SPI3_MODULE ); - periph_module_enable( PERIPH_SPI3_MODULE ); + periph_ll_reset( PERIPH_SPI3_MODULE ); + periph_ll_enable_clk_clear_rst( PERIPH_SPI3_MODULE ); } #elif CONFIG_IDF_TARGET_ESP32 if(spi_num == HSPI) { @@ -747,8 +747,8 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST); } #elif CONFIG_IDF_TARGET_ESP32C3 - periph_module_reset( PERIPH_SPI2_MODULE ); - periph_module_enable( PERIPH_SPI2_MODULE ); + periph_ll_reset( PERIPH_SPI2_MODULE ); + periph_ll_enable_clk_clear_rst( PERIPH_SPI2_MODULE ); #endif SPI_MUTEX_LOCK(); diff --git a/cores/esp32/esp32-hal-tinyusb.c b/cores/esp32/esp32-hal-tinyusb.c index 449b86755df..ebd65edce82 100644 --- a/cores/esp32/esp32-hal-tinyusb.c +++ b/cores/esp32/esp32-hal-tinyusb.c @@ -22,12 +22,12 @@ #include "hal/usb_hal.h" #include "hal/gpio_ll.h" +#include "hal/clk_gate_ll.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" -#include "driver/periph_ctrl.h" #include "esp_rom_gpio.h" @@ -395,9 +395,9 @@ static void hw_cdc_reset_handler(void *arg) { static void usb_switch_to_cdc_jtag(){ // Disable USB-OTG - periph_module_reset(PERIPH_USB_MODULE); - //periph_module_enable(PERIPH_USB_MODULE); - periph_module_disable(PERIPH_USB_MODULE); + periph_ll_reset(PERIPH_USB_MODULE); + //periph_ll_enable_clk_clear_rst(PERIPH_USB_MODULE); + periph_ll_disable_clk_set_rst(PERIPH_USB_MODULE); // Switch to hardware CDC+JTAG CLEAR_PERI_REG_MASK(RTC_CNTL_USB_CONF_REG, (RTC_CNTL_SW_HW_USB_PHY_SEL|RTC_CNTL_SW_USB_PHY_SEL|RTC_CNTL_USB_PAD_ENABLE)); @@ -457,8 +457,8 @@ static void IRAM_ATTR usb_persist_shutdown_handler(void) chip_usb_set_persist_flags(USBDC_PERSIST_ENA); #if CONFIG_IDF_TARGET_ESP32S2 } else { - periph_module_reset(PERIPH_USB_MODULE); - periph_module_enable(PERIPH_USB_MODULE); + periph_ll_reset(PERIPH_USB_MODULE); + periph_ll_enable_clk_clear_rst(PERIPH_USB_MODULE); #endif } REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); @@ -696,8 +696,8 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) { //} else if(!usb_did_persist || !usb_persist_enabled){ // Reset USB module - periph_module_reset(PERIPH_USB_MODULE); - periph_module_enable(PERIPH_USB_MODULE); + periph_ll_reset(PERIPH_USB_MODULE); + periph_ll_enable_clk_clear_rst(PERIPH_USB_MODULE); } tinyusb_config_t tusb_cfg = { From 06ec7f11b52a952b91db1a9c25868318eebb0053 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 21 Jan 2023 00:32:21 +0200 Subject: [PATCH 13/60] Replace esp_spi_flash.h use because of deprecation --- libraries/Update/src/Updater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Update/src/Updater.cpp b/libraries/Update/src/Updater.cpp index 30d88cb8ff1..67a37cda879 100644 --- a/libraries/Update/src/Updater.cpp +++ b/libraries/Update/src/Updater.cpp @@ -1,6 +1,6 @@ #include "Update.h" #include "Arduino.h" -#include "esp_spi_flash.h" +#include "spi_flash_mmap.h" #include "esp_ota_ops.h" #include "esp_image_format.h" From 6cc8f11b4050275d1156c9aeebb61b9a9a7bca4b Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 21 Jan 2023 00:33:38 +0200 Subject: [PATCH 14/60] Add includes to male mDNS::enableWorkstation compile --- libraries/ESPmDNS/src/ESPmDNS.cpp | 25 +++++++++++++------------ libraries/ESPmDNS/src/ESPmDNS.h | 4 ++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/libraries/ESPmDNS/src/ESPmDNS.cpp b/libraries/ESPmDNS/src/ESPmDNS.cpp index 36a4043b084..cb8ebf4fce3 100644 --- a/libraries/ESPmDNS/src/ESPmDNS.cpp +++ b/libraries/ESPmDNS/src/ESPmDNS.cpp @@ -42,6 +42,7 @@ License (MIT license): #include "WiFi.h" #include #include "esp_wifi.h" +#include "esp_wifi_types.h" // Add quotes around defined value #ifdef __IN_ECLIPSE__ @@ -111,18 +112,18 @@ void MDNSResponder::disableArduino(){ } } -// void MDNSResponder::enableWorkstation(esp_interface_t interface){ -// char winstance[21+_hostname.length()]; -// uint8_t mac[6]; -// esp_wifi_get_mac((wifi_interface_t)interface, mac); -// sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", _hostname.c_str(), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - -// if(mdns_service_add(NULL, "_workstation", "_tcp", 9, NULL, 0)) { -// log_e("Failed adding Workstation service"); -// } else if(mdns_service_instance_name_set("_workstation", "_tcp", winstance)) { -// log_e("Failed setting Workstation service instance name"); -// } -// } +void MDNSResponder::enableWorkstation(esp_interface_t interface){ + char winstance[21+_hostname.length()]; + uint8_t mac[6]; + esp_wifi_get_mac((wifi_interface_t)interface, mac); + sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", _hostname.c_str(), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + if(mdns_service_add(NULL, "_workstation", "_tcp", 9, NULL, 0)) { + log_e("Failed adding Workstation service"); + } else if(mdns_service_instance_name_set("_workstation", "_tcp", winstance)) { + log_e("Failed setting Workstation service instance name"); + } +} void MDNSResponder::disableWorkstation(){ if(mdns_service_remove("_workstation", "_tcp")) { diff --git a/libraries/ESPmDNS/src/ESPmDNS.h b/libraries/ESPmDNS/src/ESPmDNS.h index 240fda0b1ed..4a2950351bb 100644 --- a/libraries/ESPmDNS/src/ESPmDNS.h +++ b/libraries/ESPmDNS/src/ESPmDNS.h @@ -44,6 +44,7 @@ License (MIT license): #include "Arduino.h" #include "IPv6Address.h" #include "mdns.h" +#include "esp_interface.h" //this should be defined at build time #ifndef ARDUINO_VARIANT @@ -84,8 +85,7 @@ class MDNSResponder { void enableArduino(uint16_t port=3232, bool auth=false); void disableArduino(); - #warning This needs fixing for IDF 5.1 - //void enableWorkstation(esp_interface_t interface=ESP_IF_WIFI_STA); + void enableWorkstation(esp_interface_t interface=ESP_IF_WIFI_STA); void disableWorkstation(); IPAddress queryHost(char *host, uint32_t timeout=2000); From 2736575d16e376184f7e102750483085d10ecc54 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 21 Jan 2023 01:12:21 +0200 Subject: [PATCH 15/60] Fix ssl_client mbedtls_pk_parse_key callback --- libraries/WiFiClientSecure/src/ssl_client.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/libraries/WiFiClientSecure/src/ssl_client.cpp b/libraries/WiFiClientSecure/src/ssl_client.cpp index 571cccbeb92..c8328eb6280 100644 --- a/libraries/WiFiClientSecure/src/ssl_client.cpp +++ b/libraries/WiFiClientSecure/src/ssl_client.cpp @@ -53,15 +53,6 @@ void ssl_init(sslclient_context *ssl_client) mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx); } -#warning This needs to be properly filled -static int ssl_rng(void *ctx, unsigned char *data, size_t len) -{ - // while (len-- != 0) { - // *data++ = random(); - // } - return 0; -} - int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, bool useRootCABundle, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure, const char **alpn_protos) { char buf[512]; @@ -254,7 +245,10 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p } log_v("Loading private key"); - ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0, ssl_rng, NULL); + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ctr_drbg_init( &ctr_drbg ); + ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0, mbedtls_ctr_drbg_random, &ctr_drbg); + mbedtls_ctr_drbg_free( &ctr_drbg ); if (ret != 0) { mbedtls_x509_crt_free(&ssl_client->client_cert); // cert+key are free'd in pair From a4a293843523abf7c49303904afe04aa3a8c7279 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 21 Jan 2023 01:46:10 +0200 Subject: [PATCH 16/60] Update temperature sensor driver --- cores/esp32/esp32-hal-misc.c | 40 ++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/cores/esp32/esp32-hal-misc.c b/cores/esp32/esp32-hal-misc.c index 1a71b0e86f9..71530f7631b 100644 --- a/cores/esp32/esp32-hal-misc.c +++ b/cores/esp32/esp32-hal-misc.c @@ -40,13 +40,13 @@ #include "esp32/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/rtc.h" -#include "driver/temp_sensor.h" +#include "driver/temperature_sensor.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/rtc.h" -#include "driver/temp_sensor.h" +#include "driver/temperature_sensor.h" #elif CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/rom/rtc.h" -#include "driver/temp_sensor.h" +#include "driver/temperature_sensor.h" #else #error Target CONFIG_IDF_TARGET is not supported #endif @@ -64,14 +64,38 @@ float temperatureRead() return (temprature_sens_read() - 32) / 1.8; } #else +static temperature_sensor_handle_t temp_sensor = NULL; + +static bool temperatureReadInit() +{ + static volatile bool initialized = false; + if(!initialized){ + initialized = true; + //Install temperature sensor, expected temp ranger range: 10~50 ℃ + temperature_sensor_config_t temp_sensor_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50); + if(temperature_sensor_install(&temp_sensor_config, &temp_sensor) != ESP_OK){ + initialized = false; + temp_sensor = NULL; + log_e("temperature_sensor_install failed"); + } + else if(temperature_sensor_enable(temp_sensor) != ESP_OK){ + temperature_sensor_uninstall(temp_sensor); + initialized = false; + temp_sensor = NULL; + log_e("temperature_sensor_enable failed"); + } + } + return initialized; +} + float temperatureRead() { float result = NAN; - temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT(); - temp_sensor_set_config(tsens); - temp_sensor_start(); - temp_sensor_read_celsius(&result); - temp_sensor_stop(); + if(temperatureReadInit()){ + if(temperature_sensor_get_celsius(temp_sensor, &result) != ESP_OK){ + log_e("temperature_sensor_get_celsius failed"); + } + } return result; } #endif From b164d6611212f6ed6276335e522dee14e7812bf0 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 21 Jan 2023 03:11:19 +0200 Subject: [PATCH 17/60] Allow sketch_utils to compile with arduino-cli --- .github/scripts/sketch_utils.sh | 58 ++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/.github/scripts/sketch_utils.sh b/.github/scripts/sketch_utils.sh index 3a856202e51..a130bf2077f 100755 --- a/.github/scripts/sketch_utils.sh +++ b/.github/scripts/sketch_utils.sh @@ -121,33 +121,61 @@ function build_sketch(){ # build_sketch [ex if [ -n "$ARDUINO_BUILD_DIR" ]; then build_dir="$ARDUINO_BUILD_DIR" elif [ $len -eq 1 ]; then - build_dir="$sketchdir/build" + # build_dir="$sketchdir/build" + build_dir="$HOME/.arduino/build.tmp" fi mkdir -p "$ARDUINO_CACHE_DIR" for i in `seq 0 $(($len - 1))` do if [ $len -ne 1 ]; then - build_dir="$sketchdir/build$i" + # build_dir="$sketchdir/build$i" + build_dir="$HOME/.arduino/build$i.tmp" fi rm -rf $build_dir mkdir -p $build_dir currfqbn=`echo $fqbn | jq -r --argjson i $i '.[$i]'` sketchname=$(basename $sketchdir) - echo "Building $sketchname with FQBN=$currfqbn" - $ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \ - -fqbn=\"$currfqbn\" \ - -warnings="all" \ - -tools "$ide_path/tools-builder" \ - -tools "$ide_path/tools" \ - -built-in-libraries "$ide_path/libraries" \ - -hardware "$ide_path/hardware" \ - -hardware "$user_path/hardware" \ - -libraries "$user_path/libraries" \ - -build-cache "$ARDUINO_CACHE_DIR" \ - -build-path "$build_dir" \ - $xtra_opts "${sketchdir}/${sketchname}.ino" + + if [ -f "$ide_path/arduino-cli" ]; then + echo "Building $sketchname with arduino-cli and FQBN=$currfqbn" + + curroptions=`echo "$currfqbn" | cut -d':' -f4` + currfqbn=`echo "$currfqbn" | cut -d':' -f1-3` + $ide_path/arduino-cli compile \ + --fqbn "$currfqbn" \ + --board-options "$curroptions" \ + --warnings "all" \ + --build-cache-path "$ARDUINO_CACHE_DIR" \ + --build-path "$build_dir" \ + $xtra_opts "${sketchdir}" + elif [ -f "$ide_path/arduino-builder" ]; then + echo "Building $sketchname with arduino-builder and FQBN=$currfqbn" + + $ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \ + -fqbn=\"$currfqbn\" \ + -warnings="all" \ + -tools "$ide_path/tools-builder" \ + -hardware "$user_path/hardware" \ + -libraries "$user_path/libraries" \ + -build-cache "$ARDUINO_CACHE_DIR" \ + -build-path "$build_dir" \ + $xtra_opts "${sketchdir}/${sketchname}.ino" + + # $ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \ + # -fqbn=\"$currfqbn\" \ + # -warnings="all" \ + # -tools "$ide_path/tools-builder" \ + # -tools "$ide_path/tools" \ + # -built-in-libraries "$ide_path/libraries" \ + # -hardware "$ide_path/hardware" \ + # -hardware "$user_path/hardware" \ + # -libraries "$user_path/libraries" \ + # -build-cache "$ARDUINO_CACHE_DIR" \ + # -build-path "$build_dir" \ + # $xtra_opts "${sketchdir}/${sketchname}.ino" + fi done } From 262636e4d6ea00778b5ed97dda03bdcde5123fc9 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 23 Jan 2023 12:03:41 +0200 Subject: [PATCH 18/60] Run CI with arduino-cli --- .github/scripts/install-arduino-cli.sh | 46 ++++++++++++++++++++++++++ .github/scripts/on-push.sh | 6 ++-- .github/scripts/sketch_utils.sh | 6 ++-- 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100755 .github/scripts/install-arduino-cli.sh diff --git a/.github/scripts/install-arduino-cli.sh b/.github/scripts/install-arduino-cli.sh new file mode 100755 index 00000000000..ba7547ccc28 --- /dev/null +++ b/.github/scripts/install-arduino-cli.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +OSBITS=`arch` +if [[ "$OSTYPE" == "linux"* ]]; then + export OS_IS_LINUX="1" + if [[ "$OSBITS" == "i686" ]]; then + OS_NAME="linux32" + elif [[ "$OSBITS" == "x86_64" ]]; then + OS_NAME="linux64" + elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then + OS_NAME="linuxarm" + else + OS_NAME="$OSTYPE-$OSBITS" + echo "Unknown OS '$OS_NAME'" + exit 1 + fi +elif [[ "$OSTYPE" == "darwin"* ]]; then + export OS_IS_MACOS="1" + OS_NAME="macosx" +elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then + export OS_IS_WINDOWS="1" + OS_NAME="windows" +else + OS_NAME="$OSTYPE-$OSBITS" + echo "Unknown OS '$OS_NAME'" + exit 1 +fi +export OS_NAME + +if [ "$OS_IS_MACOS" == "1" ]; then + export ARDUINO_IDE_PATH="$HOME/bin" + export ARDUINO_USR_PATH="$HOME/Documents/Arduino" +elif [ "$OS_IS_WINDOWS" == "1" ]; then + export ARDUINO_IDE_PATH="$HOME/bin" + export ARDUINO_USR_PATH="$HOME/Documents/Arduino" +else + export ARDUINO_IDE_PATH="$HOME/bin" + export ARDUINO_USR_PATH="$HOME/Arduino" +fi + +if [ ! -d "$ARDUINO_IDE_PATH" ] || [ ! -f "$ARDUINO_IDE_PATH/arduino-cli" ]; then + echo "Installing Arduino CLI on $OS_NAME ..." + mkdir -p "$ARDUINO_IDE_PATH" + curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR="$ARDUINO_IDE_PATH" sh +fi + diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 71a92a1021a..f88059efc85 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -9,7 +9,8 @@ function build(){ local fqbn=$2 local chunk_index=$3 local chunks_cnt=$4 - local sketches=$5 + shift; shift; shift; shift; + local sketches=$* local BUILD_SKETCH="${SCRIPTS_DIR}/sketch_utils.sh build" local BUILD_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh chunk_build" @@ -59,7 +60,8 @@ fi SCRIPTS_DIR="./.github/scripts" if [ "$BUILD_PIO" -eq 0 ]; then - source ${SCRIPTS_DIR}/install-arduino-ide.sh + #source ${SCRIPTS_DIR}/install-arduino-ide.sh + source ${SCRIPTS_DIR}/install-arduino-cli.sh source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh FQBN_ESP32="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app" diff --git a/.github/scripts/sketch_utils.sh b/.github/scripts/sketch_utils.sh index a130bf2077f..4a8d500bcbc 100755 --- a/.github/scripts/sketch_utils.sh +++ b/.github/scripts/sketch_utils.sh @@ -177,6 +177,9 @@ function build_sketch(){ # build_sketch [ex # $xtra_opts "${sketchdir}/${sketchname}.ino" fi done + unset fqbn + unset xtra_opts + unset options } function count_sketches(){ # count_sketches [target] @@ -322,8 +325,7 @@ function build_sketches(){ # build_sketches Date: Mon, 23 Jan 2023 12:28:09 +0200 Subject: [PATCH 19/60] Fix arduino-cli CI build on Windows --- .github/scripts/on-push.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index f88059efc85..0ca5a648fd0 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -25,15 +25,15 @@ function build(){ ${BUILD_SKETCHES} ${args} else for sketch in ${sketches}; do - args+=" -s $(dirname $sketch)" - if [ "$OS_IS_WINDOWS" == "1" ]; then + local sargs="$args -s $(dirname $sketch)" + if [ "$OS_IS_WINDOWS" == "1" ] && [ -d "$ARDUINO_IDE_PATH/tools-builder" ]; then local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"` local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"` win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version" - args+=" ${win_opts}" + sargs+=" ${win_opts}" fi - ${BUILD_SKETCH} ${args} + ${BUILD_SKETCH} ${sargs} done fi } From bb5a8403b6ff73f1c2584abf5d14366f0a02f4e8 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 27 Jan 2023 12:41:11 +0200 Subject: [PATCH 20/60] Refactor platform.txt to not use components installed through the board manager when running from git --- .github/scripts/on-release.sh | 8 ++++---- platform.txt | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/scripts/on-release.sh b/.github/scripts/on-release.sh index fb595b4df2c..947146ec492 100755 --- a/.github/scripts/on-release.sh +++ b/.github/scripts/on-release.sh @@ -197,10 +197,10 @@ find "$PKG_DIR" -name '*.git*' -type f -delete echo "Generating platform.txt..." cat "$GITHUB_WORKSPACE/platform.txt" | \ sed "s/version=.*/version=$ver$extent/g" | \ -sed 's/runtime.tools.xtensa-esp32-elf-gcc.path={runtime.platform.path}\/tools\/xtensa-esp32-elf//g' | \ -sed 's/runtime.tools.xtensa-esp32s2-elf-gcc.path={runtime.platform.path}\/tools\/xtensa-esp32s2-elf//g' | \ -sed 's/runtime.tools.xtensa-esp32s3-elf-gcc.path={runtime.platform.path}\/tools\/xtensa-esp32s3-elf//g' | \ -sed 's/runtime.tools.riscv32-esp-elf-gcc.path={runtime.platform.path}\/tools\/riscv32-esp-elf//g' | \ +sed 's/tools.xtensa-esp32-elf-gcc.path={runtime.platform.path}\/tools\/xtensa-esp32-elf/tools.xtensa-esp32-elf-gcc.path=\{runtime.tools.xtensa-esp32-elf-gcc.path\}/g' | \ +sed 's/tools.xtensa-esp32s2-elf-gcc.path={runtime.platform.path}\/tools\/xtensa-esp32s2-elf/tools.xtensa-esp32s2-elf-gcc.path=\{runtime.tools.xtensa-esp32s2-elf-gcc.path\}/g' | \ +sed 's/tools.xtensa-esp32s3-elf-gcc.path={runtime.platform.path}\/tools\/xtensa-esp32s3-elf/tools.xtensa-esp32s3-elf-gcc.path=\{runtime.tools.xtensa-esp32s3-elf-gcc.path\}/g' | \ +sed 's/tools.riscv32-esp-elf-gcc.path={runtime.platform.path}\/tools\/riscv32-esp-elf/tools.riscv32-esp-elf-gcc.path=\{runtime.tools.riscv32-esp-elf-gcc.path\}/g' | \ sed 's/tools.esptool_py.path={runtime.platform.path}\/tools\/esptool/tools.esptool_py.path=\{runtime.tools.esptool_py.path\}/g' | \ sed 's/debug.server.openocd.path={runtime.platform.path}\/tools\/openocd-esp32\/bin\/openocd/debug.server.openocd.path=\{runtime.tools.openocd-esp32.path\}\/bin\/openocd/g' | \ sed 's/debug.server.openocd.scripts_dir={runtime.platform.path}\/tools\/openocd-esp32\/share\/openocd\/scripts\//debug.server.openocd.scripts_dir=\{runtime.tools.openocd-esp32.path\}\/share\/openocd\/scripts\//g' | \ diff --git a/platform.txt b/platform.txt index 7fc48d07115..b6152789e24 100644 --- a/platform.txt +++ b/platform.txt @@ -1,10 +1,10 @@ name=ESP32 Arduino version=2.0.6 -runtime.tools.xtensa-esp32-elf-gcc.path={runtime.platform.path}/tools/xtensa-esp32-elf -runtime.tools.xtensa-esp32s2-elf-gcc.path={runtime.platform.path}/tools/xtensa-esp32s2-elf -runtime.tools.xtensa-esp32s3-elf-gcc.path={runtime.platform.path}/tools/xtensa-esp32s3-elf -runtime.tools.riscv32-esp-elf-gcc.path={runtime.platform.path}/tools/riscv32-esp-elf +tools.xtensa-esp32-elf-gcc.path={runtime.platform.path}/tools/xtensa-esp32-elf +tools.xtensa-esp32s2-elf-gcc.path={runtime.platform.path}/tools/xtensa-esp32s2-elf +tools.xtensa-esp32s3-elf-gcc.path={runtime.platform.path}/tools/xtensa-esp32s3-elf +tools.riscv32-esp-elf-gcc.path={runtime.platform.path}/tools/riscv32-esp-elf debug.server.openocd.path={runtime.platform.path}/tools/openocd-esp32/bin/openocd debug.server.openocd.scripts_dir={runtime.platform.path}/tools/openocd-esp32/share/openocd/scripts/ @@ -27,7 +27,7 @@ tools.gen_esp32part.cmd.windows="{runtime.platform.path}/tools/gen_esp32part.exe tools.gen_insights_pkg.cmd=python3 "{runtime.platform.path}"/tools/gen_insights_package.py tools.gen_insights_pkg.cmd.windows="{runtime.platform.path}/tools/gen_insights_package.exe" -compiler.path={runtime.tools.{build.tarch}-{build.target}-elf-gcc.path}/bin/ +compiler.path={tools.{build.tarch}-{build.target}-elf-gcc.path}/bin/ compiler.sdk.path={runtime.platform.path}/tools/sdk/{build.mcu} compiler.prefix={build.tarch}-{build.target}-elf- From 3c68eb70c2c4ba6509d63f4af8087a808ff0c398 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 30 Jan 2023 21:30:16 +0200 Subject: [PATCH 21/60] Initial Peripheral Manager Implementation --- CMakeLists.txt | 1 + cores/esp32/esp32-hal-periman.c | 91 +++++++++++++++++++++++++++++++++ cores/esp32/esp32-hal-periman.h | 53 +++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 cores/esp32/esp32-hal-periman.c create mode 100644 cores/esp32/esp32-hal-periman.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a5c45c9d7d..0fae8853b7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ set(CORE_SRCS cores/esp32/esp32-hal-ledc.c cores/esp32/esp32-hal-matrix.c cores/esp32/esp32-hal-misc.c + cores/esp32/esp32-hal-periman.c cores/esp32/esp32-hal-psram.c cores/esp32/esp32-hal-rgb-led.c cores/esp32/esp32-hal-sigmadelta.c diff --git a/cores/esp32/esp32-hal-periman.c b/cores/esp32/esp32-hal-periman.c new file mode 100644 index 00000000000..c0169b95437 --- /dev/null +++ b/cores/esp32/esp32-hal-periman.c @@ -0,0 +1,91 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp32-hal-log.h" +#include "esp32-hal-periman.h" +#include "soc/soc_caps.h" + +typedef struct { + peripheral_bus_type_t type; + void * bus; +} peripheral_pin_item_t; + +static peripheral_bus_deinit_cb_t deinit_functions[ESP32_BUS_TYPE_MAX]; +static peripheral_pin_item_t pins[SOC_GPIO_PIN_COUNT]; + +bool perimanSetPinBus(uint8_t pin, peripheral_bus_type_t type, void * bus){ + peripheral_bus_type_t otype = ESP32_BUS_TYPE_INIT; + void * obus = NULL; + if(pin >= SOC_GPIO_PIN_COUNT){ + log_e("Invalid pin: %u", pin); + return false; + } + if(type >= ESP32_BUS_TYPE_MAX){ + log_e("Invalid type: %u", (unsigned int)type); + return false; + } + if(type > ESP32_BUS_TYPE_GPIO && bus == NULL){ + log_e("Bus is NULL"); + return false; + } + otype = pins[pin].type; + obus = pins[pin].bus; + if(type == otype && bus == obus){ + log_i("Bus already set"); + return true; + } + if(obus != NULL){ + if(deinit_functions[otype] == NULL){ + log_e("Bus does not have deinit function set"); + return false; + } + if(!deinit_functions[otype](obus)){ + log_e("Previous bus failed to deinit"); + return false; + } + } + pins[pin].type = type; + pins[pin].bus = bus; + return true; +} + +void * perimanGetPinBus(uint8_t pin, peripheral_bus_type_t type){ + if(pin >= SOC_GPIO_PIN_COUNT){ + log_e("Invalid pin: %u", pin); + return NULL; + } + if(type >= ESP32_BUS_TYPE_MAX){ + log_e("Invalid type: %u", (unsigned int)type); + return NULL; + } + if(pins[pin].type == type){ + return pins[pin].bus; + } + return NULL; +} + +peripheral_bus_type_t perimanGetPinBusType(uint8_t pin){ + if(pin >= SOC_GPIO_PIN_COUNT){ + log_e("Invalid pin: %u", pin); + return ESP32_BUS_TYPE_MAX; + } + return pins[pin].type; +} + +bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t cb){ + if(type >= ESP32_BUS_TYPE_MAX){ + log_e("Invalid type: %u", (unsigned int)type); + return false; + } + if(cb == NULL){ + log_e("Callback is NULL"); + return false; + } + deinit_functions[type] = cb; + return true; +} + + diff --git a/cores/esp32/esp32-hal-periman.h b/cores/esp32/esp32-hal-periman.h new file mode 100644 index 00000000000..3a03499e407 --- /dev/null +++ b/cores/esp32/esp32-hal-periman.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +typedef enum { + ESP32_BUS_TYPE_INIT, // IO has not been attached to a bus yet + ESP32_BUS_TYPE_GPIO, // IO is used as GPIO + ESP32_BUS_TYPE_SIGMADELTA, // IO is used as SigmeDelta output + ESP32_BUS_TYPE_ADC_ONESHOT, // IO is used as ADC OneShot input + ESP32_BUS_TYPE_ADC_CONT, // IO is used as ADC continuous input + ESP32_BUS_TYPE_DAC_ONESHOT, // IO is used as DAC OneShot output + ESP32_BUS_TYPE_DAC_CONT, // IO is used as DAC continuous output + ESP32_BUS_TYPE_DAC_COSINE, // IO is used as DAC cosine output + ESP32_BUS_TYPE_RMT_TX, // IO is used as RMT output + ESP32_BUS_TYPE_RMT_RX, // IO is used as RMT input + ESP32_BUS_TYPE_I2S_STD, // IO is used as I2S STD pin + ESP32_BUS_TYPE_I2S_PDM, // IO is used as I2S PDM pin + ESP32_BUS_TYPE_I2S_TDM, // IO is used as I2S TDM pin + ESP32_BUS_TYPE_UART, // IO is used as UART pin + ESP32_BUS_TYPE_I2C_MASTER, // IO is used as I2C master pin + ESP32_BUS_TYPE_I2C_SLAVE, // IO is used as I2C slave pin + ESP32_BUS_TYPE_SPI_MASTER, // IO is used as SPI master pin + ESP32_BUS_TYPE_MAX +} peripheral_bus_type_t; + +typedef bool (*peripheral_bus_deinit_cb_t)(void * bus); + +// Sets the bus type and bus handle for given pin. +bool perimanSetPinBus(uint8_t pin, peripheral_bus_type_t type, void * bus); + +// Returns handle of the bus for the given pin if type of bus matches. NULL otherwise +void * perimanGetPinBus(uint8_t pin, peripheral_bus_type_t type); + +// Returns the type of the bus for the given pin if attached. ESP32_BUS_TYPE_MAX otherwise +peripheral_bus_type_t perimanGetPinBusType(uint8_t pin); + +// Sets the peripheral destructor callback. Used to destroy bus when pin is assigned another function +bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t cb); + +#ifdef __cplusplus +} +#endif From 270b24eeae93600267d42537abaad6086cc0100b Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 30 Jan 2023 21:30:45 +0200 Subject: [PATCH 22/60] Update SigmaDelta driver to use the new ESP-IDF driver API --- cores/esp32/esp32-hal-sigmadelta.c | 138 +++++++++--------- cores/esp32/esp32-hal-sigmadelta.h | 33 ++--- .../AnalogOut/SigmaDelta/SigmaDelta.ino | 10 +- 3 files changed, 83 insertions(+), 98 deletions(-) diff --git a/cores/esp32/esp32-hal-sigmadelta.c b/cores/esp32/esp32-hal-sigmadelta.c index 8ee648373ba..4dfa00fe419 100644 --- a/cores/esp32/esp32-hal-sigmadelta.c +++ b/cores/esp32/esp32-hal-sigmadelta.c @@ -1,91 +1,87 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "esp32-hal.h" +#include "esp32-hal-periman.h" #include "soc/soc_caps.h" -#include "driver/sigmadelta.h" - -#define SOC_SIGMADELTA_CHANNEL_NUM (SOC_SDM_GROUPS * SOC_SDM_CHANNELS_PER_GROUP) +#include "driver/sdm.h" -static uint8_t duty_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0}; -static uint32_t prescaler_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0}; - -static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){ - if(old_apb == new_apb){ - return; +static bool sigmaDeltaDetachBus(void * bus){ + esp_err_t err = sdm_channel_disable((sdm_channel_handle_t)bus); + if(err != ESP_OK){ + log_w("sdm_channel_disable failed with error: %d", err); } - uint32_t iarg = (uint32_t)arg; - uint8_t channel = iarg; - if(ev_type == APB_AFTER_CHANGE){ - old_apb /= 1000000; - new_apb /= 1000000; - uint32_t old_prescale = prescaler_set[channel] + 1; - uint32_t new_prescale = ((new_apb * old_prescale) / old_apb) - 1; - sigmadelta_set_prescale(channel,new_prescale); - prescaler_set[channel] = new_prescale; + err = sdm_del_channel((sdm_channel_handle_t)bus); + if(err != ESP_OK){ + log_e("sdm_del_channel failed with error: %d", err); + return false; } + return true; } -uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq) //chan 0-x according to SOC, freq 1220-312500 +bool sigmaDeltaAttach(uint8_t pin, uint32_t freq) //freq 1220-312500 { - if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){ - return 0; - } - - uint32_t apb_freq = getApbFrequency(); - uint32_t prescale = (apb_freq/(freq*256)) - 1; - if(prescale > 0xFF) { - prescale = 0xFF; + perimanSetBusDeinit(ESP32_BUS_TYPE_SIGMADELTA, sigmaDeltaDetachBus); + sdm_channel_handle_t bus = (sdm_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_SIGMADELTA); + if(bus != NULL && !perimanSetPinBus(pin, ESP32_BUS_TYPE_INIT, NULL)){ + return false; } - - sigmadelta_config_t sigmadelta_cfg = { - .channel = channel, - .sigmadelta_prescale = prescale, - .sigmadelta_duty = 0, - .sigmadelta_gpio = pin, + bus = NULL; + sdm_config_t config = { + .gpio_num = (int)pin, + .clk_src = SDM_CLK_SRC_DEFAULT, + .sample_rate_hz = freq, + .flags = { + .invert_out = 0, + .io_loop_back = 0 + } }; - sigmadelta_config(&sigmadelta_cfg); - - prescaler_set[channel] = prescale; - uint32_t iarg = channel; - addApbChangeCallback((void*)iarg, _on_apb_change); - - return apb_freq/((prescale + 1) * 256); -} - -void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-x according to SOC duty 8 bit -{ - if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){ - return; + esp_err_t err = sdm_new_channel(&config, &bus); + if(err != ESP_OK){ + log_e("sdm_new_channel failed with error: %d", err); + return false; } - duty -= 128; - - sigmadelta_set_duty(channel,duty); - duty_set[channel] = duty; + err = sdm_channel_enable(bus); + if(err != ESP_OK){ + sigmaDeltaDetachBus((void *)bus); + log_e("sdm_channel_enable failed with error: %d", err); + return false; + } + if(!perimanSetPinBus(pin, ESP32_BUS_TYPE_SIGMADELTA, (void *)bus)){ + sigmaDeltaDetachBus((void *)bus); + return false; + } + return true; } -uint8_t sigmaDeltaRead(uint8_t channel) //chan 0-x according to SOC +bool sigmaDeltaWrite(uint8_t pin, uint8_t duty) //chan 0-x according to SOC duty 8 bit { - if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){ - return 0; + sdm_channel_handle_t bus = (sdm_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_SIGMADELTA); + if(bus != NULL){ + int8_t d = duty - 128; + esp_err_t err = sdm_channel_set_duty(bus, d); + if(err != ESP_OK){ + log_e("sdm_channel_set_duty failed with error: %d", err); + return false; + } + return true; + } else { + log_e("pin %u is not attached to SigmaDelta"); } - return duty_set[channel]+128; + return false; } -void sigmaDeltaDetachPin(uint8_t pin) +bool sigmaDeltaDetach(uint8_t pin) { - pinMatrixOutDetach(pin, false, false); + void * bus = perimanGetPinBus(pin, ESP32_BUS_TYPE_SIGMADELTA); + if(bus != NULL){ + // will call sigmaDeltaDetachBus + return perimanSetPinBus(pin, ESP32_BUS_TYPE_INIT, NULL); + } else { + log_e("pin %u is not attached to SigmaDelta"); + } + return false; } \ No newline at end of file diff --git a/cores/esp32/esp32-hal-sigmadelta.h b/cores/esp32/esp32-hal-sigmadelta.h index 0a526e8d513..2b7b2471ce7 100644 --- a/cores/esp32/esp32-hal-sigmadelta.h +++ b/cores/esp32/esp32-hal-sigmadelta.h @@ -1,19 +1,10 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _ESP32_HAL_SD_H_ -#define _ESP32_HAL_SD_H_ +#pragma once #ifdef __cplusplus extern "C" { @@ -22,15 +13,13 @@ extern "C" { #include #include -//channel 0-7 freq 1220-312500 duty 0-255 -uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq); -void sigmaDeltaWrite(uint8_t channel, uint8_t duty); -uint8_t sigmaDeltaRead(uint8_t channel); -void sigmaDeltaDetachPin(uint8_t pin); +//freq 1220-312500 duty 0-255 +bool sigmaDeltaAttach(uint8_t pin, uint32_t freq); +bool sigmaDeltaWrite(uint8_t pin, uint8_t duty); +uint8_t sigmaDeltaRead(uint8_t pin); +bool sigmaDeltaDetach(uint8_t pin); #ifdef __cplusplus } #endif - -#endif /* _ESP32_HAL_SD_H_ */ diff --git a/libraries/ESP32/examples/AnalogOut/SigmaDelta/SigmaDelta.ino b/libraries/ESP32/examples/AnalogOut/SigmaDelta/SigmaDelta.ino index 6520815a113..261263fa98e 100644 --- a/libraries/ESP32/examples/AnalogOut/SigmaDelta/SigmaDelta.ino +++ b/libraries/ESP32/examples/AnalogOut/SigmaDelta/SigmaDelta.ino @@ -1,9 +1,9 @@ void setup() { - //setup on pin 18, channel 0 with frequency 312500 Hz - sigmaDeltaSetup(18,0, 312500); - //initialize channel 0 to off - sigmaDeltaWrite(0, 0); + //setup on pin 18 with frequency 312500 Hz + sigmaDeltaAttach(18, 312500); + //set pin 18 to off + sigmaDeltaWrite(18, 0); } void loop() @@ -11,6 +11,6 @@ void loop() //slowly ramp-up the value //will overflow at 256 static uint8_t i = 0; - sigmaDeltaWrite(0, i++); + sigmaDeltaWrite(18, i++); delay(100); } From b55025129d400d2f2366cc5cc8e0fad23e162c11 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 31 Jan 2023 01:17:54 +0200 Subject: [PATCH 23/60] Small improvements to peripheral manager and SigmaDelta --- cores/esp32/esp32-hal-periman.c | 10 ++++++---- cores/esp32/esp32-hal-periman.h | 23 ++++++++++++++++++++++- cores/esp32/esp32-hal-sigmadelta.c | 8 +++++--- cores/esp32/esp32-hal-sigmadelta.h | 5 ++++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/cores/esp32/esp32-hal-periman.c b/cores/esp32/esp32-hal-periman.c index c0169b95437..a990e3824ef 100644 --- a/cores/esp32/esp32-hal-periman.c +++ b/cores/esp32/esp32-hal-periman.c @@ -6,7 +6,7 @@ #include "esp32-hal-log.h" #include "esp32-hal-periman.h" -#include "soc/soc_caps.h" +#include "esp_bit_defs.h" typedef struct { peripheral_bus_type_t type; @@ -16,10 +16,12 @@ typedef struct { static peripheral_bus_deinit_cb_t deinit_functions[ESP32_BUS_TYPE_MAX]; static peripheral_pin_item_t pins[SOC_GPIO_PIN_COUNT]; +#define GPIO_NOT_VALID(p) ((p >= SOC_GPIO_PIN_COUNT) || ((SOC_GPIO_VALID_GPIO_MASK & (1ULL << p)) == 0)) + bool perimanSetPinBus(uint8_t pin, peripheral_bus_type_t type, void * bus){ peripheral_bus_type_t otype = ESP32_BUS_TYPE_INIT; void * obus = NULL; - if(pin >= SOC_GPIO_PIN_COUNT){ + if(GPIO_NOT_VALID(pin)){ log_e("Invalid pin: %u", pin); return false; } @@ -53,7 +55,7 @@ bool perimanSetPinBus(uint8_t pin, peripheral_bus_type_t type, void * bus){ } void * perimanGetPinBus(uint8_t pin, peripheral_bus_type_t type){ - if(pin >= SOC_GPIO_PIN_COUNT){ + if(GPIO_NOT_VALID(pin)){ log_e("Invalid pin: %u", pin); return NULL; } @@ -68,7 +70,7 @@ void * perimanGetPinBus(uint8_t pin, peripheral_bus_type_t type){ } peripheral_bus_type_t perimanGetPinBusType(uint8_t pin){ - if(pin >= SOC_GPIO_PIN_COUNT){ + if(GPIO_NOT_VALID(pin)){ log_e("Invalid pin: %u", pin); return ESP32_BUS_TYPE_MAX; } diff --git a/cores/esp32/esp32-hal-periman.h b/cores/esp32/esp32-hal-periman.h index 3a03499e407..af94d0d061e 100644 --- a/cores/esp32/esp32-hal-periman.h +++ b/cores/esp32/esp32-hal-periman.h @@ -9,6 +9,7 @@ extern "C" { #endif +#include "soc/soc_caps.h" #include #include #include @@ -16,21 +17,41 @@ extern "C" typedef enum { ESP32_BUS_TYPE_INIT, // IO has not been attached to a bus yet ESP32_BUS_TYPE_GPIO, // IO is used as GPIO + ESP32_BUS_TYPE_UART, // IO is used as UART pin +#if SOC_SDM_SUPPORTED ESP32_BUS_TYPE_SIGMADELTA, // IO is used as SigmeDelta output +#endif +#if SOC_ADC_SUPPORTED ESP32_BUS_TYPE_ADC_ONESHOT, // IO is used as ADC OneShot input ESP32_BUS_TYPE_ADC_CONT, // IO is used as ADC continuous input +#endif +#if SOC_DAC_SUPPORTED ESP32_BUS_TYPE_DAC_ONESHOT, // IO is used as DAC OneShot output ESP32_BUS_TYPE_DAC_CONT, // IO is used as DAC continuous output ESP32_BUS_TYPE_DAC_COSINE, // IO is used as DAC cosine output +#endif +#if SOC_LEDC_SUPPORTED + ESP32_BUS_TYPE_LEDC, // IO is used as LEDC output +#endif +#if SOC_RMT_SUPPORTED ESP32_BUS_TYPE_RMT_TX, // IO is used as RMT output ESP32_BUS_TYPE_RMT_RX, // IO is used as RMT input +#endif +#if SOC_I2S_SUPPORTED ESP32_BUS_TYPE_I2S_STD, // IO is used as I2S STD pin ESP32_BUS_TYPE_I2S_PDM, // IO is used as I2S PDM pin ESP32_BUS_TYPE_I2S_TDM, // IO is used as I2S TDM pin - ESP32_BUS_TYPE_UART, // IO is used as UART pin +#endif +#if SOC_I2C_SUPPORTED ESP32_BUS_TYPE_I2C_MASTER, // IO is used as I2C master pin ESP32_BUS_TYPE_I2C_SLAVE, // IO is used as I2C slave pin +#endif +#if SOC_GPSPI_SUPPORTED ESP32_BUS_TYPE_SPI_MASTER, // IO is used as SPI master pin +#endif +#if SOC_SDMMC_HOST_SUPPORTED + ESP32_BUS_TYPE_SDMMC, // IO is used as SDMMC pin +#endif ESP32_BUS_TYPE_MAX } peripheral_bus_type_t; diff --git a/cores/esp32/esp32-hal-sigmadelta.c b/cores/esp32/esp32-hal-sigmadelta.c index 4dfa00fe419..12b095e348b 100644 --- a/cores/esp32/esp32-hal-sigmadelta.c +++ b/cores/esp32/esp32-hal-sigmadelta.c @@ -6,7 +6,8 @@ #include "esp32-hal.h" #include "esp32-hal-periman.h" -#include "soc/soc_caps.h" + +#if SOC_SDM_SUPPORTED #include "driver/sdm.h" static bool sigmaDeltaDetachBus(void * bus){ @@ -69,7 +70,7 @@ bool sigmaDeltaWrite(uint8_t pin, uint8_t duty) //chan 0-x according to SOC duty } return true; } else { - log_e("pin %u is not attached to SigmaDelta"); + log_e("pin %u is not attached to SigmaDelta", pin); } return false; } @@ -84,4 +85,5 @@ bool sigmaDeltaDetach(uint8_t pin) log_e("pin %u is not attached to SigmaDelta"); } return false; -} \ No newline at end of file +} +#endif diff --git a/cores/esp32/esp32-hal-sigmadelta.h b/cores/esp32/esp32-hal-sigmadelta.h index 2b7b2471ce7..9500852c077 100644 --- a/cores/esp32/esp32-hal-sigmadelta.h +++ b/cores/esp32/esp32-hal-sigmadelta.h @@ -10,6 +10,9 @@ extern "C" { #endif +#include "soc/soc_caps.h" +#if SOC_SDM_SUPPORTED + #include #include @@ -19,7 +22,7 @@ bool sigmaDeltaWrite(uint8_t pin, uint8_t duty); uint8_t sigmaDeltaRead(uint8_t pin); bool sigmaDeltaDetach(uint8_t pin); - +#endif #ifdef __cplusplus } #endif From 769f92dcd67b156db9122a9ff8fb64a73351c242 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 31 Jan 2023 01:22:04 +0200 Subject: [PATCH 24/60] Remove deleted function from SigmaDelta header --- cores/esp32/esp32-hal-sigmadelta.h | 1 - 1 file changed, 1 deletion(-) diff --git a/cores/esp32/esp32-hal-sigmadelta.h b/cores/esp32/esp32-hal-sigmadelta.h index 9500852c077..bca2c532018 100644 --- a/cores/esp32/esp32-hal-sigmadelta.h +++ b/cores/esp32/esp32-hal-sigmadelta.h @@ -19,7 +19,6 @@ extern "C" { //freq 1220-312500 duty 0-255 bool sigmaDeltaAttach(uint8_t pin, uint32_t freq); bool sigmaDeltaWrite(uint8_t pin, uint8_t duty); -uint8_t sigmaDeltaRead(uint8_t pin); bool sigmaDeltaDetach(uint8_t pin); #endif From b73af1396ec7273dfc7230194d5613c760326f83 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Mon, 6 Feb 2023 09:29:32 -0300 Subject: [PATCH 25/60] Adds softAp(String) to make it compatible with ESP8266 (#7801) --- libraries/WiFi/src/WiFiAP.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/WiFi/src/WiFiAP.h b/libraries/WiFi/src/WiFiAP.h index a9d8f551e51..7ac03034b4c 100644 --- a/libraries/WiFi/src/WiFiAP.h +++ b/libraries/WiFi/src/WiFiAP.h @@ -38,6 +38,10 @@ class WiFiAPClass public: bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false); + bool softAP(const String& ssid, const String& passphrase = emptyString, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false) { + return softAP(ssid.c_str(), passphrase.c_str(), channel, ssid_hidden, max_connection, ftm_responder); + } + bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dhcp_lease_start = (uint32_t) 0); bool softAPdisconnect(bool wifioff = false); From 0f4e04b7d1a65ad2815261ff759e73aee9718809 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Mon, 6 Feb 2023 09:29:58 -0300 Subject: [PATCH 26/60] Fix commentary (#7800) Minor fix based on observation done in https://github.com/espressif/arduino-esp32/issues/7795#issuecomment-1416868611 --- libraries/Ethernet/src/ETH.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Ethernet/src/ETH.cpp b/libraries/Ethernet/src/ETH.cpp index 2dd2c1f9a30..0a79d46bf20 100644 --- a/libraries/Ethernet/src/ETH.cpp +++ b/libraries/Ethernet/src/ETH.cpp @@ -404,7 +404,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ log_e("esp_eth_init error: %d", err); } #endif - // holds a few microseconds to let DHCP start and enter into a good state + // holds a few milliseconds to let DHCP start and enter into a good state // FIX ME -- adresses issue https://github.com/espressif/arduino-esp32/issues/5733 delay(50); From c3ecc5c4d42ff64b09398cfb8c6cf60b00e15d9c Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 6 Feb 2023 19:31:06 +0700 Subject: [PATCH 27/60] add adafruit new board feather esp32s2 reserve tft (#7794) --- boards.txt | 171 ++++++++++++++++++ .../variant.cpp | 7 +- 2 files changed, 177 insertions(+), 1 deletion(-) diff --git a/boards.txt b/boards.txt index c0ceb0d7f88..0e253e434c3 100644 --- a/boards.txt +++ b/boards.txt @@ -8256,6 +8256,177 @@ adafruit_feather_esp32s2_tft.menu.EraseFlash.none.upload.erase_cmd= adafruit_feather_esp32s2_tft.menu.EraseFlash.all=Enabled adafruit_feather_esp32s2_tft.menu.EraseFlash.all.upload.erase_cmd=-e +############################################################## +# Adafruit Feather ESP32-S2 Reverse TFT + +adafruit_feather_esp32s2_reversetft.name=Adafruit Feather ESP32-S2 Reverse TFT +adafruit_feather_esp32s2_reversetft.vid.0=0x239A +adafruit_feather_esp32s2_reversetft.pid.0=0x80ED +adafruit_feather_esp32s2_reversetft.vid.1=0x239A +adafruit_feather_esp32s2_reversetft.pid.1=0x00ED +adafruit_feather_esp32s2_reversetft.vid.2=0x239A +adafruit_feather_esp32s2_reversetft.pid.2=0x80EE + +adafruit_feather_esp32s2_reversetft.bootloader.tool=esptool_py +adafruit_feather_esp32s2_reversetft.bootloader.tool.default=esptool_py + +adafruit_feather_esp32s2_reversetft.upload.tool=esptool_py +adafruit_feather_esp32s2_reversetft.upload.tool.default=esptool_py +adafruit_feather_esp32s2_reversetft.upload.tool.network=esp_ota + +adafruit_feather_esp32s2_reversetft.upload.maximum_size=1310720 +adafruit_feather_esp32s2_reversetft.upload.maximum_data_size=327680 +adafruit_feather_esp32s2_reversetft.upload.flags= +adafruit_feather_esp32s2_reversetft.upload.extra_flags= +adafruit_feather_esp32s2_reversetft.upload.use_1200bps_touch=true +adafruit_feather_esp32s2_reversetft.upload.wait_for_upload_port=true + +adafruit_feather_esp32s2_reversetft.serial.disableDTR=false +adafruit_feather_esp32s2_reversetft.serial.disableRTS=false + +adafruit_feather_esp32s2_reversetft.build.tarch=xtensa +adafruit_feather_esp32s2_reversetft.build.bootloader_addr=0x1000 +adafruit_feather_esp32s2_reversetft.build.target=esp32s2 +adafruit_feather_esp32s2_reversetft.build.mcu=esp32s2 +adafruit_feather_esp32s2_reversetft.build.core=esp32 +adafruit_feather_esp32s2_reversetft.build.variant=adafruit_feather_esp32s2_reversetft +adafruit_feather_esp32s2_reversetft.build.board=ADAFRUIT_FEATHER_ESP32S2_REVTFT + +adafruit_feather_esp32s2_reversetft.build.cdc_on_boot=1 +adafruit_feather_esp32s2_reversetft.build.msc_on_boot=0 +adafruit_feather_esp32s2_reversetft.build.dfu_on_boot=0 +adafruit_feather_esp32s2_reversetft.build.f_cpu=240000000L +adafruit_feather_esp32s2_reversetft.build.flash_size=4MB +adafruit_feather_esp32s2_reversetft.build.flash_freq=80m +adafruit_feather_esp32s2_reversetft.build.flash_mode=dio +adafruit_feather_esp32s2_reversetft.build.boot=qio +adafruit_feather_esp32s2_reversetft.build.partitions=default +adafruit_feather_esp32s2_reversetft.build.defines= + +adafruit_feather_esp32s2_reversetft.menu.CDCOnBoot.cdc=Enabled +adafruit_feather_esp32s2_reversetft.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 +adafruit_feather_esp32s2_reversetft.menu.CDCOnBoot.default=Disabled +adafruit_feather_esp32s2_reversetft.menu.CDCOnBoot.default.build.cdc_on_boot=0 + +adafruit_feather_esp32s2_reversetft.menu.MSCOnBoot.default=Disabled +adafruit_feather_esp32s2_reversetft.menu.MSCOnBoot.default.build.msc_on_boot=0 +adafruit_feather_esp32s2_reversetft.menu.MSCOnBoot.msc=Enabled +adafruit_feather_esp32s2_reversetft.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +adafruit_feather_esp32s2_reversetft.menu.DFUOnBoot.default=Disabled +adafruit_feather_esp32s2_reversetft.menu.DFUOnBoot.default.build.dfu_on_boot=0 +adafruit_feather_esp32s2_reversetft.menu.DFUOnBoot.dfu=Enabled +adafruit_feather_esp32s2_reversetft.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +adafruit_feather_esp32s2_reversetft.menu.UploadMode.cdc=Internal USB +adafruit_feather_esp32s2_reversetft.menu.UploadMode.cdc.upload.use_1200bps_touch=true +adafruit_feather_esp32s2_reversetft.menu.UploadMode.cdc.upload.wait_for_upload_port=true +adafruit_feather_esp32s2_reversetft.menu.UploadMode.default=UART0 +adafruit_feather_esp32s2_reversetft.menu.UploadMode.default.upload.use_1200bps_touch=false +adafruit_feather_esp32s2_reversetft.menu.UploadMode.default.upload.wait_for_upload_port=false + +adafruit_feather_esp32s2_reversetft.menu.PSRAM.enabled=Enabled +adafruit_feather_esp32s2_reversetft.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM +adafruit_feather_esp32s2_reversetft.menu.PSRAM.disabled=Disabled +adafruit_feather_esp32s2_reversetft.menu.PSRAM.disabled.build.defines= + +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.tinyuf2=TinyUF2 4MB (1.3MB APP/960KB FFAT) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader-tinyuf2 +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.tinyuf2.build.custom_partitions=partitions-4MB-tinyuf2 +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.tinyuf2.upload.maximum_size=1441792 +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x2d0000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.default.build.partitions=default +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.minimal.build.partitions=minimal +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.no_ota.build.partitions=no_ota +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.huge_app.build.partitions=huge_app +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +adafruit_feather_esp32s2_reversetft.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 + +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.240=240MHz (WiFi) +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.240.build.f_cpu=240000000L +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.160=160MHz (WiFi) +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.160.build.f_cpu=160000000L +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.80=80MHz (WiFi) +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.80.build.f_cpu=80000000L +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.40=40MHz +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.40.build.f_cpu=40000000L +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.20=20MHz +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.20.build.f_cpu=20000000L +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.10=10MHz +adafruit_feather_esp32s2_reversetft.menu.CPUFreq.10.build.f_cpu=10000000L + +adafruit_feather_esp32s2_reversetft.menu.FlashMode.qio=QIO +adafruit_feather_esp32s2_reversetft.menu.FlashMode.qio.build.flash_mode=dio +adafruit_feather_esp32s2_reversetft.menu.FlashMode.qio.build.boot=qio +adafruit_feather_esp32s2_reversetft.menu.FlashMode.dio=DIO +adafruit_feather_esp32s2_reversetft.menu.FlashMode.dio.build.flash_mode=dio +adafruit_feather_esp32s2_reversetft.menu.FlashMode.dio.build.boot=dio +adafruit_feather_esp32s2_reversetft.menu.FlashMode.qout=QOUT +adafruit_feather_esp32s2_reversetft.menu.FlashMode.qout.build.flash_mode=dout +adafruit_feather_esp32s2_reversetft.menu.FlashMode.qout.build.boot=qout +adafruit_feather_esp32s2_reversetft.menu.FlashMode.dout=DOUT +adafruit_feather_esp32s2_reversetft.menu.FlashMode.dout.build.flash_mode=dout +adafruit_feather_esp32s2_reversetft.menu.FlashMode.dout.build.boot=dout + +adafruit_feather_esp32s2_reversetft.menu.FlashFreq.80=80MHz +adafruit_feather_esp32s2_reversetft.menu.FlashFreq.80.build.flash_freq=80m +adafruit_feather_esp32s2_reversetft.menu.FlashFreq.40=40MHz +adafruit_feather_esp32s2_reversetft.menu.FlashFreq.40.build.flash_freq=40m + +adafruit_feather_esp32s2_reversetft.menu.FlashSize.4M=4MB (32Mb) +adafruit_feather_esp32s2_reversetft.menu.FlashSize.4M.build.flash_size=4MB + +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.921600=921600 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.921600.upload.speed=921600 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.115200=115200 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.115200.upload.speed=115200 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.256000.windows=256000 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.256000.upload.speed=256000 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.230400.windows.upload.speed=256000 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.230400=230400 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.230400.upload.speed=230400 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.460800.linux=460800 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.460800.macosx=460800 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.460800.upload.speed=460800 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.512000.windows=512000 +adafruit_feather_esp32s2_reversetft.menu.UploadSpeed.512000.upload.speed=512000 + +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.none=None +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.none.build.code_debug=0 +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.error=Error +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.error.build.code_debug=1 +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.warn=Warn +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.warn.build.code_debug=2 +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.info=Info +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.info.build.code_debug=3 +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.debug=Debug +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.debug.build.code_debug=4 +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.verbose=Verbose +adafruit_feather_esp32s2_reversetft.menu.DebugLevel.verbose.build.code_debug=5 + +adafruit_feather_esp32s2_reversetft.menu.EraseFlash.none=Disabled +adafruit_feather_esp32s2_reversetft.menu.EraseFlash.none.upload.erase_cmd= +adafruit_feather_esp32s2_reversetft.menu.EraseFlash.all=Enabled +adafruit_feather_esp32s2_reversetft.menu.EraseFlash.all.upload.erase_cmd=-e + ############################################################## # Adafruit QT Py ESP32-S2 diff --git a/variants/adafruit_feather_esp32s2_reversetft/variant.cpp b/variants/adafruit_feather_esp32s2_reversetft/variant.cpp index 750f5f72b02..548ce9ff4a1 100644 --- a/variants/adafruit_feather_esp32s2_reversetft/variant.cpp +++ b/variants/adafruit_feather_esp32s2_reversetft/variant.cpp @@ -31,7 +31,12 @@ extern "C" { // Initialize variant/board, called before setup() void initVariant(void) { - + // This board has power control pins, and we must set them to output and high + // in order to enable the NeoPixels, TFT & I2C + pinMode(NEOPIXEL_POWER, OUTPUT); + digitalWrite(NEOPIXEL_POWER, HIGH); + pinMode(TFT_I2C_POWER, OUTPUT); + digitalWrite(TFT_I2C_POWER, HIGH); } } From f2950ba4b8b1d5807727e5f38551de0ed8b01ec1 Mon Sep 17 00:00:00 2001 From: Martin Turski Date: Mon, 6 Feb 2023 13:43:22 +0100 Subject: [PATCH 28/60] bugfix: add for uint8_t to avoid compilation failure (GCC 11.2.0) (#7744) --- cores/esp32/FunctionalInterrupt.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cores/esp32/FunctionalInterrupt.h b/cores/esp32/FunctionalInterrupt.h index b5e3181f986..69bb5aee7b3 100644 --- a/cores/esp32/FunctionalInterrupt.h +++ b/cores/esp32/FunctionalInterrupt.h @@ -9,6 +9,7 @@ #define CORE_CORE_FUNCTIONALINTERRUPT_H_ #include +#include struct InterruptArgStructure { std::function interruptFunction; From 8f4f37dfe6584dc70c86d3849fbabd7883670eb3 Mon Sep 17 00:00:00 2001 From: raviypujar Date: Mon, 6 Feb 2023 18:14:17 +0530 Subject: [PATCH 29/60] Adding 3rd party boards for VALTRACK-V4-VTS-ESP32-C3 & VALTRACK-V4-MFW-ESP32-C3 (#7735) * Added VALTRACK-V4-VTS-ESP32-C3 board definition Created pins_arduino.h & made changes to boards.txt with necessary changes * Modified the URL * Renamed json * renamed all auRL * Adding VALTRACK-V4 series board definitions Added VALTRACK-V4-VTS-ESP32C3 & VALTRACK-V4-MFW-ESP32-C3 board variants * Adding VALTRACK-V4 series board definitions Added VALTRACK-V4-VTS-ESP32C3 & VALTRACK-V4-MFW-ESP32-C3 board variants * Reverted package_esp32_index.template.json restored package_esp32_index.template.json from edits * Reverted package_esp32_index.template.json Added new line to package_esp32_index.template.json --- boards.txt | 308 ++++++++++++++++++ .../VALTRACK_V4_MFW_ESP32_C3/pins_arduino.h | 57 ++++ .../VALTRACK_V4_VTS_ESP32_C3/pins_arduino.h | 57 ++++ 3 files changed, 422 insertions(+) create mode 100644 variants/VALTRACK_V4_MFW_ESP32_C3/pins_arduino.h create mode 100644 variants/VALTRACK_V4_VTS_ESP32_C3/pins_arduino.h diff --git a/boards.txt b/boards.txt index 0e253e434c3..a165b97756a 100644 --- a/boards.txt +++ b/boards.txt @@ -20820,3 +20820,311 @@ esp32c3m1IKit.menu.EraseFlash.all=Enabled esp32c3m1IKit.menu.EraseFlash.all.upload.erase_cmd=-e ############################################################## + +VALTRACK_V4_VTS_ESP32_C3.name=VALTRACK_V4_VTS_ESP32_C3 +VALTRACK_V4_VTS_ESP32_C3.vid.0=0x303a +VALTRACK_V4_VTS_ESP32_C3.pid.0=0x1001 + +VALTRACK_V4_VTS_ESP32_C3.bootloader.tool=esptool_py +VALTRACK_V4_VTS_ESP32_C3.bootloader.tool.default=esptool_py + +VALTRACK_V4_VTS_ESP32_C3.upload.tool=esptool_py +VALTRACK_V4_VTS_ESP32_C3.upload.tool.default=esptool_py +VALTRACK_V4_VTS_ESP32_C3.upload.tool.network=esp_ota + +VALTRACK_V4_VTS_ESP32_C3.upload.maximum_size=1310720 +VALTRACK_V4_VTS_ESP32_C3.upload.maximum_data_size=327680 +VALTRACK_V4_VTS_ESP32_C3.upload.flags= +VALTRACK_V4_VTS_ESP32_C3.upload.extra_flags= +VALTRACK_V4_VTS_ESP32_C3.upload.use_1200bps_touch=false +VALTRACK_V4_VTS_ESP32_C3.upload.wait_for_upload_port=false + +VALTRACK_V4_VTS_ESP32_C3.serial.disableDTR=false +VALTRACK_V4_VTS_ESP32_C3.serial.disableRTS=false + +VALTRACK_V4_VTS_ESP32_C3.build.tarch=riscv32 +VALTRACK_V4_VTS_ESP32_C3.build.target=esp +VALTRACK_V4_VTS_ESP32_C3.build.mcu=esp32c3 +VALTRACK_V4_VTS_ESP32_C3.build.core=esp32 +VALTRACK_V4_VTS_ESP32_C3.build.variant=VALTRACK_V4_VTS_ESP32_C3 +VALTRACK_V4_VTS_ESP32_C3.build.board=VALTRACK_V4_VTS_ESP32_C3 +VALTRACK_V4_VTS_ESP32_C3.build.bootloader_addr=0x0 + +VALTRACK_V4_VTS_ESP32_C3.build.cdc_on_boot=1 +VALTRACK_V4_VTS_ESP32_C3.build.f_cpu=160000000L +VALTRACK_V4_VTS_ESP32_C3.build.flash_size=4MB +VALTRACK_V4_VTS_ESP32_C3.build.flash_freq=80m +VALTRACK_V4_VTS_ESP32_C3.build.flash_mode=qio +VALTRACK_V4_VTS_ESP32_C3.build.boot=qio +VALTRACK_V4_VTS_ESP32_C3.build.partitions=default +VALTRACK_V4_VTS_ESP32_C3.build.defines= + +VALTRACK_V4_VTS_ESP32_C3.menu.CDCOnBoot.default=Enabled +VALTRACK_V4_VTS_ESP32_C3.menu.CDCOnBoot.default.build.cdc_on_boot=1 +VALTRACK_V4_VTS_ESP32_C3.menu.CDCOnBoot.cdc=Disabled +VALTRACK_V4_VTS_ESP32_C3.menu.CDCOnBoot.cdc.build.cdc_on_boot=0 + +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.default.build.partitions=default +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.default_8MB=8M with spiffs (3MB APP/1.5MB SPIFFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.default_8MB.build.partitions=default_8MB +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.minimal.build.partitions=minimal +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.no_ota.build.partitions=no_ota +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.huge_app.build.partitions=huge_app +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FATFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.fatflash.build.partitions=ffat +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9.9MB FATFS) +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.rainmaker=RainMaker +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +VALTRACK_V4_VTS_ESP32_C3.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 + +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.160=160MHz (WiFi) +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.160.build.f_cpu=160000000L +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.80=80MHz (WiFi) +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.80.build.f_cpu=80000000L +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.40=40MHz +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.40.build.f_cpu=40000000L +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.20=20MHz +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.20.build.f_cpu=20000000L +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.10=10MHz +VALTRACK_V4_VTS_ESP32_C3.menu.CPUFreq.10.build.f_cpu=10000000L + +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.qio=QIO +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.qio.build.flash_mode=dio +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.qio.build.boot=qio +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.dio=DIO +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.dio.build.flash_mode=dio +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.dio.build.boot=dio +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.qout=QOUT +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.qout.build.flash_mode=dout +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.qout.build.boot=qout +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.dout=DOUT +VALTRACK_V4_VTS_ESP32_C3.menu.FlashMode.dout.build.flash_mode=dout + +VALTRACK_V4_VTS_ESP32_C3.menu.FlashFreq.80=80MHz +VALTRACK_V4_VTS_ESP32_C3.menu.FlashFreq.80.build.flash_freq=80m +VALTRACK_V4_VTS_ESP32_C3.menu.FlashFreq.40=40MHz +VALTRACK_V4_VTS_ESP32_C3.menu.FlashFreq.40.build.flash_freq=40m + +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.4M=4MB (32Mb) +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.4M.build.flash_size=4MB +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.8M=8MB (64Mb) +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.8M.build.flash_size=8MB +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.8M.build.partitions=default_8MB +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.2M=2MB (16Mb) +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.2M.build.flash_size=2MB +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.2M.build.partitions=minimal +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.16M=16MB (128Mb) +VALTRACK_V4_VTS_ESP32_C3.menu.FlashSize.16M.build.flash_size=16MB + +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.921600=921600 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.921600.upload.speed=921600 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.115200=115200 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.115200.upload.speed=115200 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.256000.windows=256000 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.256000.upload.speed=256000 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.230400.windows.upload.speed=256000 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.230400=230400 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.230400.upload.speed=230400 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.460800.linux=460800 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.460800.macosx=460800 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.460800.upload.speed=460800 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.512000.windows=512000 +VALTRACK_V4_VTS_ESP32_C3.menu.UploadSpeed.512000.upload.speed=512000 + +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.none=None +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.none.build.code_debug=0 +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.error=Error +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.error.build.code_debug=1 +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.warn=Warn +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.warn.build.code_debug=2 +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.info=Info +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.info.build.code_debug=3 +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.debug=Debug +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.debug.build.code_debug=4 +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.verbose=Verbose +VALTRACK_V4_VTS_ESP32_C3.menu.DebugLevel.verbose.build.code_debug=5 + +VALTRACK_V4_VTS_ESP32_C3.menu.EraseFlash.none=Disabled +VALTRACK_V4_VTS_ESP32_C3.menu.EraseFlash.none.upload.erase_cmd= +VALTRACK_V4_VTS_ESP32_C3.menu.EraseFlash.all=Enabled +VALTRACK_V4_VTS_ESP32_C3.menu.EraseFlash.all.upload.erase_cmd=-e + +############################################################## + +VALTRACK_V4_MFW_ESP32_C3.name=VALTRACK_V4_MFW_ESP32_C3 +VALTRACK_V4_MFW_ESP32_C3.vid.0=0x303a +VALTRACK_V4_MFW_ESP32_C3.pid.0=0x1001 + +VALTRACK_V4_MFW_ESP32_C3.bootloader.tool=esptool_py +VALTRACK_V4_MFW_ESP32_C3.bootloader.tool.default=esptool_py + +VALTRACK_V4_MFW_ESP32_C3.upload.tool=esptool_py +VALTRACK_V4_MFW_ESP32_C3.upload.tool.default=esptool_py +VALTRACK_V4_MFW_ESP32_C3.upload.tool.network=esp_ota + +VALTRACK_V4_MFW_ESP32_C3.upload.maximum_size=1310720 +VALTRACK_V4_MFW_ESP32_C3.upload.maximum_data_size=327680 +VALTRACK_V4_MFW_ESP32_C3.upload.flags= +VALTRACK_V4_MFW_ESP32_C3.upload.extra_flags= +VALTRACK_V4_MFW_ESP32_C3.upload.use_1200bps_touch=false +VALTRACK_V4_MFW_ESP32_C3.upload.wait_for_upload_port=false + +VALTRACK_V4_MFW_ESP32_C3.serial.disableDTR=false +VALTRACK_V4_MFW_ESP32_C3.serial.disableRTS=false + +VALTRACK_V4_MFW_ESP32_C3.build.tarch=riscv32 +VALTRACK_V4_MFW_ESP32_C3.build.target=esp +VALTRACK_V4_MFW_ESP32_C3.build.mcu=esp32c3 +VALTRACK_V4_MFW_ESP32_C3.build.core=esp32 +VALTRACK_V4_MFW_ESP32_C3.build.variant=VALTRACK_V4_MFW_ESP32_C3 +VALTRACK_V4_MFW_ESP32_C3.build.board=VALTRACK_V4_MFW_ESP32_C3 +VALTRACK_V4_MFW_ESP32_C3.build.bootloader_addr=0x0 + +VALTRACK_V4_MFW_ESP32_C3.build.cdc_on_boot=1 +VALTRACK_V4_MFW_ESP32_C3.build.f_cpu=160000000L +VALTRACK_V4_MFW_ESP32_C3.build.flash_size=4MB +VALTRACK_V4_MFW_ESP32_C3.build.flash_freq=80m +VALTRACK_V4_MFW_ESP32_C3.build.flash_mode=qio +VALTRACK_V4_MFW_ESP32_C3.build.boot=qio +VALTRACK_V4_MFW_ESP32_C3.build.partitions=default +VALTRACK_V4_MFW_ESP32_C3.build.defines= + +VALTRACK_V4_MFW_ESP32_C3.menu.CDCOnBoot.default=Enabled +VALTRACK_V4_MFW_ESP32_C3.menu.CDCOnBoot.default.build.cdc_on_boot=1 +VALTRACK_V4_MFW_ESP32_C3.menu.CDCOnBoot.cdc=Disabled +VALTRACK_V4_MFW_ESP32_C3.menu.CDCOnBoot.cdc.build.cdc_on_boot=0 + +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.default.build.partitions=default +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.default_8MB=8M with spiffs (3MB APP/1.5MB SPIFFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.default_8MB.build.partitions=default_8MB +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.minimal.build.partitions=minimal +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.no_ota.build.partitions=no_ota +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.huge_app.build.partitions=huge_app +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FATFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.fatflash.build.partitions=ffat +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9.9MB FATFS) +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.rainmaker=RainMaker +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +VALTRACK_V4_MFW_ESP32_C3.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 + +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.160=160MHz (WiFi) +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.160.build.f_cpu=160000000L +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.80=80MHz (WiFi) +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.80.build.f_cpu=80000000L +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.40=40MHz +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.40.build.f_cpu=40000000L +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.20=20MHz +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.20.build.f_cpu=20000000L +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.10=10MHz +VALTRACK_V4_MFW_ESP32_C3.menu.CPUFreq.10.build.f_cpu=10000000L + +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.qio=QIO +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.qio.build.flash_mode=dio +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.qio.build.boot=qio +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.dio=DIO +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.dio.build.flash_mode=dio +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.dio.build.boot=dio +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.qout=QOUT +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.qout.build.flash_mode=dout +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.qout.build.boot=qout +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.dout=DOUT +VALTRACK_V4_MFW_ESP32_C3.menu.FlashMode.dout.build.flash_mode=dout + +VALTRACK_V4_MFW_ESP32_C3.menu.FlashFreq.80=80MHz +VALTRACK_V4_MFW_ESP32_C3.menu.FlashFreq.80.build.flash_freq=80m +VALTRACK_V4_MFW_ESP32_C3.menu.FlashFreq.40=40MHz +VALTRACK_V4_MFW_ESP32_C3.menu.FlashFreq.40.build.flash_freq=40m + +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.4M=4MB (32Mb) +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.4M.build.flash_size=4MB +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.8M=8MB (64Mb) +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.8M.build.flash_size=8MB +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.8M.build.partitions=default_8MB +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.2M=2MB (16Mb) +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.2M.build.flash_size=2MB +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.2M.build.partitions=minimal +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.16M=16MB (128Mb) +VALTRACK_V4_MFW_ESP32_C3.menu.FlashSize.16M.build.flash_size=16MB + +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.921600=921600 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.921600.upload.speed=921600 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.115200=115200 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.115200.upload.speed=115200 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.256000.windows=256000 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.256000.upload.speed=256000 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.230400.windows.upload.speed=256000 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.230400=230400 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.230400.upload.speed=230400 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.460800.linux=460800 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.460800.macosx=460800 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.460800.upload.speed=460800 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.512000.windows=512000 +VALTRACK_V4_MFW_ESP32_C3.menu.UploadSpeed.512000.upload.speed=512000 + +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.none=None +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.none.build.code_debug=0 +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.error=Error +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.error.build.code_debug=1 +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.warn=Warn +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.warn.build.code_debug=2 +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.info=Info +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.info.build.code_debug=3 +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.debug=Debug +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.debug.build.code_debug=4 +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.verbose=Verbose +VALTRACK_V4_MFW_ESP32_C3.menu.DebugLevel.verbose.build.code_debug=5 + +VALTRACK_V4_MFW_ESP32_C3.menu.EraseFlash.none=Disabled +VALTRACK_V4_MFW_ESP32_C3.menu.EraseFlash.none.upload.erase_cmd= +VALTRACK_V4_MFW_ESP32_C3.menu.EraseFlash.all=Enabled +VALTRACK_V4_MFW_ESP32_C3.menu.EraseFlash.all.upload.erase_cmd=-e + +############################################################## \ No newline at end of file diff --git a/variants/VALTRACK_V4_MFW_ESP32_C3/pins_arduino.h b/variants/VALTRACK_V4_MFW_ESP32_C3/pins_arduino.h new file mode 100644 index 00000000000..4e3c771578b --- /dev/null +++ b/variants/VALTRACK_V4_MFW_ESP32_C3/pins_arduino.h @@ -0,0 +1,57 @@ +#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 EXTERNAL_NUM_INTERRUPTS 22 +#define NUM_DIGITAL_PINS 22 +#define NUM_ANALOG_INPUTS 6 + +#define analogInputToDigitalPin(p) (((p) Date: Mon, 6 Feb 2023 13:45:30 +0100 Subject: [PATCH 30/60] Update Platformio CI (#7725) --- .github/scripts/install-platformio-esp32.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh index 96cf7330f6b..b3f7b081ba1 100755 --- a/.github/scripts/install-platformio-esp32.sh +++ b/.github/scripts/install-platformio-esp32.sh @@ -3,8 +3,8 @@ export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32" PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git" -TOOLCHAIN_VERSION="8.4.0+2021r2-patch3" -ESPTOOLPY_VERSION="~1.40201.0" +TOOLCHAIN_VERSION="8.4.0+2021r2-patch5" +ESPTOOLPY_VERSION="~1.40400.0" ESPRESSIF_ORGANIZATION_NAME="espressif" echo "Installing Python Wheel ..." From 51bc08c1861a20d5dc90665e209af7cf0f514865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Piln=C3=BD?= <34927466+PilnyTomas@users.noreply.github.com> Date: Mon, 6 Feb 2023 13:54:11 +0100 Subject: [PATCH 31/60] WiFiClient example fix (#7711) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Modified WiFiClient example to use thingspeak instead of non-functionig sparkfun * Moved instructions to README * Fixed spelling * Added link to S3 datasheet --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> --- libraries/WiFi/examples/WiFiClient/README.md | 165 ++++++++++++++++++ .../WiFi/examples/WiFiClient/WiFiClient.ino | 132 +++++++------- 2 files changed, 238 insertions(+), 59 deletions(-) create mode 100644 libraries/WiFi/examples/WiFiClient/README.md diff --git a/libraries/WiFi/examples/WiFiClient/README.md b/libraries/WiFi/examples/WiFiClient/README.md new file mode 100644 index 00000000000..079ed9f29a8 --- /dev/null +++ b/libraries/WiFi/examples/WiFiClient/README.md @@ -0,0 +1,165 @@ +# WiFiClient + +This example demonstrates reading and writing data from and to a web service which can be used for logging data, creating insights and taking actions based on those data. + +# Supported Targets + +Currently, this example supports all SoC with WiFi. + + +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | + + +## How to Use Example + +Flash this example and observe the serial output. You can also take a look at the values at [https://thingspeak.com/channels/2005329](https://thingspeak.com/channels/2005329) + +Please note that this public channel can be accessed by anyone and it is possible that more people will write their values. + +### Configure the Project + +Change `SSID` and `password` to connect to your WiFi. +Default values will allow you to use this example without any changes. If you want to use your own channel and you don't have one already follow these steps: + +* Create an account on [thingspeak.com](https://www.thingspeak.com). +* After logging in, click on the "New Channel" button to create a new channel for your data. This is where your data will be stored and displayed. +* Fill in the Name, Description, and other fields for your channel as desired, then click the "Save Channel" button. +* Take note of the "Write API Key" located in the "API keys" tab, this is the key you will use to send data to your channel. +* Replace the channelID from tab "Channel Settings" and privateKey with "Read API Keys" from "API Keys" tab. +* Replace the host variable with the thingspeak server hostname "api.thingspeak.com" +* Upload the sketch to your ESP32 board and make sure that the board is connected to the internet. The ESP32 should now send data to your Thingspeak channel at the intervals specified by the loop function. +* Go to the channel view page on thingspeak and check the "Field1" for the new incoming data. +* You can use the data visualization and analysis tools provided by Thingspeak to display and process your data in various ways. +* Please note, that Thingspeak accepts only integer values. + +#### Config example: + +You can find the data to be changed at the top of the file: + +```cpp +const char* ssid = "your-ssid"; // Change this to your WiFi SSID +const char* password = "your-password"; // Change this to your WiFi password + +const char* host = "api.thingspeak.com"; // This should not be changed +const int httpPort = 80; // This should not be changed +const String channelID = "2005329"; // Change this to your channel ID +const String writeApiKey = "V6YOTILH9I7D51F9"; // Change this to your Write API key +const String readApiKey = "34W6LGLIFXD56MPM"; // Change this to your Read API key + +// The default example accepts one data filed named "field1" +// For your own server you can ofcourse create more of them. +int field1 = 0; + +int numberOfResults = 3; // Number of results to be read +int fieldNumber = 1; // Field number which will be read out +``` + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. + +## Example Log Output + +The initial output which is common for all examples can be ignored: +``` +SP-ROM:esp32c3-api1-20210207 +Build:Feb 7 2021 +rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT) +SPIWP:0xee +mode:DIO, clock div:1 +load:0x3fcd5810,len:0x438 +load:0x403cc710,len:0x918 +load:0x403ce710,len:0x24e4 +entry 0x403cc710 +``` +Follows the setup output where connection to your WiFi happens: +``` +****************************************************** +Connecting to your-ssid +. +WiFi connected +IP address: +192.168.1.2 +``` +Then you can see the write log: +``` +HTTP/1.1 200 OK +Date: Fri, 13 Jan 2023 13:12:31 GMT +Content-Type: text/plain; charset=utf-8 +Content-Length: 1 +Connection: close +Status: 200 OK +Cache-Control: max-age=0, private, must-revalidate +Access-Control-Allow-Origin: * +Access-Control-Max-Age: 1800 +X-Request-Id: 188e3464-f155-44b0-96f6-0f3614170bb0 +Access-Control-Allow-Headers: origin, content-type, X-Requested-With +Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH +ETag: W/"5feceb66ffc86f38d952786c6d696c79" +X-Frame-Options: SAMEORIGIN + +0 +Closing connection +``` +Last portion is the read log: +``` +HTTP/1.1 200 OK +Date: Fri, 13 Jan 2023 13:12:32 GMT +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: chunked +Connection: close +Status: 200 OK +Cache-Control: max-age=7, private +Access-Control-Allow-Origin: * +Access-Control-Max-Age: 1800 +X-Request-Id: 91b97016-7625-44f6-9797-1b2973aa57b7 +Access-Control-Allow-Headers: origin, content-type, X-Requested-With +Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH +ETag: W/"8e9c308fe2c50309f991586be1aff28d" +X-Frame-Options: SAMEORIGIN + +1e3 +{"channel":{"id":2005329,"name":"WiFiCLient example","description":"Default setup for Arduino ESP32 WiFiClient example","latitude":"0.0","longitude":"0.0","field1":"data0","created_at":"2023-01-11T15:56:08Z","updated_at":"2023-01-13T08:13:58Z","last_entry_id":2871},"feeds":[{"created_at":"2023-01-13T13:11:30Z","entry_id":2869,"field1":"359"},{"created_at":"2023-01-13T13:11:57Z","entry_id":2870,"field1":"361"},{"created_at":"2023-01-13T13:12:23Z","entry_id":2871,"field1":"363"}]} +0 + + +Closing connection +``` +After this the write+read log repeat every 10 seconds. + + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **WiFi not connected:** Check the SSID and password and also that the signal has sufficient strength. +* **400 Bad Request:** Check the writeApiKey. +* **404 Not Found:** Check the channel ID. +* **No data on chart / reading NULL:** Data must be sent as an integer, without commas. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try the Troubleshooting and to check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/WiFi/examples/WiFiClient/WiFiClient.ino b/libraries/WiFi/examples/WiFiClient/WiFiClient.ino index 7dd9c8d0d35..ebd207984a2 100644 --- a/libraries/WiFi/examples/WiFiClient/WiFiClient.ino +++ b/libraries/WiFi/examples/WiFiClient/WiFiClient.ino @@ -1,29 +1,46 @@ /* - * This sketch sends data via HTTP GET requests to data.sparkfun.com service. - * - * You need to get streamId and privateKey at data.sparkfun.com and paste them - * below. Or just customize this script to talk to other HTTP servers. - * + Go to thingspeak.com and create an account if you don't have one already. + After logging in, click on the "New Channel" button to create a new channel for your data. This is where your data will be stored and displayed. + Fill in the Name, Description, and other fields for your channel as desired, then click the "Save Channel" button. + Take note of the "Write API Key" located in the "API keys" tab, this is the key you will use to send data to your channel. + Replace the channelID from tab "Channel Settings" and privateKey with "Read API Keys" from "API Keys" tab. + Replace the host variable with the thingspeak server hostname "api.thingspeak.com" + Upload the sketch to your ESP32 board and make sure that the board is connected to the internet. The ESP32 should now send data to your Thingspeak channel at the intervals specified by the loop function. + Go to the channel view page on thingspeak and check the "Field1" for the new incoming data. + You can use the data visualization and analysis tools provided by Thingspeak to display and process your data in various ways. + Please note, that Thingspeak accepts only integer values. + + You can later check the values at https://thingspeak.com/channels/2005329 + Please note that this public channel can be accessed by anyone and it is possible that more people will write their values. */ #include -const char* ssid = "your-ssid"; -const char* password = "your-password"; +const char* ssid = "your-ssid"; // Change this to your WiFi SSID +const char* password = "your-password"; // Change this to your WiFi password -const char* host = "data.sparkfun.com"; -const char* streamId = "...................."; -const char* privateKey = "...................."; +const char* host = "api.thingspeak.com"; // This should not be changed +const int httpPort = 80; // This should not be changed +const String channelID = "2005329"; // Change this to your channel ID +const String writeApiKey = "V6YOTILH9I7D51F9"; // Change this to your Write API key +const String readApiKey = "34W6LGLIFXD56MPM"; // Change this to your Read API key + +// The default example accepts one data filed named "field1" +// For your own server you can ofcourse create more of them. +int field1 = 0; + +int numberOfResults = 3; // Number of results to be read +int fieldNumber = 1; // Field number which will be read out void setup() { Serial.begin(115200); - delay(10); + while(!Serial){delay(100);} // We start by connecting to a WiFi network Serial.println(); - Serial.println(); + Serial.println("******************************************************"); Serial.print("Connecting to "); Serial.println(ssid); @@ -40,55 +57,52 @@ void setup() Serial.println(WiFi.localIP()); } -int value = 0; - -void loop() -{ - delay(5000); - ++value; - - Serial.print("connecting to "); - Serial.println(host); - - // Use WiFiClient class to create TCP connections - WiFiClient client; - const int httpPort = 80; - if (!client.connect(host, httpPort)) { - Serial.println("connection failed"); - return; +void readResponse(WiFiClient *client){ + unsigned long timeout = millis(); + while(client->available() == 0){ + if(millis() - timeout > 5000){ + Serial.println(">>> Client Timeout !"); + client->stop(); + return; } + } - // We now create a URI for the request - String url = "/input/"; - url += streamId; - url += "?private_key="; - url += privateKey; - url += "&value="; - url += value; - - Serial.print("Requesting URL: "); - Serial.println(url); - - // This will send the request to the server - client.print(String("GET ") + url + " HTTP/1.1\r\n" + - "Host: " + host + "\r\n" + - "Connection: close\r\n\r\n"); - unsigned long timeout = millis(); - while (client.available() == 0) { - if (millis() - timeout > 5000) { - Serial.println(">>> Client Timeout !"); - client.stop(); - return; - } - } - - // Read all the lines of the reply from server and print them to Serial - while(client.available()) { - String line = client.readStringUntil('\r'); - Serial.print(line); - } + // Read all the lines of the reply from server and print them to Serial + while(client->available()) { + String line = client->readStringUntil('\r'); + Serial.print(line); + } - Serial.println(); - Serial.println("closing connection"); + Serial.printf("\nClosing connection\n\n"); } +void loop(){ + WiFiClient client; + String footer = String(" HTTP/1.1\r\n") + "Host: " + String(host) + "\r\n" + "Connection: close\r\n\r\n"; + + // WRITE -------------------------------------------------------------------------------------------- + if (!client.connect(host, httpPort)) { + return; + } + + client.print("GET /update?api_key=" + writeApiKey + "&field1=" + field1 + footer); + readResponse(&client); + + // READ -------------------------------------------------------------------------------------------- + + String readRequest = "GET /channels/" + channelID + "/fields/" + fieldNumber + ".json?results=" + numberOfResults + " HTTP/1.1\r\n" + + "Host: " + host + "\r\n" + + "Connection: close\r\n\r\n"; + + if (!client.connect(host, httpPort)) { + return; + } + + client.print(readRequest); + readResponse(&client); + + // ------------------------------------------------------------------------------------------------- + + ++field1; + delay(10000); +} \ No newline at end of file From 490f1d6c86ac05e59bd39a6f492456a6dd891198 Mon Sep 17 00:00:00 2001 From: Daniel Berlin Date: Mon, 6 Feb 2023 07:54:44 -0500 Subject: [PATCH 32/60] Mirror update from Heltec repository (#7709) Heltec updated the I2C pins in https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series/commit/b10f4bf85d13fd01be80dcdb0eb59e6a8c8ba19a --- variants/heltec_wifi_lora_32_V3/pins_arduino.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/variants/heltec_wifi_lora_32_V3/pins_arduino.h b/variants/heltec_wifi_lora_32_V3/pins_arduino.h index 04dcadc4030..24fd2a41f28 100644 --- a/variants/heltec_wifi_lora_32_V3/pins_arduino.h +++ b/variants/heltec_wifi_lora_32_V3/pins_arduino.h @@ -29,8 +29,8 @@ static const uint8_t LED_BUILTIN = SOC_GPIO_PIN_COUNT+48; 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 SDA = 41; +static const uint8_t SCL = 42; static const uint8_t SS = 10; static const uint8_t MOSI = 11; From 53e3f9893ab80fe170a2aa4c73d94422ea0c5ca0 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Mon, 6 Feb 2023 09:55:41 -0300 Subject: [PATCH 33/60] Fixes BLE data printing (#7699) * Fixes BLE data printing BLE data has no '\0' terminator, therefore it can't be printed as a regular C string. This fix just prints the BLE data based on its length. * Simplify printing to a single call --- libraries/BLE/examples/BLE_client/BLE_client.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/BLE/examples/BLE_client/BLE_client.ino b/libraries/BLE/examples/BLE_client/BLE_client.ino index 5d39c109709..74ae8b7532d 100644 --- a/libraries/BLE/examples/BLE_client/BLE_client.ino +++ b/libraries/BLE/examples/BLE_client/BLE_client.ino @@ -29,7 +29,8 @@ static void notifyCallback( Serial.print(" of data length "); Serial.println(length); Serial.print("data: "); - Serial.println((char*)pData); + Serial.write(pData, length); + Serial.println(); } class MyClientCallback : public BLEClientCallbacks { From 2bd5f721f8f2c82d4d9f5947af6be5a2a0678aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 6 Feb 2023 13:56:32 +0100 Subject: [PATCH 34/60] split menu options + lora_32_V3 fix (#7697) --- boards.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/boards.txt b/boards.txt index a165b97756a..ba4ee1a0316 100644 --- a/boards.txt +++ b/boards.txt @@ -1,3 +1,4 @@ +# Official Espressif options menu.UploadSpeed=Upload Speed menu.USBMode=USB Mode menu.CDCOnBoot=USB CDC On Boot @@ -11,15 +12,19 @@ menu.FlashSize=Flash Size menu.PartitionScheme=Partition Scheme menu.DebugLevel=Core Debug Level menu.PSRAM=PSRAM -menu.Revision=Board Revision -menu.LORAWAN_REGION=LoRaWan Region -menu.LoRaWanDebugLevel=LoRaWan Debug Level menu.LoopCore=Arduino Runs On menu.EventsCore=Events Run On menu.MemoryType=Memory Type menu.EraseFlash=Erase All Flash Before Sketch Upload menu.JTAGAdapter=JTAG Adapter +# Custom options +menu.Revision=Board Revision +menu.LORAWAN_REGION=LoRaWan Region +menu.LoRaWanDebugLevel=LoRaWan Debug Level +menu.LORAWAN_DEVEUI=LoRaWan DevEUI +menu.LORAWAN_PREAMBLE_LENGTH=LoRaWan Preamble Length + ############################################################## ### DO NOT PUT BOARDS ABOVE THE OFFICIAL ESPRESSIF BOARDS! ### ############################################################## @@ -12179,8 +12184,8 @@ heltec_wifi_lora_32_V3.build.bootloader_addr=0x0 heltec_wifi_lora_32_V3.build.target=esp32s3 heltec_wifi_lora_32_V3.build.mcu=esp32s3 heltec_wifi_lora_32_V3.build.core=esp32 -heltec_wifi_lora_32_V3.build.variant=heltec_heltec_wifi_lora_32_V3 -heltec_wifi_lora_32_V3.build.board=heltec_heltec_wifi_32_lora_V3 +heltec_wifi_lora_32_V3.build.variant=heltec_wifi_lora_32_V3 +heltec_wifi_lora_32_V3.build.board=heltec_wifi_32_lora_V3 heltec_wifi_lora_32_V3.build.usb_mode=1 heltec_wifi_lora_32_V3.build.cdc_on_boot=0 @@ -12290,7 +12295,6 @@ heltec_wifi_lora_32_V3.menu.LORAWAN_PREAMBLE_LENGTH.1=16(For M00 and M00L) heltec_wifi_lora_32_V3.menu.LORAWAN_PREAMBLE_LENGTH.1.build.LORAWAN_PREAMBLE_LENGTH=16 heltec_wifi_lora_32_V3.build.defines=-D{build.band} -DLoRaWAN_DEBUG_LEVEL={build.LoRaWanDebugLevel} -DACTIVE_REGION=LORAMAC_{build.band} -DLORAWAN_PREAMBLE_LENGTH={build.LORAWAN_PREAMBLE_LENGTH} -DLORAWAN_DEVEUI_AUTO={build.LORAWAN_DEVEUI_AUTO} -D{build.board} -heltec_wifi_lora_32_V3.build.extra_libs=-lheltec heltec_wifi_lora_32_V3.menu.EraseFlash.none=Disabled heltec_wifi_lora_32_V3.menu.EraseFlash.none.upload.erase_cmd= From 6913eaabe4ba089cf7e512a0454dc36e137b61af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nima=20Askari=20=28=D9=86=DB=8C=D9=85=D8=A7=20=D8=B9=D8=B3?= =?UTF-8?q?=DA=A9=D8=B1=DB=8C=29?= Date: Mon, 6 Feb 2023 16:34:19 +0330 Subject: [PATCH 35/60] Change header gaurd name (#7696) --- libraries/Update/src/Update.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/Update/src/Update.h b/libraries/Update/src/Update.h index 303ec7cc4cc..0969f248666 100644 --- a/libraries/Update/src/Update.h +++ b/libraries/Update/src/Update.h @@ -1,5 +1,5 @@ -#ifndef ESP8266UPDATER_H -#define ESP8266UPDATER_H +#ifndef ESP32UPDATER_H +#define ESP32UPDATER_H #include #include From 6cd0ebc11a4d1b1556f3b548f84d476d777e02f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nima=20Askari=20=28=D9=86=DB=8C=D9=85=D8=A7=20=D8=B9=D8=B3?= =?UTF-8?q?=DA=A9=D8=B1=DB=8C=29?= Date: Mon, 6 Feb 2023 16:35:31 +0330 Subject: [PATCH 36/60] Fix Name (#7691) Wrong name in definitions. --- libraries/Update/src/HttpsOTAUpdate.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/Update/src/HttpsOTAUpdate.h b/libraries/Update/src/HttpsOTAUpdate.h index c2030a96477..076e4f7894b 100644 --- a/libraries/Update/src/HttpsOTAUpdate.h +++ b/libraries/Update/src/HttpsOTAUpdate.h @@ -1,5 +1,5 @@ -#ifndef HTPSPOTUADATE_H -#define HTPSPOTUADATE_H +#ifndef HTTPSOTAUPDATE_H +#define HTTPSOTAUPDATE_H #include "esp_http_client.h" #define HttpEvent_t esp_http_client_event_t From 54b1ea2f059e4c92b04d629d4aa120fb4b7e2414 Mon Sep 17 00:00:00 2001 From: rtpmsys <106180646+rtpmsys@users.noreply.github.com> Date: Mon, 6 Feb 2023 14:09:14 +0100 Subject: [PATCH 37/60] Fix error in WiFiClient.cpp where the connect function fails for timeouts below 1 second (#7686) * Update WiFiClient.cpp This change will allow specifying connect timeouts below 1 second. Without this change, if connect timeouts under 1 second are given, the connect defaults to 0ms and fails. This will also allow timeouts in fractions of seconds, e.g. 1500ms. Without this change, connect timeouts are truncated to full second increments. * Make parameter timeout_ms clear * Change connection timeout_ms name for clarity --------- Co-authored-by: Rodrigo Garcia --- libraries/WiFi/src/WiFiClient.cpp | 10 +++++----- libraries/WiFi/src/WiFiClient.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/WiFi/src/WiFiClient.cpp index 6e56e94ac53..9e2a85f5dea 100644 --- a/libraries/WiFi/src/WiFiClient.cpp +++ b/libraries/WiFi/src/WiFiClient.cpp @@ -210,9 +210,9 @@ int WiFiClient::connect(IPAddress ip, uint16_t port) { return connect(ip,port,_timeout); } -int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout) +int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout_ms) { - _timeout = timeout; + _timeout = timeout_ms; int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { log_e("socket: %d", errno); @@ -231,7 +231,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout) FD_ZERO(&fdset); FD_SET(sockfd, &fdset); tv.tv_sec = _timeout / 1000; - tv.tv_usec = 0; + tv.tv_usec = (_timeout % 1000) * 1000; #ifdef ESP_IDF_VERSION_MAJOR int res = lwip_connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); @@ -292,13 +292,13 @@ int WiFiClient::connect(const char *host, uint16_t port) return connect(host,port,_timeout); } -int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout) +int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout_ms) { IPAddress srv((uint32_t)0); if(!WiFiGenericClass::hostByName(host, srv)){ return 0; } - return connect(srv, port, timeout); + return connect(srv, port, timeout_ms); } int WiFiClient::setSocketOption(int option, char* value, size_t len) diff --git a/libraries/WiFi/src/WiFiClient.h b/libraries/WiFi/src/WiFiClient.h index e6e7ecd4b3c..b18f9324209 100644 --- a/libraries/WiFi/src/WiFiClient.h +++ b/libraries/WiFi/src/WiFiClient.h @@ -50,9 +50,9 @@ class WiFiClient : public ESPLwIPClient WiFiClient(int fd); ~WiFiClient(); int connect(IPAddress ip, uint16_t port); - int connect(IPAddress ip, uint16_t port, int32_t timeout); + int connect(IPAddress ip, uint16_t port, int32_t timeout_ms); int connect(const char *host, uint16_t port); - int connect(const char *host, uint16_t port, int32_t timeout); + int connect(const char *host, uint16_t port, int32_t timeout_ms); size_t write(uint8_t data); size_t write(const uint8_t *buf, size_t size); size_t write_P(PGM_P buf, size_t size); From 7942a8bf8acb85ac5f6977314ce5f1e926d96cad Mon Sep 17 00:00:00 2001 From: bytiful <55647551+bytiful@users.noreply.github.com> Date: Mon, 6 Feb 2023 23:09:50 +1000 Subject: [PATCH 38/60] fixed the function header (#7674) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fixed the function header * fixed function name and paramaters --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> --- docs/source/api/sigmadelta.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/api/sigmadelta.rst b/docs/source/api/sigmadelta.rst index d5036a38487..537c5894d6c 100644 --- a/docs/source/api/sigmadelta.rst +++ b/docs/source/api/sigmadelta.rst @@ -28,7 +28,7 @@ This function is used to setup the SigmaDelta channel frequency and resolution. .. code-block:: arduino - double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits); + uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq); * ``pin`` select GPIO pin. * ``channel`` select SigmaDelta channel. From 8dc520a5d135acc58faf8bf2e1cbb0278e54ce5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Piln=C3=BD?= <34927466+PilnyTomas@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:25:58 +0100 Subject: [PATCH 39/60] Ticker fix solving #6155 (#7664) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Wrapped Ticker functions with #pragma disabling -Wcast-function-type * Revert "Wrapped Ticker functions with #pragma disabling -Wcast-function-type" This reverts commit 160be7e67a10d01b6e44c4bf2521c0ccd6348976. * Fixed Ticker example * Modified Ticker example * Fixed LED_BUILTIN err for ESP32 --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> --- .../Ticker/examples/Arguments/Arguments.ino | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/libraries/Ticker/examples/Arguments/Arguments.ino b/libraries/Ticker/examples/Arguments/Arguments.ino index cde8acbfa09..7f5bc5cde21 100644 --- a/libraries/Ticker/examples/Arguments/Arguments.ino +++ b/libraries/Ticker/examples/Arguments/Arguments.ino @@ -1,25 +1,49 @@ +/* + * This example demonstrates used of Ticker with arguments. + * You can call the same callback function with different argument on different times. + * Based on the argument the callback can perform different tasks. + */ + #include #include -// attach a LED to GPIO 21 -#define LED_PIN 21 +// Arguments for the function must remain valid (not run out of scope) otherwise the function would read garbage data. +int LED_PIN_1 = 4; +#ifdef LED_BUILTIN + int LED_PIN_2 = LED_BUILTIN; +#else + int LED_PIN_2 = 8; +#endif Ticker tickerSetHigh; Ticker tickerSetLow; -void setPin(int state) { - digitalWrite(LED_PIN, state); +// Argument to callback must always be passed a reference +void swapState(int *pin) { + static int led_1_state = 1; + static int led_2_state = 1; + if(*pin == LED_PIN_1){ + Serial.printf("[%lu ms] set pin %d to state: %d\n", millis(), *pin, led_1_state); + digitalWrite(*pin, led_1_state); + led_1_state = led_1_state ? 0 : 1; // reverse for next pass + }else if(*pin == LED_PIN_2){ + Serial.printf("[%lu ms] set pin %d to state: %d\n", millis(), *pin, led_2_state); + digitalWrite(*pin, led_2_state); + led_2_state = led_2_state ? 0 : 1; // reverse for next pass + } } void setup() { - pinMode(LED_PIN, OUTPUT); - digitalWrite(1, LOW); + Serial.begin(115200); + pinMode(LED_PIN_1, OUTPUT); + pinMode(LED_PIN_2, OUTPUT); + //digitalWrite(1, LOW); - // every 25 ms, call setPin(0) - tickerSetLow.attach_ms(25, setPin, 0); + // Blink LED every 500 ms on LED_PIN_1 + tickerSetLow.attach_ms(500, swapState, &LED_PIN_1); - // every 26 ms, call setPin(1) - tickerSetHigh.attach_ms(26, setPin, 1); + // Blink LED every 1000 ms on LED_PIN_2 + tickerSetHigh.attach_ms(1000, swapState, &LED_PIN_2); } void loop() { From 51f2e56c555d9f8fac5c9221057c0fdafc3ea827 Mon Sep 17 00:00:00 2001 From: tmfarrington Date: Mon, 6 Feb 2023 12:36:16 -0500 Subject: [PATCH 40/60] setPins fix ESP32 "specified pins are not supported by this chip." (#7646) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ESP32: SDMMCFS::begin hardcodes the usage of slot 1, only check if the pins match slot 1 pins.] setPins() was testing pins D1, D2 and D3 all against D1 ... fine in 1 pin mode when all are -1 not so much if you're trying to get 4 pin mode working. I now see this function doesn't really do anything on the ESP32...accept now correctly checks that you are trying to use the slot 1 pins. Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> --- libraries/SD_MMC/src/SD_MMC.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/SD_MMC/src/SD_MMC.cpp b/libraries/SD_MMC/src/SD_MMC.cpp index fad63dea2d2..b8f0fd0e15f 100644 --- a/libraries/SD_MMC/src/SD_MMC.cpp +++ b/libraries/SD_MMC/src/SD_MMC.cpp @@ -72,8 +72,8 @@ bool SDMMCFS::setPins(int clk, int cmd, int d0, int d1, int d2, int d3) (d0 == (int)SDMMC_SLOT1_IOMUX_PIN_NUM_D0) && (((d1 == -1) && (d2 == -1) && (d3 == -1)) || ((d1 == (int)SDMMC_SLOT1_IOMUX_PIN_NUM_D1) && - (d1 == (int)SDMMC_SLOT1_IOMUX_PIN_NUM_D2) && - (d1 == (int)SDMMC_SLOT1_IOMUX_PIN_NUM_D3))); + (d2 == (int)SDMMC_SLOT1_IOMUX_PIN_NUM_D2) && + (d3 == (int)SDMMC_SLOT1_IOMUX_PIN_NUM_D3))); if (!pins_ok) { log_e("SDMMCFS: specified pins are not supported by this chip."); return false; From a26fce2ce93329e62078cdcd27637c9de1bf47c3 Mon Sep 17 00:00:00 2001 From: Krzysiek S Date: Mon, 6 Feb 2023 20:11:22 +0100 Subject: [PATCH 41/60] Allow passing IP as connect method parameter in WiFiClientSecure and skip unnecessary host-ip conversions (#7643) --- .../WiFiClientSecure/src/WiFiClientSecure.cpp | 20 ++++++++++++++++--- .../WiFiClientSecure/src/WiFiClientSecure.h | 1 + libraries/WiFiClientSecure/src/ssl_client.cpp | 11 +++------- libraries/WiFiClientSecure/src/ssl_client.h | 2 +- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp b/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp index c7ee7e1cf83..1c9ea8d2190 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp +++ b/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp @@ -124,12 +124,21 @@ int WiFiClientSecure::connect(const char *host, uint16_t port, int32_t timeout){ int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) { - return connect(ip.toString().c_str(), port, CA_cert, cert, private_key); + return connect(ip, port, NULL, CA_cert, cert, private_key); } int WiFiClientSecure::connect(const char *host, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) { - int ret = start_ssl_client(sslclient, host, port, _timeout, CA_cert, _use_ca_bundle, cert, private_key, NULL, NULL, _use_insecure, _alpn_protos); + IPAddress address; + if (!WiFi.hostByName(host, address)) + return 0; + + return connect(address, port, host, CA_cert, cert, private_key); +} + +int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *host, const char *CA_cert, const char *cert, const char *private_key) +{ + int ret = start_ssl_client(sslclient, ip, port, host, _timeout, CA_cert, _use_ca_bundle, cert, private_key, NULL, NULL, _use_insecure, _alpn_protos); _lastError = ret; if (ret < 0) { log_e("start_ssl_client: %d", ret); @@ -146,7 +155,12 @@ 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"); - int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, false, NULL, NULL, pskIdent, psKey, _use_insecure, _alpn_protos); + + IPAddress address; + if (!WiFi.hostByName(host, address)) + return 0; + + int ret = start_ssl_client(sslclient, address, port, host, _timeout, NULL, false, NULL, NULL, pskIdent, psKey, _use_insecure, _alpn_protos); _lastError = ret; if (ret < 0) { log_e("start_ssl_client: %d", ret); diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.h b/libraries/WiFiClientSecure/src/WiFiClientSecure.h index 2d49610425d..6c967fbd0e6 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.h +++ b/libraries/WiFiClientSecure/src/WiFiClientSecure.h @@ -55,6 +55,7 @@ class WiFiClientSecure : public WiFiClient int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); int connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey); int connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey); + int connect(IPAddress ip, uint16_t port, const char *host, const char *CA_cert, const char *cert, const char *private_key); int peek(); size_t write(uint8_t data); size_t write(const uint8_t *buf, size_t size); diff --git a/libraries/WiFiClientSecure/src/ssl_client.cpp b/libraries/WiFiClientSecure/src/ssl_client.cpp index c8328eb6280..8dcf05877ba 100644 --- a/libraries/WiFiClientSecure/src/ssl_client.cpp +++ b/libraries/WiFiClientSecure/src/ssl_client.cpp @@ -53,7 +53,7 @@ void ssl_init(sslclient_context *ssl_client) mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx); } -int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, bool useRootCABundle, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure, const char **alpn_protos) +int start_ssl_client(sslclient_context *ssl_client, const IPAddress& ip, uint32_t port, const char* hostname, int timeout, const char *rootCABuff, bool useRootCABundle, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure, const char **alpn_protos) { char buf[512]; int ret, flags; @@ -73,16 +73,11 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p return ssl_client->socket; } - IPAddress srv((uint32_t)0); - if(!WiFiGenericClass::hostByName(host, srv)){ - return -1; - } - fcntl( ssl_client->socket, F_SETFL, fcntl( ssl_client->socket, F_GETFL, 0 ) | O_NONBLOCK ); struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = srv; + serv_addr.sin_addr.s_addr = ip; serv_addr.sin_port = htons(port); if(timeout <= 0){ @@ -261,7 +256,7 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p log_v("Setting hostname for TLS session..."); // Hostname set here should match CN in server certificate - if((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0){ + if((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, hostname != NULL ? hostname : ip.toString().c_str())) != 0){ return handle_error(ret); } diff --git a/libraries/WiFiClientSecure/src/ssl_client.h b/libraries/WiFiClientSecure/src/ssl_client.h index 9690caafddf..69e49707cba 100644 --- a/libraries/WiFiClientSecure/src/ssl_client.h +++ b/libraries/WiFiClientSecure/src/ssl_client.h @@ -30,7 +30,7 @@ typedef struct sslclient_context { void ssl_init(sslclient_context *ssl_client); -int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, bool useRootCABundle, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure, const char **alpn_protos); +int start_ssl_client(sslclient_context *ssl_client, const IPAddress& ip, uint32_t port, const char* hostname, int timeout, const char *rootCABuff, bool useRootCABundle, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure, const char **alpn_protos); void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key); int data_to_read(sslclient_context *ssl_client); int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, size_t len); From d0c014c630d62ffe659f15bff56b06ecccbf1150 Mon Sep 17 00:00:00 2001 From: surt Date: Tue, 7 Feb 2023 05:12:06 +1000 Subject: [PATCH 42/60] Add LED_BUILTIN* definitions and initialization for LEDs to stop them floating. (#7636) Co-authored-by: Rodrigo Garcia --- variants/AirM2M_CORE_ESP32C3/pins_arduino.h | 4 ++++ variants/AirM2M_CORE_ESP32C3/variant.cpp | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 variants/AirM2M_CORE_ESP32C3/variant.cpp diff --git a/variants/AirM2M_CORE_ESP32C3/pins_arduino.h b/variants/AirM2M_CORE_ESP32C3/pins_arduino.h index af061a0eee2..4af6c1d87cd 100644 --- a/variants/AirM2M_CORE_ESP32C3/pins_arduino.h +++ b/variants/AirM2M_CORE_ESP32C3/pins_arduino.h @@ -11,6 +11,10 @@ #define digitalPinToInterrupt(p) (((p) Date: Tue, 7 Feb 2023 06:13:14 +1100 Subject: [PATCH 43/60] Expand path to tinuf2 image when checking existence in platformio-build.py (#7631) * Expand path to tinuf2 image when checking existence * More isFiles fixed --- tools/platformio-build.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/platformio-build.py b/tools/platformio-build.py index b3fa396a489..e3c7b50dbb8 100644 --- a/tools/platformio-build.py +++ b/tools/platformio-build.py @@ -51,19 +51,19 @@ def get_partition_table_csv(variants_dir): if partitions_name: # A custom partitions file is selected - if isfile(join(variant_partitions_dir, partitions_name)): + if isfile(env.subst(join(variant_partitions_dir, partitions_name))): return join(variant_partitions_dir, partitions_name) return abspath( join(fwpartitions_dir, partitions_name) - if isfile(join(fwpartitions_dir, partitions_name)) + if isfile(env.subst(join(fwpartitions_dir, partitions_name))) else partitions_name ) variant_partitions = join(variant_partitions_dir, "partitions.csv") return ( variant_partitions - if isfile(variant_partitions) + if isfile(env.subst(variant_partitions)) else join(fwpartitions_dir, "default.csv") ) @@ -81,7 +81,7 @@ def get_bootloader_image(variants_dir): return ( variant_bootloader - if isfile(variant_bootloader) + if isfile(env.subst(variant_bootloader)) else generate_bootloader_image( join( FRAMEWORK_DIR, @@ -126,8 +126,8 @@ def add_tinyuf2_extra_image(): ) # Add the UF2 image only if it exists and it's not already added - if not isfile(tinuf2_image): - print("Warning! The `%s` UF2 bootloader image doesn't exist" % tinuf2_image) + if not isfile(env.subst(tinuf2_image)): + print("Warning! The `%s` UF2 bootloader image doesn't exist" % env.subst(tinuf2_image)) return if any( From 214680f08275dc011e0eb466dace2474d91673bb Mon Sep 17 00:00:00 2001 From: Clemens Kirchgatterer Date: Mon, 6 Feb 2023 20:13:52 +0100 Subject: [PATCH 44/60] Remove (useless) trailing semicolon from Print.cpp (#7622) --- cores/esp32/Print.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp32/Print.cpp b/cores/esp32/Print.cpp index e5d388ec588..53231e60909 100644 --- a/cores/esp32/Print.cpp +++ b/cores/esp32/Print.cpp @@ -57,7 +57,7 @@ size_t Print::printf(const char *format, ...) if(len < 0) { va_end(arg); return 0; - }; + } if(len >= (int)sizeof(loc_buf)){ // comparation of same sign type for the compiler temp = (char*) malloc(len+1); if(temp == NULL) { From fe9a60cbf51936d08f0a7ca5633cff54c876c336 Mon Sep 17 00:00:00 2001 From: Peter Pan's Techland Date: Tue, 7 Feb 2023 20:25:45 +0800 Subject: [PATCH 45/60] ADD: New variant Edgebox-ESP-100 (#7771) * ADD: New variant Edgebox-ESP-100 * FIX: Edgebox-ESP-100 Board.txt usb mode option change back to default value as ESP32S3 --- boards.txt | 207 ++++++++++++++++++++++++ variants/Edgebox-ESP-100/pins_arduino.h | 67 ++++++++ 2 files changed, 274 insertions(+) create mode 100644 variants/Edgebox-ESP-100/pins_arduino.h diff --git a/boards.txt b/boards.txt index ba4ee1a0316..af10552400a 100644 --- a/boards.txt +++ b/boards.txt @@ -21131,4 +21131,211 @@ VALTRACK_V4_MFW_ESP32_C3.menu.EraseFlash.none.upload.erase_cmd= VALTRACK_V4_MFW_ESP32_C3.menu.EraseFlash.all=Enabled VALTRACK_V4_MFW_ESP32_C3.menu.EraseFlash.all.upload.erase_cmd=-e +############################################################## + +Edgebox-ESP-100.name=Edgebox-ESP-100 + +Edgebox-ESP-100.bootloader.tool=esptool_py +Edgebox-ESP-100.bootloader.tool.default=esptool_py + +Edgebox-ESP-100.upload.tool=esptool_py +Edgebox-ESP-100.upload.tool.default=esptool_py +Edgebox-ESP-100.upload.tool.network=esp_ota + +Edgebox-ESP-100.upload.maximum_size=1310720 +Edgebox-ESP-100.upload.maximum_data_size=327680 +Edgebox-ESP-100.upload.flags= +Edgebox-ESP-100.upload.extra_flags= +Edgebox-ESP-100.upload.use_1200bps_touch=false +Edgebox-ESP-100.upload.wait_for_upload_port=false + +Edgebox-ESP-100.serial.disableDTR=false +Edgebox-ESP-100.serial.disableRTS=false + +Edgebox-ESP-100.build.tarch=xtensa +Edgebox-ESP-100.build.bootloader_addr=0x0 +Edgebox-ESP-100.build.target=esp32s3 +Edgebox-ESP-100.build.mcu=esp32s3 +Edgebox-ESP-100.build.core=esp32 +Edgebox-ESP-100.build.variant=Edgebox-ESP-100 +Edgebox-ESP-100.build.board=Edgebox-ESP-100 + +Edgebox-ESP-100.build.usb_mode=1 +Edgebox-ESP-100.build.cdc_on_boot=0 +Edgebox-ESP-100.build.msc_on_boot=0 +Edgebox-ESP-100.build.dfu_on_boot=0 +Edgebox-ESP-100.build.f_cpu=240000000L +Edgebox-ESP-100.build.flash_size=4MB +Edgebox-ESP-100.build.flash_freq=80m +Edgebox-ESP-100.build.flash_mode=dio +Edgebox-ESP-100.build.boot=qio +Edgebox-ESP-100.build.boot_freq=80m +Edgebox-ESP-100.build.partitions=default +Edgebox-ESP-100.build.defines= +Edgebox-ESP-100.build.loop_core= +Edgebox-ESP-100.build.event_core= +Edgebox-ESP-100.build.psram_type=qspi +Edgebox-ESP-100.build.memory_type={build.boot}_{build.psram_type} + +Edgebox-ESP-100.menu.PSRAM.disabled=Disabled +Edgebox-ESP-100.menu.PSRAM.disabled.build.defines= +Edgebox-ESP-100.menu.PSRAM.disabled.build.psram_type=qspi +Edgebox-ESP-100.menu.PSRAM.enabled=QSPI PSRAM +Edgebox-ESP-100.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM +Edgebox-ESP-100.menu.PSRAM.enabled.build.psram_type=qspi +Edgebox-ESP-100.menu.PSRAM.opi=OPI PSRAM +Edgebox-ESP-100.menu.PSRAM.opi.build.defines=-DBOARD_HAS_PSRAM +Edgebox-ESP-100.menu.PSRAM.opi.build.psram_type=opi + +Edgebox-ESP-100.menu.FlashMode.qio=QIO 80MHz +Edgebox-ESP-100.menu.FlashMode.qio.build.flash_mode=dio +Edgebox-ESP-100.menu.FlashMode.qio.build.boot=qio +Edgebox-ESP-100.menu.FlashMode.qio.build.boot_freq=80m +Edgebox-ESP-100.menu.FlashMode.qio.build.flash_freq=80m +Edgebox-ESP-100.menu.FlashMode.qio120=QIO 120MHz +Edgebox-ESP-100.menu.FlashMode.qio120.build.flash_mode=dio +Edgebox-ESP-100.menu.FlashMode.qio120.build.boot=qio +Edgebox-ESP-100.menu.FlashMode.qio120.build.boot_freq=120m +Edgebox-ESP-100.menu.FlashMode.qio120.build.flash_freq=80m +Edgebox-ESP-100.menu.FlashMode.dio=DIO 80MHz +Edgebox-ESP-100.menu.FlashMode.dio.build.flash_mode=dio +Edgebox-ESP-100.menu.FlashMode.dio.build.boot=dio +Edgebox-ESP-100.menu.FlashMode.dio.build.boot_freq=80m +Edgebox-ESP-100.menu.FlashMode.dio.build.flash_freq=80m +Edgebox-ESP-100.menu.FlashMode.opi=OPI 80MHz +Edgebox-ESP-100.menu.FlashMode.opi.build.flash_mode=dout +Edgebox-ESP-100.menu.FlashMode.opi.build.boot=opi +Edgebox-ESP-100.menu.FlashMode.opi.build.boot_freq=80m +Edgebox-ESP-100.menu.FlashMode.opi.build.flash_freq=80m + +Edgebox-ESP-100.menu.FlashSize.4M=4MB (32Mb) +Edgebox-ESP-100.menu.FlashSize.4M.build.flash_size=4MB +Edgebox-ESP-100.menu.FlashSize.8M=8MB (64Mb) +Edgebox-ESP-100.menu.FlashSize.8M.build.flash_size=8MB +Edgebox-ESP-100.menu.FlashSize.8M.build.partitions=default_8MB +Edgebox-ESP-100.menu.FlashSize.16M=16MB (128Mb) +Edgebox-ESP-100.menu.FlashSize.16M.build.flash_size=16MB +#Edgebox-ESP-100.menu.FlashSize.32M=32MB (256Mb) +#Edgebox-ESP-100.menu.FlashSize.32M.build.flash_size=32MB + +Edgebox-ESP-100.menu.LoopCore.1=Core 1 +Edgebox-ESP-100.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +Edgebox-ESP-100.menu.LoopCore.0=Core 0 +Edgebox-ESP-100.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +Edgebox-ESP-100.menu.EventsCore.1=Core 1 +Edgebox-ESP-100.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +Edgebox-ESP-100.menu.EventsCore.0=Core 0 +Edgebox-ESP-100.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +Edgebox-ESP-100.menu.USBMode.default=Hardware CDC and JTAG +Edgebox-ESP-100.menu.USBMode.default.build.usb_mode=1 +Edgebox-ESP-100.menu.USBMode.hwcdc=USB-OTG (TinyUSB) +Edgebox-ESP-100.menu.USBMode.hwcdc.build.usb_mode=0 + +Edgebox-ESP-100.menu.CDCOnBoot.default=Disabled +Edgebox-ESP-100.menu.CDCOnBoot.default.build.cdc_on_boot=0 +Edgebox-ESP-100.menu.CDCOnBoot.cdc=Enabled +Edgebox-ESP-100.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 + +Edgebox-ESP-100.menu.MSCOnBoot.default=Disabled +Edgebox-ESP-100.menu.MSCOnBoot.default.build.msc_on_boot=0 +Edgebox-ESP-100.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +Edgebox-ESP-100.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +Edgebox-ESP-100.menu.DFUOnBoot.default=Disabled +Edgebox-ESP-100.menu.DFUOnBoot.default.build.dfu_on_boot=0 +Edgebox-ESP-100.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +Edgebox-ESP-100.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +Edgebox-ESP-100.menu.UploadMode.default=UART0 / Hardware CDC +Edgebox-ESP-100.menu.UploadMode.default.upload.use_1200bps_touch=false +Edgebox-ESP-100.menu.UploadMode.default.upload.wait_for_upload_port=false +Edgebox-ESP-100.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +Edgebox-ESP-100.menu.UploadMode.cdc.upload.use_1200bps_touch=true +Edgebox-ESP-100.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +Edgebox-ESP-100.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +Edgebox-ESP-100.menu.PartitionScheme.default.build.partitions=default +Edgebox-ESP-100.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +Edgebox-ESP-100.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +Edgebox-ESP-100.menu.PartitionScheme.default_8MB=8M with spiffs (3MB APP/1.5MB SPIFFS) +Edgebox-ESP-100.menu.PartitionScheme.default_8MB.build.partitions=default_8MB +Edgebox-ESP-100.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336 +Edgebox-ESP-100.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +Edgebox-ESP-100.menu.PartitionScheme.minimal.build.partitions=minimal +Edgebox-ESP-100.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +Edgebox-ESP-100.menu.PartitionScheme.no_ota.build.partitions=no_ota +Edgebox-ESP-100.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +Edgebox-ESP-100.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +Edgebox-ESP-100.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +Edgebox-ESP-100.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +Edgebox-ESP-100.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +Edgebox-ESP-100.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +Edgebox-ESP-100.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +Edgebox-ESP-100.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +Edgebox-ESP-100.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +Edgebox-ESP-100.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +Edgebox-ESP-100.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +Edgebox-ESP-100.menu.PartitionScheme.huge_app.build.partitions=huge_app +Edgebox-ESP-100.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +Edgebox-ESP-100.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +Edgebox-ESP-100.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +Edgebox-ESP-100.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +Edgebox-ESP-100.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FATFS) +Edgebox-ESP-100.menu.PartitionScheme.fatflash.build.partitions=ffat +Edgebox-ESP-100.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 +Edgebox-ESP-100.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9.9MB FATFS) +Edgebox-ESP-100.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB +Edgebox-ESP-100.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +Edgebox-ESP-100.menu.PartitionScheme.rainmaker=RainMaker +Edgebox-ESP-100.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +Edgebox-ESP-100.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 + +Edgebox-ESP-100.menu.CPUFreq.240=240MHz (WiFi) +Edgebox-ESP-100.menu.CPUFreq.240.build.f_cpu=240000000L +Edgebox-ESP-100.menu.CPUFreq.160=160MHz (WiFi) +Edgebox-ESP-100.menu.CPUFreq.160.build.f_cpu=160000000L +Edgebox-ESP-100.menu.CPUFreq.80=80MHz (WiFi) +Edgebox-ESP-100.menu.CPUFreq.80.build.f_cpu=80000000L +Edgebox-ESP-100.menu.CPUFreq.40=40MHz +Edgebox-ESP-100.menu.CPUFreq.40.build.f_cpu=40000000L +Edgebox-ESP-100.menu.CPUFreq.20=20MHz +Edgebox-ESP-100.menu.CPUFreq.20.build.f_cpu=20000000L +Edgebox-ESP-100.menu.CPUFreq.10=10MHz +Edgebox-ESP-100.menu.CPUFreq.10.build.f_cpu=10000000L + +Edgebox-ESP-100.menu.UploadSpeed.921600=921600 +Edgebox-ESP-100.menu.UploadSpeed.921600.upload.speed=921600 +Edgebox-ESP-100.menu.UploadSpeed.115200=115200 +Edgebox-ESP-100.menu.UploadSpeed.115200.upload.speed=115200 +Edgebox-ESP-100.menu.UploadSpeed.256000.windows=256000 +Edgebox-ESP-100.menu.UploadSpeed.256000.upload.speed=256000 +Edgebox-ESP-100.menu.UploadSpeed.230400.windows.upload.speed=256000 +Edgebox-ESP-100.menu.UploadSpeed.230400=230400 +Edgebox-ESP-100.menu.UploadSpeed.230400.upload.speed=230400 +Edgebox-ESP-100.menu.UploadSpeed.460800.linux=460800 +Edgebox-ESP-100.menu.UploadSpeed.460800.macosx=460800 +Edgebox-ESP-100.menu.UploadSpeed.460800.upload.speed=460800 +Edgebox-ESP-100.menu.UploadSpeed.512000.windows=512000 +Edgebox-ESP-100.menu.UploadSpeed.512000.upload.speed=512000 + +Edgebox-ESP-100.menu.DebugLevel.none=None +Edgebox-ESP-100.menu.DebugLevel.none.build.code_debug=0 +Edgebox-ESP-100.menu.DebugLevel.error=Error +Edgebox-ESP-100.menu.DebugLevel.error.build.code_debug=1 +Edgebox-ESP-100.menu.DebugLevel.warn=Warn +Edgebox-ESP-100.menu.DebugLevel.warn.build.code_debug=2 +Edgebox-ESP-100.menu.DebugLevel.info=Info +Edgebox-ESP-100.menu.DebugLevel.info.build.code_debug=3 +Edgebox-ESP-100.menu.DebugLevel.debug=Debug +Edgebox-ESP-100.menu.DebugLevel.debug.build.code_debug=4 +Edgebox-ESP-100.menu.DebugLevel.verbose=Verbose +Edgebox-ESP-100.menu.DebugLevel.verbose.build.code_debug=5 + +Edgebox-ESP-100.menu.EraseFlash.none=Disabled +Edgebox-ESP-100.menu.EraseFlash.none.upload.erase_cmd= +Edgebox-ESP-100.menu.EraseFlash.all=Enabled +Edgebox-ESP-100.menu.EraseFlash.all.upload.erase_cmd=-e + ############################################################## \ No newline at end of file diff --git a/variants/Edgebox-ESP-100/pins_arduino.h b/variants/Edgebox-ESP-100/pins_arduino.h new file mode 100644 index 00000000000..ae212f44dea --- /dev/null +++ b/variants/Edgebox-ESP-100/pins_arduino.h @@ -0,0 +1,67 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define EXTERNAL_NUM_INTERRUPTS 34 +#define NUM_DIGITAL_PINS 34 +#define NUM_ANALOG_INPUTS 2 + +#define analogInputToDigitalPin(p) (((p)<2)?(analogChannelToDigitalPin(p)):-1) +#define digitalPinToInterrupt(p) (((p)<34)?(p):-1) +#define digitalPinHasPWM(p) (p < 34) + +//Programming and Debugging Port +static const uint8_t TXD = 43; +static const uint8_t RXD = 44; +static const uint8_t RST = 0; + +//I2C +static const uint8_t SDA = 20; +static const uint8_t SCL = 19; + +//I2C INT fro RTC PCF8563 +static const uint8_t I2C_INT = 9; + +//SPI BUS for W5500 Ethernet Port Driver +static const uint8_t SS = 10; +static const uint8_t MOSI = 12; +static const uint8_t MISO = 11; +static const uint8_t SCK = 13; +static const uint8_t ETH_INT = 14; +static const uint8_t ETH_RST = 15; + +//A7670G +static const uint8_t LTE_PWR_EN = 16; +static const uint8_t LTE_PWR_KEY = 21; +static const uint8_t LTE_TXD = 48; +static const uint8_t LTE_RXD = 47; + +//RS485 +static const uint8_t RS485_TXD = 17; +static const uint8_t RS485_RXD = 18; +static const uint8_t RS485_RTS = 8; + +//CAN BUS +static const uint8_t CAN_TXD = 1; +static const uint8_t CAN_RXD = 2; + +//BUZZER +static const uint8_t BUZZER = 45; + +static const uint8_t DO0 = 40; +static const uint8_t DO1 = 39; +static const uint8_t DO2 = 38; +static const uint8_t DO3 = 37; +static const uint8_t DO4 = 36; +static const uint8_t DO5 = 35; + +static const uint8_t DI0 = 4; +static const uint8_t DI1 = 5; +static const uint8_t DI2 = 6; +static const uint8_t DI3 = 7; + +static const uint8_t AO0 = 42; +static const uint8_t AO1 = 41; + +#endif /* Pins_Arduino_h */ \ No newline at end of file From 401fda093fa586d058405daf9c2c67264073ba51 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 7 Feb 2023 19:50:01 +0500 Subject: [PATCH 46/60] Add Crabik Slot ESP32-S3 board (#7790) * Added Crabik Slot ESP32-S3 * Adding CPU frequency settings and removing excess from partition scheme settings --- boards.txt | 148 +++++++++++++++++++ variants/crabik_slot_esp32_s3/pins_arduino.h | 88 +++++++++++ 2 files changed, 236 insertions(+) create mode 100644 variants/crabik_slot_esp32_s3/pins_arduino.h diff --git a/boards.txt b/boards.txt index af10552400a..ccb69716a00 100644 --- a/boards.txt +++ b/boards.txt @@ -21338,4 +21338,152 @@ Edgebox-ESP-100.menu.EraseFlash.none.upload.erase_cmd= Edgebox-ESP-100.menu.EraseFlash.all=Enabled Edgebox-ESP-100.menu.EraseFlash.all.upload.erase_cmd=-e +############################################################## + +crabik_slot_esp32_s3.name=Crabik Slot ESP32-S3 +crabik_slot_esp32_s3.vid.0=0x303a +crabik_slot_esp32_s3.pid.0=0x1001 + +crabik_slot_esp32_s3.bootloader.tool=esptool_py +crabik_slot_esp32_s3.bootloader.tool.default=esptool_py + +crabik_slot_esp32_s3.upload.tool=esptool_py +crabik_slot_esp32_s3.upload.tool.default=esptool_py +crabik_slot_esp32_s3.upload.tool.network=esp_ota + +crabik_slot_esp32_s3.upload.maximum_size=1310720 +crabik_slot_esp32_s3.upload.maximum_data_size=327680 +crabik_slot_esp32_s3.upload.speed=921600 +crabik_slot_esp32_s3.upload.flags= +crabik_slot_esp32_s3.upload.extra_flags= +crabik_slot_esp32_s3.upload.use_1200bps_touch=false +crabik_slot_esp32_s3.upload.wait_for_upload_port=false + +crabik_slot_esp32_s3.serial.disableDTR=false +crabik_slot_esp32_s3.serial.disableRTS=false + +crabik_slot_esp32_s3.build.tarch=xtensa +crabik_slot_esp32_s3.build.bootloader_addr=0x0 +crabik_slot_esp32_s3.build.target=esp32s3 +crabik_slot_esp32_s3.build.mcu=esp32s3 +crabik_slot_esp32_s3.build.core=esp32 +crabik_slot_esp32_s3.build.variant=crabik_slot_esp32_s3 +crabik_slot_esp32_s3.build.board=CRABIK_SLOT_ESP32_S3 + +crabik_slot_esp32_s3.build.usb_mode=0 +crabik_slot_esp32_s3.build.cdc_on_boot=0 +crabik_slot_esp32_s3.build.msc_on_boot=0 +crabik_slot_esp32_s3.build.dfu_on_boot=0 +crabik_slot_esp32_s3.build.f_cpu=240000000L +crabik_slot_esp32_s3.build.flash_size=8MB +crabik_slot_esp32_s3.build.flash_freq=80m +crabik_slot_esp32_s3.build.flash_mode=dio +crabik_slot_esp32_s3.build.boot=qio +crabik_slot_esp32_s3.build.partitions=default +crabik_slot_esp32_s3.build.defines= +crabik_slot_esp32_s3.build.memory_type=qio_qspi +crabik_slot_esp32_s3.build.loop_core= +crabik_slot_esp32_s3.build.event_core= + +## IDE 2.0 Seems to not update the value +crabik_slot_esp32_s3.menu.JTAGAdapter.default=Disabled +crabik_slot_esp32_s3.menu.JTAGAdapter.default.build.copy_jtag_files=0 +crabik_slot_esp32_s3.menu.JTAGAdapter.builtin=Integrated USB JTAG +crabik_slot_esp32_s3.menu.JTAGAdapter.builtin.build.openocdscript=esp32s3-builtin.cfg +crabik_slot_esp32_s3.menu.JTAGAdapter.builtin.build.copy_jtag_files=1 + +crabik_slot_esp32_s3.menu.LoopCore.1=Core 1 +crabik_slot_esp32_s3.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +crabik_slot_esp32_s3.menu.LoopCore.0=Core 0 +crabik_slot_esp32_s3.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +crabik_slot_esp32_s3.menu.EventsCore.1=Core 1 +crabik_slot_esp32_s3.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +crabik_slot_esp32_s3.menu.EventsCore.0=Core 0 +crabik_slot_esp32_s3.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +crabik_slot_esp32_s3.menu.CDCOnBoot.default=Enabled (Requires Hardware CDC and JTAG Mode) +crabik_slot_esp32_s3.menu.CDCOnBoot.default.build.cdc_on_boot=1 +crabik_slot_esp32_s3.menu.CDCOnBoot.discdc=Disabled +crabik_slot_esp32_s3.menu.CDCOnBoot.discdc.build.cdc_on_boot=0 + +crabik_slot_esp32_s3.menu.MSCOnBoot.default=Disabled +crabik_slot_esp32_s3.menu.MSCOnBoot.default.build.msc_on_boot=0 +crabik_slot_esp32_s3.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +crabik_slot_esp32_s3.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +crabik_slot_esp32_s3.menu.USBMode.default=Hardware CDC and JTAG +crabik_slot_esp32_s3.menu.USBMode.default.build.usb_mode=1 +crabik_slot_esp32_s3.menu.USBMode.default.build.cdc_on_boot=1 +crabik_slot_esp32_s3.menu.USBMode.usbotg=USB-OTG +crabik_slot_esp32_s3.menu.USBMode.usbotg.build.usb_mode=0 +crabik_slot_esp32_s3.menu.USBMode.usbotg.build.cdc_on_boot=0 + +crabik_slot_esp32_s3.menu.UploadMode.default=UART0 / Hardware CDC +crabik_slot_esp32_s3.menu.UploadMode.default.upload.use_1200bps_touch=false +crabik_slot_esp32_s3.menu.UploadMode.default.upload.wait_for_upload_port=false +crabik_slot_esp32_s3.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +crabik_slot_esp32_s3.menu.UploadMode.cdc.upload.use_1200bps_touch=true +crabik_slot_esp32_s3.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +crabik_slot_esp32_s3.menu.CPUFreq.240=240MHz (WiFi) +crabik_slot_esp32_s3.menu.CPUFreq.240.build.f_cpu=240000000L +crabik_slot_esp32_s3.menu.CPUFreq.160=160MHz (WiFi) +crabik_slot_esp32_s3.menu.CPUFreq.160.build.f_cpu=160000000L +crabik_slot_esp32_s3.menu.CPUFreq.80=80MHz (WiFi) +crabik_slot_esp32_s3.menu.CPUFreq.80.build.f_cpu=80000000L + +crabik_slot_esp32_s3.menu.PartitionScheme.default=8M Flash (3MB APP/1.5MB FATFS) +crabik_slot_esp32_s3.menu.PartitionScheme.default.build.partitions=default_8MB +crabik_slot_esp32_s3.menu.PartitionScheme.default.upload.maximum_size=3342336 +crabik_slot_esp32_s3.menu.PartitionScheme.default_4MB=4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +crabik_slot_esp32_s3.menu.PartitionScheme.default_4MB.build.partitions=default +crabik_slot_esp32_s3.menu.PartitionScheme.defaultffat=4MB with ffat (1.2MB APP/1.5MB FATFS) +crabik_slot_esp32_s3.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +crabik_slot_esp32_s3.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +crabik_slot_esp32_s3.menu.PartitionScheme.no_ota.build.partitions=no_ota +crabik_slot_esp32_s3.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +crabik_slot_esp32_s3.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +crabik_slot_esp32_s3.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +crabik_slot_esp32_s3.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +crabik_slot_esp32_s3.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +crabik_slot_esp32_s3.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +crabik_slot_esp32_s3.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +crabik_slot_esp32_s3.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +crabik_slot_esp32_s3.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +crabik_slot_esp32_s3.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 + +crabik_slot_esp32_s3.menu.UploadSpeed.921600=921600 +crabik_slot_esp32_s3.menu.UploadSpeed.921600.upload.speed=921600 +crabik_slot_esp32_s3.menu.UploadSpeed.115200=115200 +crabik_slot_esp32_s3.menu.UploadSpeed.115200.upload.speed=115200 +crabik_slot_esp32_s3.menu.UploadSpeed.256000.windows=256000 +crabik_slot_esp32_s3.menu.UploadSpeed.256000.upload.speed=256000 +crabik_slot_esp32_s3.menu.UploadSpeed.230400.windows.upload.speed=256000 +crabik_slot_esp32_s3.menu.UploadSpeed.230400=230400 +crabik_slot_esp32_s3.menu.UploadSpeed.230400.upload.speed=230400 +crabik_slot_esp32_s3.menu.UploadSpeed.460800.linux=460800 +crabik_slot_esp32_s3.menu.UploadSpeed.460800.macosx=460800 +crabik_slot_esp32_s3.menu.UploadSpeed.460800.upload.speed=460800 +crabik_slot_esp32_s3.menu.UploadSpeed.512000.windows=512000 +crabik_slot_esp32_s3.menu.UploadSpeed.512000.upload.speed=512000 + +crabik_slot_esp32_s3.menu.DebugLevel.none=None +crabik_slot_esp32_s3.menu.DebugLevel.none.build.code_debug=0 +crabik_slot_esp32_s3.menu.DebugLevel.error=Error +crabik_slot_esp32_s3.menu.DebugLevel.error.build.code_debug=1 +crabik_slot_esp32_s3.menu.DebugLevel.warn=Warn +crabik_slot_esp32_s3.menu.DebugLevel.warn.build.code_debug=2 +crabik_slot_esp32_s3.menu.DebugLevel.info=Info +crabik_slot_esp32_s3.menu.DebugLevel.info.build.code_debug=3 +crabik_slot_esp32_s3.menu.DebugLevel.debug=Debug +crabik_slot_esp32_s3.menu.DebugLevel.debug.build.code_debug=4 +crabik_slot_esp32_s3.menu.DebugLevel.verbose=Verbose +crabik_slot_esp32_s3.menu.DebugLevel.verbose.build.code_debug=5 + +crabik_slot_esp32_s3.menu.EraseFlash.none=Disabled +crabik_slot_esp32_s3.menu.EraseFlash.none.upload.erase_cmd= +crabik_slot_esp32_s3.menu.EraseFlash.all=Enabled +crabik_slot_esp32_s3.menu.EraseFlash.all.upload.erase_cmd=-e + ############################################################## \ No newline at end of file diff --git a/variants/crabik_slot_esp32_s3/pins_arduino.h b/variants/crabik_slot_esp32_s3/pins_arduino.h new file mode 100644 index 00000000000..31aa9ee79cb --- /dev/null +++ b/variants/crabik_slot_esp32_s3/pins_arduino.h @@ -0,0 +1,88 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_VID 0x303a +#define USB_PID 0x814D // for user apps (https://github.com/espressif/usb-pids/pull/77) +#define USB_MANUFACTURER "Crabik" +#define USB_PRODUCT "Slot ESP32-S3" +#define USB_SERIAL "" + +#define EXTERNAL_NUM_INTERRUPTS 46 +#define NUM_DIGITAL_PINS 48 +#define NUM_ANALOG_INPUTS 20 + +#define analogInputToDigitalPin(p) (((p)<20)?(analogChannelToDigitalPin(p)):-1) +#define digitalPinToInterrupt(p) (((p)<48)?(p):-1) +#define digitalPinHasPWM(p) (p < 46) + +static const uint8_t LED_BUILTIN = 21; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN + +static const uint8_t S1 = 1; +static const uint8_t S2 = 12; +static const uint8_t S3 = 2; +static const uint8_t S4 = 11; +static const uint8_t S5 = 17; +static const uint8_t S6 = 18; +static const uint8_t S7 = 3; +static const uint8_t S8 = 4; +static const uint8_t S9 = 5; +static const uint8_t S10 = 6; +static const uint8_t S11 = 7; +static const uint8_t S12 = 8; +static const uint8_t S13 = 9; +static const uint8_t S14 = 10; +static const uint8_t S15 = 45; +static const uint8_t S16 = 46; +static const uint8_t S17 = 48; +static const uint8_t S18 = 47; +static const uint8_t S19 = 33; +static const uint8_t S20 = 34; + +static const uint8_t TX = S12; +static const uint8_t RX = S11; +#define TX1 TX +#define RX1 RX + +static const uint8_t SDA = 13; +static const uint8_t SCL = 14; +static const uint8_t D = SDA; +static const uint8_t C = SCL; + +static const uint8_t MOSI = 35; +static const uint8_t MISO = 37; +static const uint8_t SCK = 36; +static const uint8_t DO = MOSI; +static const uint8_t DI = MISO; +static const uint8_t CLK = SCK; +static const uint8_t CS1 = S5; +static const uint8_t CS2 = S6; +static const uint8_t SS = CS1; + +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 USB_DN = 19; +static const uint8_t USB_DP = 20; + +static const uint8_t BOOT_BTN = 0; +static const uint8_t USER_LED = LED_BUILTIN; + +static const uint8_t EN_TROYKA = 15; + +static const uint8_t LIPO_ALERT = 16; + +#endif /* Pins_Arduino_h */ From 5ab7d6d7e8061cc0283a3e0150176be0cfd55bd9 Mon Sep 17 00:00:00 2001 From: Eistee Date: Tue, 7 Feb 2023 15:50:42 +0100 Subject: [PATCH 47/60] new variant LilyGO T-Display-S3 (#7763) * new variant LilyGO T-Display-S3 https://github.com/Xinyuan-LilyGO/T-Display-S3 * Add boards.txt definition --------- Co-authored-by: Me No Dev --- boards.txt | 118 ++++++++++++++++++++ variants/lilygo_t_display_s3/pins_arduino.h | 92 +++++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 variants/lilygo_t_display_s3/pins_arduino.h diff --git a/boards.txt b/boards.txt index ccb69716a00..791c0d8e349 100644 --- a/boards.txt +++ b/boards.txt @@ -2934,6 +2934,124 @@ S_ODI_Ultra.menu.EraseFlash.all.upload.erase_cmd=-e ############################################################## +lilygo_t_display_s3.name=LilyGo T-Display-S3 +lilygo_t_display_s3.vid.0=0x303a +lilygo_t_display_s3.pid.0=0x1001 + +lilygo_t_display_s3.bootloader.tool=esptool_py +lilygo_t_display_s3.bootloader.tool.default=esptool_py + +lilygo_t_display_s3.upload.tool=esptool_py +lilygo_t_display_s3.upload.tool.default=esptool_py +lilygo_t_display_s3.upload.tool.network=esp_ota + +lilygo_t_display_s3.upload.maximum_size=3145728 +lilygo_t_display_s3.upload.maximum_data_size=327680 +lilygo_t_display_s3.upload.speed=921600 +lilygo_t_display_s3.upload.flags= +lilygo_t_display_s3.upload.extra_flags= +lilygo_t_display_s3.upload.use_1200bps_touch=false +lilygo_t_display_s3.upload.wait_for_upload_port=false + +lilygo_t_display_s3.serial.disableDTR=false +lilygo_t_display_s3.serial.disableRTS=false + +lilygo_t_display_s3.build.tarch=xtensa +lilygo_t_display_s3.build.bootloader_addr=0x0 +lilygo_t_display_s3.build.target=esp32s3 +lilygo_t_display_s3.build.mcu=esp32s3 +lilygo_t_display_s3.build.core=esp32 +lilygo_t_display_s3.build.variant=lilygo_t_display_s3 +lilygo_t_display_s3.build.board=LILYGO_T_DISPLAY_S3 + +lilygo_t_display_s3.build.usb_mode=1 +lilygo_t_display_s3.build.cdc_on_boot=1 +lilygo_t_display_s3.build.msc_on_boot=0 +lilygo_t_display_s3.build.dfu_on_boot=0 +lilygo_t_display_s3.build.f_cpu=240000000L +lilygo_t_display_s3.build.flash_size=16MB +lilygo_t_display_s3.build.flash_freq=80m +lilygo_t_display_s3.build.flash_mode=dio +lilygo_t_display_s3.build.boot=qio +lilygo_t_display_s3.build.boot_freq=80m +lilygo_t_display_s3.build.partitions=app3M_fat9M_16MB +lilygo_t_display_s3.build.defines= +lilygo_t_display_s3.build.loop_core= +lilygo_t_display_s3.build.event_core= +lilygo_t_display_s3.build.psram_type=opi +lilygo_t_display_s3.build.memory_type={build.boot}_{build.psram_type} + +## IDE 2.0 Seems to not update the value +lilygo_t_display_s3.menu.JTAGAdapter.default=Disabled +lilygo_t_display_s3.menu.JTAGAdapter.default.build.copy_jtag_files=0 +lilygo_t_display_s3.menu.JTAGAdapter.builtin=Integrated USB JTAG +lilygo_t_display_s3.menu.JTAGAdapter.builtin.build.openocdscript=esp32s3-builtin.cfg +lilygo_t_display_s3.menu.JTAGAdapter.builtin.build.copy_jtag_files=1 + +lilygo_t_display_s3.menu.LoopCore.1=Core 1 +lilygo_t_display_s3.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +lilygo_t_display_s3.menu.LoopCore.0=Core 0 +lilygo_t_display_s3.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +lilygo_t_display_s3.menu.EventsCore.1=Core 1 +lilygo_t_display_s3.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +lilygo_t_display_s3.menu.EventsCore.0=Core 0 +lilygo_t_display_s3.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +lilygo_t_display_s3.menu.USBMode.hwcdc=Hardware CDC and JTAG +lilygo_t_display_s3.menu.USBMode.hwcdc.build.usb_mode=1 +lilygo_t_display_s3.menu.USBMode.default=USB-OTG (TinyUSB) +lilygo_t_display_s3.menu.USBMode.default.build.usb_mode=0 + +lilygo_t_display_s3.menu.CDCOnBoot.cdc=Enabled +lilygo_t_display_s3.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 +lilygo_t_display_s3.menu.CDCOnBoot.default=Disabled +lilygo_t_display_s3.menu.CDCOnBoot.default.build.cdc_on_boot=0 + +lilygo_t_display_s3.menu.MSCOnBoot.default=Disabled +lilygo_t_display_s3.menu.MSCOnBoot.default.build.msc_on_boot=0 +lilygo_t_display_s3.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +lilygo_t_display_s3.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +lilygo_t_display_s3.menu.DFUOnBoot.default=Disabled +lilygo_t_display_s3.menu.DFUOnBoot.default.build.dfu_on_boot=0 +lilygo_t_display_s3.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +lilygo_t_display_s3.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +lilygo_t_display_s3.menu.UploadMode.default=UART0 / Hardware CDC +lilygo_t_display_s3.menu.UploadMode.default.upload.use_1200bps_touch=false +lilygo_t_display_s3.menu.UploadMode.default.upload.wait_for_upload_port=false +lilygo_t_display_s3.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +lilygo_t_display_s3.menu.UploadMode.cdc.upload.use_1200bps_touch=true +lilygo_t_display_s3.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +lilygo_t_display_s3.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9.9MB FATFS) +lilygo_t_display_s3.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB +lilygo_t_display_s3.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +lilygo_t_display_s3.menu.PartitionScheme.rainmaker=RainMaker +lilygo_t_display_s3.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +lilygo_t_display_s3.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 + +lilygo_t_display_s3.menu.DebugLevel.none=None +lilygo_t_display_s3.menu.DebugLevel.none.build.code_debug=0 +lilygo_t_display_s3.menu.DebugLevel.error=Error +lilygo_t_display_s3.menu.DebugLevel.error.build.code_debug=1 +lilygo_t_display_s3.menu.DebugLevel.warn=Warn +lilygo_t_display_s3.menu.DebugLevel.warn.build.code_debug=2 +lilygo_t_display_s3.menu.DebugLevel.info=Info +lilygo_t_display_s3.menu.DebugLevel.info.build.code_debug=3 +lilygo_t_display_s3.menu.DebugLevel.debug=Debug +lilygo_t_display_s3.menu.DebugLevel.debug.build.code_debug=4 +lilygo_t_display_s3.menu.DebugLevel.verbose=Verbose +lilygo_t_display_s3.menu.DebugLevel.verbose.build.code_debug=5 + +lilygo_t_display_s3.menu.EraseFlash.none=Disabled +lilygo_t_display_s3.menu.EraseFlash.none.upload.erase_cmd= +lilygo_t_display_s3.menu.EraseFlash.all=Enabled +lilygo_t_display_s3.menu.EraseFlash.all.upload.erase_cmd=-e + +############################################################## + micros2.name=microS2 micros2.vid.0=0x239A micros2.pid.0=0x80C5 diff --git a/variants/lilygo_t_display_s3/pins_arduino.h b/variants/lilygo_t_display_s3/pins_arduino.h new file mode 100644 index 00000000000..099bdad5876 --- /dev/null +++ b/variants/lilygo_t_display_s3/pins_arduino.h @@ -0,0 +1,92 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include +#include "soc/soc_caps.h" + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +#define EXTERNAL_NUM_INTERRUPTS 46 +#define NUM_DIGITAL_PINS 48 +#define NUM_ANALOG_INPUTS 20 + +#define analogInputToDigitalPin(p) (((p)<20)?(analogChannelToDigitalPin(p)):-1) +#define digitalPinToInterrupt(p) (((p)<48)?(p):-1) +#define digitalPinHasPWM(p) (p < 46) + +static const uint8_t BUTTON_1 = 0; +static const uint8_t BUTTON_2 = 14; +static const uint8_t BAT_VOLT = 4; + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +static const uint8_t SDA = 18; +static const uint8_t SCL = 17; + +static const uint8_t SS = 10; +static const uint8_t MOSI = 11; +static const uint8_t MISO = 13; +static const uint8_t SCK = 12; + +static const uint8_t TP_RESET = 21; +static const uint8_t TP_INIT = 16; + +// ST7789 IPS TFT 170x320 +static const uint8_t LCD_BL = 38; +static const uint8_t LCD_D0 = 39; +static const uint8_t LCD_D1 = 40; +static const uint8_t LCD_D2 = 41; +static const uint8_t LCD_D3 = 42; +static const uint8_t LCD_D4 = 45; +static const uint8_t LCD_D5 = 46; +static const uint8_t LCD_D6 = 47; +static const uint8_t LCD_D7 = 48; +static const uint8_t LCD_WR = 8; +static const uint8_t LCD_RD = 9; +static const uint8_t LCD_DC = 7; +static const uint8_t LCD_CS = 6; +static const uint8_t LCD_RES = 5; +static const uint8_t LCD_POWER_ON = 15; + +// P1 +static const uint8_t PIN_43 = 43; +static const uint8_t PIN_44 = 44; +static const uint8_t PIN_18 = 18; +static const uint8_t PIN_17 = 17; +static const uint8_t PIN_21 = 21; +static const uint8_t PIN_16 = 16; + +// P2 +static const uint8_t PIN_1 = 1; +static const uint8_t PIN_2 = 2; +static const uint8_t PIN_3 = 3; +static const uint8_t PIN_10 = 10; +static const uint8_t PIN_11 = 11; +static const uint8_t PIN_12 = 12; +static const uint8_t PIN_13 = 13; + +// Analog +static const uint8_t A0 = 1; +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +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 A15 = 16; +static const uint8_t A16 = 17; +static const uint8_t A17 = 18; + + +// Touch +static const uint8_t T1 = 1; +static const uint8_t T2 = 2; +static const uint8_t T3 = 3; +static const uint8_t T10 = 10; +static const uint8_t T11 = 11; +static const uint8_t T12 = 12; +static const uint8_t T13 = 13; + +#endif /* Pins_Arduino_h */ From 94c779b3836df5c55c85186ad5e97e5af134c6fc Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 8 Feb 2023 17:02:45 +0200 Subject: [PATCH 48/60] Update get.py to support Apple ARM64 --- tools/get.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/tools/get.py b/tools/get.py index 8836e4cc6cc..16e1e097b2a 100755 --- a/tools/get.py +++ b/tools/get.py @@ -181,20 +181,34 @@ def load_tools_list(filename, platform): for t in tools_info: tool_platform = [p for p in t['systems'] if p['host'] == platform] if len(tool_platform) == 0: - continue + # Fallback to x86 on Apple ARM + if platform == 'arm64-apple-darwin': + tool_platform = [p for p in t['systems'] if p['host'] == 'x86_64-apple-darwin'] + if len(tool_platform) == 0: + continue + # Fallback to 32bit on 64bit x86 Windows + elif platform == 'x86_64-mingw32': + tool_platform = [p for p in t['systems'] if p['host'] == 'i686-mingw32'] + if len(tool_platform) == 0: + continue + else: + continue tools_to_download.append(tool_platform[0]) return tools_to_download def identify_platform(): - arduino_platform_names = {'Darwin' : {32 : 'i386-apple-darwin', 64 : 'x86_64-apple-darwin'}, - 'Linux' : {32 : 'i686-pc-linux-gnu', 64 : 'x86_64-pc-linux-gnu'}, - 'LinuxARM': {32 : 'arm-linux-gnueabihf', 64 : 'aarch64-linux-gnu'}, - 'Windows' : {32 : 'i686-mingw32', 64 : 'i686-mingw32'}} + arduino_platform_names = {'Darwin' : {32 : 'i386-apple-darwin', 64 : 'x86_64-apple-darwin'}, + 'DarwinARM': {32 : 'arm64-apple-darwin', 64 : 'arm64-apple-darwin'}, + 'Linux' : {32 : 'i686-pc-linux-gnu', 64 : 'x86_64-pc-linux-gnu'}, + 'LinuxARM' : {32 : 'arm-linux-gnueabihf', 64 : 'aarch64-linux-gnu'}, + 'Windows' : {32 : 'i686-mingw32', 64 : 'x86_64-mingw32'}} bits = 32 if sys.maxsize > 2**32: bits = 64 sys_name = platform.system() sys_platform = platform.platform() + if 'Darwin' in sys_name and (sys_platform.find('arm') > 0 or sys_platform.find('arm64') > 0): + sys_name = 'DarwinARM' if 'Linux' in sys_name and (sys_platform.find('arm') > 0 or sys_platform.find('aarch64') > 0): sys_name = 'LinuxARM' if 'CYGWIN_NT' in sys_name: From 7c7b4b51af14a99fcfef60e3578d519eaeac8e98 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 8 Feb 2023 17:02:45 +0200 Subject: [PATCH 49/60] Update get.py to support Apple ARM64 From 74ddcf47b1f06ca1208d9ecb141bd83ca3844971 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 8 Feb 2023 17:11:10 +0200 Subject: [PATCH 50/60] Update package_esp32_index.template.json --- package/package_esp32_index.template.json | 276 ++++++++++++---------- 1 file changed, 152 insertions(+), 124 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index 5ec92b01d30..922c776fd63 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -36,35 +36,35 @@ } ], "toolsDependencies": [ - { - "packager": "esp32", - "name": "riscv32-esp-elf-gcc", - "version": "gcc11_2_0-esp-2022r1" - }, { "packager": "esp32", "name": "xtensa-esp32-elf-gcc", - "version": "gcc11_2_0-esp-2022r1" + "version": "esp-2022r1-11.2.0" }, { "packager": "esp32", "name": "xtensa-esp32s2-elf-gcc", - "version": "gcc11_2_0-esp-2022r1" + "version": "esp-2022r1-11.2.0" }, { "packager": "esp32", "name": "xtensa-esp32s3-elf-gcc", - "version": "gcc11_2_0-esp-2022r1" + "version": "esp-2022r1-11.2.0" }, { "packager": "esp32", - "name": "esptool_py", - "version": "4.2.1" + "name": "riscv32-esp-elf-gcc", + "version": "esp-2022r1-11.2.0" }, { "packager": "esp32", "name": "openocd-esp32", - "version": "v0.11.0-esp32-20220706" + "version": "v0.11.0-esp32-20221026" + }, + { + "packager": "esp32", + "name": "esptool_py", + "version": "4.2.1" }, { "packager": "esp32", @@ -80,64 +80,9 @@ } ], "tools": [ - { - "name": "riscv32-esp-elf-gcc", - "version": "gcc11_2_0-esp-2022r1", - "systems": [ - { - "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", - "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", - "checksum": "SHA-256:52710f804df4a033a2b621cc16cfa21023b42052819a51e35a2a164140bbf665", - "size": "110107900" - }, - { - "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", - "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", - "checksum": "SHA-256:812a18f2ecdc3f72c1d098c4e8baa968841099ce9d9ecf95baea85ff71e11013", - "size": "104279292" - }, - { - "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", - "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", - "checksum": "SHA-256:bc6e3ff8323d1f8b137374788b5615152281aab9e7561c55ab1504145677b6c7", - "size": "102802824" - }, - { - "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", - "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", - "checksum": "SHA-256:39d7295c30a23b5ea91baf61c207718ce86d4b1589014b030e121300370f696d", - "size": "111505972" - }, - { - "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", - "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", - "checksum": "SHA-256:d3a6f42b02a5f1485ba3fa92b8a9d9f307f643420e22b3765e88bbe4570aee01", - "size": "112060920" - }, - { - "host": "i686-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-win32.zip", - "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-win32.zip", - "checksum": "SHA-256:3e677ef068d7f154d33b0d3788b5f985c5066d110028eac44e0f76b3bda4429b", - "size": "268053767" - }, - { - "host": "x86_64-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-win64.zip", - "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-win64.zip", - "checksum": "SHA-256:324a5c679fef75313766cc48d3433c48bf23985a11b5070c5d19144538c6357b", - "size": "271158759" - } - ] - }, { "name": "xtensa-esp32-elf-gcc", - "version": "gcc11_2_0-esp-2022r1", + "version": "esp-2022r1-11.2.0", "systems": [ { "host": "x86_64-pc-linux-gnu", @@ -174,6 +119,13 @@ "checksum": "SHA-256:1c9d873c56469e3abec1e4214b7200d36804a605d4f0991e539b1577415409bf", "size": "68189688" }, + { + "host": "arm64-apple-darwin", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-macos-arm64.tar.xz", + "archiveFileName": "xtensa-esp32-elf-gcc11_2_0-esp-2022r1-macos-arm64.tar.xz", + "checksum": "SHA-256:297249b0dc5307fd496c4d85d960b69824996c0c450a8c92f8414a5fd32a7c3b", + "size": "58460768" + }, { "host": "i686-mingw32", "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32-elf-gcc11_2_0-esp-2022r1-win32.zip", @@ -192,7 +144,7 @@ }, { "name": "xtensa-esp32s2-elf-gcc", - "version": "gcc11_2_0-esp-2022r1", + "version": "esp-2022r1-11.2.0", "systems": [ { "host": "x86_64-pc-linux-gnu", @@ -229,6 +181,13 @@ "checksum": "SHA-256:f53da9423490001727c5b6c3b8e1602b887783f0ed68e5defbb3c7712ada9631", "size": "53568496" }, + { + "host": "arm64-apple-darwin", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-macos-arm64.tar.xz", + "archiveFileName": "xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-macos-arm64.tar.xz", + "checksum": "SHA-256:3592e0fbdb2ca438c7360d93fd62ef0e05ead2fc8144eff344bbe1971d333287", + "size": "44218948" + }, { "host": "i686-mingw32", "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s2-elf-gcc11_2_0-esp-2022r1-win32.zip", @@ -247,7 +206,7 @@ }, { "name": "xtensa-esp32s3-elf-gcc", - "version": "gcc11_2_0-esp-2022r1", + "version": "esp-2022r1-11.2.0", "systems": [ { "host": "x86_64-pc-linux-gnu", @@ -284,6 +243,13 @@ "checksum": "SHA-256:2b46730adc6afd8115e0be9365050a87f9523617e5e58ee35cb85ff1ddf2756c", "size": "54256036" }, + { + "host": "arm64-apple-darwin", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-macos-arm64.tar.xz", + "archiveFileName": "xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-macos-arm64.tar.xz", + "checksum": "SHA-256:bb449ac62b9917638b35234c98ce03ddf1cac75c2d80fbd67c46ecec08369838", + "size": "44835256" + }, { "host": "i686-mingw32", "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/xtensa-esp32s3-elf-gcc11_2_0-esp-2022r1-win32.zip", @@ -300,6 +266,123 @@ } ] }, + { + "name": "riscv32-esp-elf-gcc", + "version": "esp-2022r1-11.2.0", + "systems": [ + { + "host": "x86_64-pc-linux-gnu", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-amd64.tar.xz", + "checksum": "SHA-256:52710f804df4a033a2b621cc16cfa21023b42052819a51e35a2a164140bbf665", + "size": "110107900" + }, + { + "host": "aarch64-linux-gnu", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-arm64.tar.xz", + "checksum": "SHA-256:812a18f2ecdc3f72c1d098c4e8baa968841099ce9d9ecf95baea85ff71e11013", + "size": "104279292" + }, + { + "host": "arm-linux-gnueabihf", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-armel.tar.xz", + "checksum": "SHA-256:bc6e3ff8323d1f8b137374788b5615152281aab9e7561c55ab1504145677b6c7", + "size": "102802824" + }, + { + "host": "i686-pc-linux-gnu", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-linux-i686.tar.xz", + "checksum": "SHA-256:39d7295c30a23b5ea91baf61c207718ce86d4b1589014b030e121300370f696d", + "size": "111505972" + }, + { + "host": "x86_64-apple-darwin", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-macos.tar.xz", + "checksum": "SHA-256:d3a6f42b02a5f1485ba3fa92b8a9d9f307f643420e22b3765e88bbe4570aee01", + "size": "112060920" + }, + { + "host": "arm64-apple-darwin", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-macos-arm64.tar.xz", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-macos-arm64.tar.xz", + "checksum": "SHA-256:23d9a715d932a3af57fd7393b0789f88d0f70fedaf5b803deb9ab81dee271bd6", + "size": "101254152" + }, + { + "host": "i686-mingw32", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-win32.zip", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-win32.zip", + "checksum": "SHA-256:3e677ef068d7f154d33b0d3788b5f985c5066d110028eac44e0f76b3bda4429b", + "size": "268053767" + }, + { + "host": "x86_64-mingw32", + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-win64.zip", + "archiveFileName": "riscv32-esp-elf-gcc11_2_0-esp-2022r1-win64.zip", + "checksum": "SHA-256:324a5c679fef75313766cc48d3433c48bf23985a11b5070c5d19144538c6357b", + "size": "271158759" + } + ] + }, + { + "name": "openocd-esp32", + "version": "v0.11.0-esp32-20221026", + "systems": [ + { + "host": "x86_64-pc-linux-gnu", + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20221026/openocd-esp32-linux-amd64-0.11.0-esp32-20221026.tar.gz", + "archiveFileName": "openocd-esp32-linux-amd64-0.11.0-esp32-20221026.tar.gz", + "checksum": "SHA-256:ce63e9b1dfab60cc62da5dc2abcc22ba7036c42afe74671c787eb026744e7d0b", + "size": "2051435" + }, + { + "host": "aarch64-linux-gnu", + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20221026/openocd-esp32-linux-arm64-0.11.0-esp32-20221026.tar.gz", + "archiveFileName": "openocd-esp32-linux-arm64-0.11.0-esp32-20221026.tar.gz", + "checksum": "SHA-256:fe60a3a603e8c6bee47367e40fcb8c0da3a38e01163e9674ebc919b067700506", + "size": "1993843" + }, + { + "host": "arm-linux-gnueabihf", + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20221026/openocd-esp32-linux-armel-0.11.0-esp32-20221026.tar.gz", + "archiveFileName": "openocd-esp32-linux-armel-0.11.0-esp32-20221026.tar.gz", + "checksum": "SHA-256:6ef76101cca196a4be30fc74f191eff34abb423e32930a383012b866c9b76135", + "size": "2092111" + }, + { + "host": "x86_64-apple-darwin", + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20221026/openocd-esp32-macos-0.11.0-esp32-20221026.tar.gz", + "archiveFileName": "openocd-esp32-macos-0.11.0-esp32-20221026.tar.gz", + "checksum": "SHA-256:8edc666a0a230432554b73df7c62e0b5ec21fb018e7fda13b11a7ca8b6c1763b", + "size": "2199855" + }, + { + "host": "arm64-apple-darwin", + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20221026/openocd-esp32-macos-arm64-0.11.0-esp32-20221026.tar.gz", + "archiveFileName": "openocd-esp32-macos-arm64-0.11.0-esp32-20221026.tar.gz", + "checksum": "SHA-256:c426c0158ba6488e2f432f7c5b22e79155b5b0fae6d1ad5bbd7894723b43aa12", + "size": "2247179" + }, + { + "host": "i686-mingw32", + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20221026/openocd-esp32-win32-0.11.0-esp32-20221026.zip", + "archiveFileName": "openocd-esp32-win32-0.11.0-esp32-20221026.zip", + "checksum": "SHA-256:e0e789d35308c029c6b53457cf4a42a5620cb1a3014740026c089c2ed4fd77b2", + "size": "2493214" + }, + { + "host": "x86_64-mingw32", + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20221026/openocd-esp32-win32-0.11.0-esp32-20221026.zip", + "archiveFileName": "openocd-esp32-win32-0.11.0-esp32-20221026.zip", + "checksum": "SHA-256:e0e789d35308c029c6b53457cf4a42a5620cb1a3014740026c089c2ed4fd77b2", + "size": "2493214" + } + ] + }, { "name": "esptool_py", "version": "4.2.1", @@ -355,61 +438,6 @@ } ] }, - { - "name": "openocd-esp32", - "version": "v0.11.0-esp32-20220706", - "systems": [ - { - "host": "i686-mingw32", - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20220706/openocd-esp32-win32-0.11.0-esp32-20220706.zip", - "archiveFileName": "openocd-esp32-win32-0.11.0-esp32-20220706.zip", - "checksum": "SHA-256:c3d39eb4365a9947e71f1d3780ce031185bc6437f21186568a5c05f23f57a8d0", - "size": "2608736" - }, - { - "host": "x86_64-mingw32", - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20220706/openocd-esp32-win32-0.11.0-esp32-20220706.zip", - "archiveFileName": "openocd-esp32-win32-0.11.0-esp32-20220706.zip", - "checksum": "SHA-256:c3d39eb4365a9947e71f1d3780ce031185bc6437f21186568a5c05f23f57a8d0", - "size": "2608736" - }, - { - "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20220706/openocd-esp32-macos-0.11.0-esp32-20220706.tar.gz", - "archiveFileName": "openocd-esp32-macos-0.11.0-esp32-20220706.tar.gz", - "checksum": "SHA-256:333ee2ec3c9b5dc6ad4509faae55335cdea7f8bf83a56bfcf5327e4497c8538a", - "size": "2077882" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20220706/openocd-esp32-linux-amd64-0.11.0-esp32-20220706.tar.gz", - "archiveFileName": "openocd-esp32-linux-amd64-0.11.0-esp32-20220706.tar.gz", - "checksum": "SHA-256:26f1f18dd93eb70a13203848d3fb1cc2e0de1fd6749c7dd771b2de8709735aed", - "size": "2011201" - }, - { - "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20220706/openocd-esp32-linux-amd64-0.11.0-esp32-20220706.tar.gz", - "archiveFileName": "openocd-esp32-linux-amd64-0.11.0-esp32-20220706.tar.gz", - "checksum": "SHA-256:26f1f18dd93eb70a13203848d3fb1cc2e0de1fd6749c7dd771b2de8709735aed", - "size": "2011201" - }, - { - "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20220706/openocd-esp32-linux-armhf-0.11.0-esp32-20220706.tar.gz", - "archiveFileName": "openocd-esp32-linux-armhf-0.11.0-esp32-20220706.tar.gz", - "checksum": "SHA-256:7f3b57332104e8b8e6194553365a70a9d3754878cfc063d5dc5d839513a63de9", - "size": "1902964" - }, - { - "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.11.0-esp32-20220706/openocd-esp32-linux-arm64-0.11.0-esp32-20220706.tar.gz", - "archiveFileName": "openocd-esp32-linux-arm64-0.11.0-esp32-20220706.tar.gz", - "checksum": "SHA-256:f97792bc2852937ec0accb9f0eb2e49926c0f747a71f101a4e34aed75d2c6fcc", - "size": "1954685" - } - ] - }, { "version": "3.0.0-gnu12-dc7f933", "name": "mklittlefs", From 1ccbc708816e422e9579af3ba8fb79eb0805ccf7 Mon Sep 17 00:00:00 2001 From: David McCurley <44048235+mrengineer7777@users.noreply.github.com> Date: Wed, 8 Feb 2023 03:54:32 -0600 Subject: [PATCH 51/60] WString Return bool (#7774) --- cores/esp32/WString.cpp | 112 ++++++++++++++++++++-------------------- cores/esp32/WString.h | 70 ++++++++++++------------- 2 files changed, 92 insertions(+), 90 deletions(-) diff --git a/cores/esp32/WString.cpp b/cores/esp32/WString.cpp index f31024ea8ba..9b92fb84559 100644 --- a/cores/esp32/WString.cpp +++ b/cores/esp32/WString.cpp @@ -176,26 +176,25 @@ void String::invalidate(void) { init(); } -unsigned char String::reserve(unsigned int size) { +bool String::reserve(unsigned int size) { if(buffer() && capacity() >= size) - return 1; + return true; if(changeBuffer(size)) { if(len() == 0) wbuffer()[0] = 0; - return 1; + return true; } - return 0; + return false; } -unsigned char String::changeBuffer(unsigned int maxStrLen) { +bool String::changeBuffer(unsigned int maxStrLen) { // Can we use SSO here to avoid allocation? if (maxStrLen < sizeof(sso.buff) - 1) { if (isSSO() || !buffer()) { // Already using SSO, nothing to do - uint16_t oldLen = len(); + uint16_t oldLen = len(); setSSO(true); setLen(oldLen); - return 1; } else { // if bufptr && !isSSO() // Using bufptr, need to shrink into sso.buff char temp[sizeof(sso.buff)]; @@ -205,8 +204,8 @@ unsigned char String::changeBuffer(unsigned int maxStrLen) { setSSO(true); memcpy(wbuffer(), temp, maxStrLen); setLen(oldLen); - return 1; } + return true; } // Fallthrough to normal allocator size_t newSize = (maxStrLen + 16) & (~0xf); @@ -230,9 +229,9 @@ unsigned char String::changeBuffer(unsigned int maxStrLen) { setCapacity(newSize - 1); setBuffer(newbuffer); setLen(oldLen); // Needed in case of SSO where len() never existed - return 1; + return true; } - return 0; + return false; } // /*********************************************/ @@ -338,34 +337,34 @@ String & String::operator =(const __FlashStringHelper *pstr) { // /* concat */ // /*********************************************/ -unsigned char String::concat(const String &s) { +bool String::concat(const String &s) { // Special case if we're concatting ourself (s += s;) since we may end up // realloc'ing the buffer and moving s.buffer in the method called if (&s == this) { unsigned int newlen = 2 * len(); if (!s.buffer()) - return 0; + return false; if (s.len() == 0) - return 1; + return true; if (!reserve(newlen)) - return 0; + return false; memmove(wbuffer() + len(), buffer(), len()); setLen(newlen); wbuffer()[len()] = 0; - return 1; + return true; } else { return concat(s.buffer(), s.len()); } } -unsigned char String::concat(const char *cstr, unsigned int length) { +bool String::concat(const char *cstr, unsigned int length) { unsigned int newlen = len() + length; if(!cstr) - return 0; + return false; if(length == 0) - return 1; + return true; if(!reserve(newlen)) - return 0; + return false; if (cstr >= wbuffer() && cstr < wbuffer() + len()) // compatible with SSO in ram #6155 (case "x += x.c_str()") memmove(wbuffer() + len(), cstr, length + 1); @@ -373,79 +372,82 @@ unsigned char String::concat(const char *cstr, unsigned int length) { // compatible with source in flash #6367 memcpy_P(wbuffer() + len(), cstr, length + 1); setLen(newlen); - return 1; + return true; } -unsigned char String::concat(const char *cstr) { +bool String::concat(const char *cstr) { if(!cstr) - return 0; + return false; return concat(cstr, strlen(cstr)); } -unsigned char String::concat(char c) { +bool String::concat(char c) { char buf[] = { c, '\0' }; return concat(buf, 1); } -unsigned char String::concat(unsigned char num) { +bool String::concat(unsigned char num) { char buf[1 + 3 * sizeof(unsigned char)]; return concat(buf, sprintf(buf, "%d", num)); } -unsigned char String::concat(int num) { +bool String::concat(int num) { char buf[2 + 3 * sizeof(int)]; return concat(buf, sprintf(buf, "%d", num)); } -unsigned char String::concat(unsigned int num) { +bool String::concat(unsigned int num) { char buf[1 + 3 * sizeof(unsigned int)]; utoa(num, buf, 10); return concat(buf, strlen(buf)); } -unsigned char String::concat(long num) { +bool String::concat(long num) { char buf[2 + 3 * sizeof(long)]; return concat(buf, sprintf(buf, "%ld", num)); } -unsigned char String::concat(unsigned long num) { +bool String::concat(unsigned long num) { char buf[1 + 3 * sizeof(unsigned long)]; ultoa(num, buf, 10); return concat(buf, strlen(buf)); } -unsigned char String::concat(float num) { +bool String::concat(float num) { char buf[20]; char* string = dtostrf(num, 4, 2, buf); return concat(string, strlen(string)); } -unsigned char String::concat(double num) { +bool String::concat(double num) { char buf[20]; char* string = dtostrf(num, 4, 2, buf); return concat(string, strlen(string)); } -unsigned char String::concat(long long num) { +bool String::concat(long long num) { char buf[2 + 3 * sizeof(long long)]; return concat(buf, sprintf(buf, "%lld", num)); // NOT SURE - NewLib Nano ... does it support %lld? } -unsigned char String::concat(unsigned long long num) { +bool String::concat(unsigned long long num) { char buf[1 + 3 * sizeof(unsigned long long)]; ulltoa(num, buf, 10); return concat(buf, strlen(buf)); } -unsigned char String::concat(const __FlashStringHelper * str) { - if (!str) return 0; +bool String::concat(const __FlashStringHelper * str) { + if (!str) + return false; int length = strlen_P((PGM_P)str); - if (length == 0) return 1; + if (length == 0) + return true; unsigned int newlen = len() + length; - if (!reserve(newlen)) return 0; + if (!reserve(newlen)) + return false; memcpy_P(wbuffer() + len(), (PGM_P)str, length + 1); setLen(newlen); - return 1; + return true; } /*********************************************/ @@ -559,11 +561,11 @@ int String::compareTo(const String &s) const { return strcmp(buffer(), s.buffer()); } -unsigned char String::equals(const String &s2) const { +bool String::equals(const String &s2) const { return (len() == s2.len() && compareTo(s2) == 0); } -unsigned char String::equals(const char *cstr) const { +bool String::equals(const char *cstr) const { if(len() == 0) return (cstr == NULL || *cstr == 0); if(cstr == NULL) @@ -571,36 +573,36 @@ unsigned char String::equals(const char *cstr) const { return strcmp(buffer(), cstr) == 0; } -unsigned char String::operator<(const String &rhs) const { +bool String::operator<(const String &rhs) const { return compareTo(rhs) < 0; } -unsigned char String::operator>(const String &rhs) const { +bool String::operator>(const String &rhs) const { return compareTo(rhs) > 0; } -unsigned char String::operator<=(const String &rhs) const { +bool String::operator<=(const String &rhs) const { return compareTo(rhs) <= 0; } -unsigned char String::operator>=(const String &rhs) const { +bool String::operator>=(const String &rhs) const { return compareTo(rhs) >= 0; } -unsigned char String::equalsIgnoreCase(const String &s2) const { +bool String::equalsIgnoreCase(const String &s2) const { if(this == &s2) - return 1; + return true; if(len() != s2.len()) - return 0; + return false; if(len() == 0) - return 1; + return true; const char *p1 = buffer(); const char *p2 = s2.buffer(); while(*p1) { if(tolower(*p1++) != tolower(*p2++)) - return 0; + return false; } - return 1; + return true; } unsigned char String::equalsConstantTime(const String &s2) const { @@ -630,21 +632,21 @@ unsigned char String::equalsConstantTime(const String &s2) const { return (equalcond & diffcond); //bitwise AND } -unsigned char String::startsWith(const String &s2) const { +bool String::startsWith(const String &s2) const { if(len() < s2.len()) - return 0; + return false; return startsWith(s2, 0); } -unsigned char String::startsWith(const String &s2, unsigned int offset) const { +bool String::startsWith(const String &s2, unsigned int offset) const { if(offset > (unsigned)(len() - s2.len()) || !buffer() || !s2.buffer()) - return 0; + return false; return strncmp(&buffer()[offset], s2.buffer(), s2.len()) == 0; } -unsigned char String::endsWith(const String &s2) const { +bool String::endsWith(const String &s2) const { if(len() < s2.len() || !buffer() || !s2.buffer()) - return 0; + return false; return strcmp(&buffer()[len() - s2.len()], s2.buffer()) == 0; } diff --git a/cores/esp32/WString.h b/cores/esp32/WString.h index 99e85e0df52..f7f0d814ddc 100644 --- a/cores/esp32/WString.h +++ b/cores/esp32/WString.h @@ -81,7 +81,7 @@ class String { // return true on success, false on failure (in which case, the string // is left unchanged). reserve(0), if successful, will validate an // invalid string (i.e., "if (s)" will be true afterwards) - unsigned char reserve(unsigned int size); + bool reserve(unsigned int size); inline unsigned int length(void) const { if(buffer()) { return len(); @@ -112,21 +112,21 @@ class String { // returns true on success, false on failure (in which case, the string // is left unchanged). if the argument is null or invalid, the // concatenation is considered unsuccessful. - unsigned char concat(const String &str); - unsigned char concat(const char *cstr); - unsigned char concat(const char *cstr, unsigned int length); - unsigned char concat(const uint8_t *cstr, unsigned int length) {return concat((const char*)cstr, length);} - unsigned char concat(char c); - unsigned char concat(unsigned char c); - unsigned char concat(int num); - unsigned char concat(unsigned int num); - unsigned char concat(long num); - unsigned char concat(unsigned long num); - unsigned char concat(float num); - unsigned char concat(double num); - unsigned char concat(long long num); - unsigned char concat(unsigned long long num); - unsigned char concat(const __FlashStringHelper * str); + bool concat(const String &str); + bool concat(const char *cstr); + bool concat(const char *cstr, unsigned int length); + bool concat(const uint8_t *cstr, unsigned int length) {return concat((const char*)cstr, length);} + bool concat(char c); + bool concat(unsigned char c); + bool concat(int num); + bool concat(unsigned int num); + bool concat(long num); + bool concat(unsigned long num); + bool concat(float num); + bool concat(double num); + bool concat(long long num); + bool concat(unsigned long long num); + bool concat(const __FlashStringHelper * str); // if there's not enough memory for the concatenated value, the string // will be left unchanged (but this isn't signalled in any way) @@ -202,39 +202,39 @@ class String { return buffer() ? &String::StringIfHelper : 0; } int compareTo(const String &s) const; - unsigned char equals(const String &s) const; - unsigned char equals(const char *cstr) const; - unsigned char operator ==(const String &rhs) const { + bool equals(const String &s) const; + bool equals(const char *cstr) const; + bool operator ==(const String &rhs) const { return equals(rhs); } - unsigned char operator ==(const char *cstr) const { + bool operator ==(const char *cstr) const { return equals(cstr); } - unsigned char operator !=(const String &rhs) const { + bool operator !=(const String &rhs) const { return !equals(rhs); } - unsigned char operator !=(const char *cstr) const { + bool operator !=(const char *cstr) const { return !equals(cstr); } - unsigned char operator <(const String &rhs) const; - unsigned char operator >(const String &rhs) const; - unsigned char operator <=(const String &rhs) const; - unsigned char operator >=(const String &rhs) const; - unsigned char equalsIgnoreCase(const String &s) const; + bool operator <(const String &rhs) const; + bool operator >(const String &rhs) const; + bool operator <=(const String &rhs) const; + bool operator >=(const String &rhs) const; + bool equalsIgnoreCase(const String &s) const; unsigned char equalsConstantTime(const String &s) const; - unsigned char startsWith(const String &prefix) const; - unsigned char startsWith(const char *prefix) const { + bool startsWith(const String &prefix) const; + bool startsWith(const char *prefix) const { return this->startsWith(String(prefix)); } - unsigned char startsWith(const __FlashStringHelper *prefix) const { + bool startsWith(const __FlashStringHelper *prefix) const { return this->startsWith(String(prefix)); } - unsigned char startsWith(const String &prefix, unsigned int offset) const; - unsigned char endsWith(const String &suffix) const; - unsigned char endsWith(const char *suffix) const { + bool startsWith(const String &prefix, unsigned int offset) const; + bool endsWith(const String &suffix) const; + bool endsWith(const char *suffix) const { return this->endsWith(String(suffix)); } - unsigned char endsWith(const __FlashStringHelper * suffix) const { + bool endsWith(const __FlashStringHelper * suffix) const { return this->endsWith(String(suffix)); } @@ -345,7 +345,7 @@ class String { protected: void init(void); void invalidate(void); - unsigned char changeBuffer(unsigned int maxStrLen); + bool changeBuffer(unsigned int maxStrLen); // copy and move String & copy(const char *cstr, unsigned int length); From 415078044369bd3627ff4a587d45a406f24ea0e2 Mon Sep 17 00:00:00 2001 From: Gaya3N25 <30388176+Gaya3N25@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:32:49 +0100 Subject: [PATCH 52/60] Add Roboheart Hercules development board to the esp32-core (#7672) * added Roboheart Hercules pin definitions and board.txt entries * added package_roboheat.json for prototyping * Roboheart Hercules pins * Updated the pins * Delete package_roboheart.json * Requested changes --------- Co-authored-by: renebohne --- boards.txt | 133 ++++++++++++++++++++- variants/roboheart_hercules/pins_arduino.h | 104 ++++++++++++++++ 2 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 variants/roboheart_hercules/pins_arduino.h diff --git a/boards.txt b/boards.txt index 791c0d8e349..5fd2b4f64de 100644 --- a/boards.txt +++ b/boards.txt @@ -20943,6 +20943,137 @@ esp32c3m1IKit.menu.EraseFlash.all.upload.erase_cmd=-e ############################################################## +roboheart_hercules.name=RoboHeart Hercules + +roboheart_hercules.upload.tool=esptool_py +roboheart_hercules.upload.maximum_size=1310720 +roboheart_hercules.upload.maximum_data_size=327680 +roboheart_hercules.upload.wait_for_upload_port=true +roboheart_hercules.upload.flags= +roboheart_hercules.upload.extra_flags= + +roboheart_hercules.serial.disableDTR=true +roboheart_hercules.serial.disableRTS=true + +roboheart_hercules.build.tarch=xtensa +roboheart_hercules.build.bootloader_addr=0x1000 +roboheart_hercules.build.target=esp32 +roboheart_hercules.build.mcu=esp32 +roboheart_hercules.build.core=esp32 +roboheart_hercules.build.variant=roboheart_hercules +roboheart_hercules.build.board=roboheart_hercules + +roboheart_hercules.build.f_cpu=240000000L +roboheart_hercules.build.flash_size=4MB +roboheart_hercules.build.flash_freq=40m +roboheart_hercules.build.flash_mode=dio +roboheart_hercules.build.boot=dio +roboheart_hercules.build.partitions=default +roboheart_hercules.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw +roboheart_hercules.build.extra_libs= + +roboheart_hercules.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +roboheart_hercules.menu.PartitionScheme.default.build.partitions=default +roboheart_hercules.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +roboheart_hercules.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +roboheart_hercules.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT) +roboheart_hercules.menu.PartitionScheme.default_8MB.build.partitions=default_8MB +roboheart_hercules.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336 +roboheart_hercules.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +roboheart_hercules.menu.PartitionScheme.minimal.build.partitions=minimal +roboheart_hercules.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +roboheart_hercules.menu.PartitionScheme.no_ota.build.partitions=no_ota +roboheart_hercules.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +roboheart_hercules.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +roboheart_hercules.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +roboheart_hercules.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +roboheart_hercules.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +roboheart_hercules.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +roboheart_hercules.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +roboheart_hercules.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +roboheart_hercules.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +roboheart_hercules.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +roboheart_hercules.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +roboheart_hercules.menu.PartitionScheme.huge_app.build.partitions=huge_app +roboheart_hercules.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +roboheart_hercules.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +roboheart_hercules.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +roboheart_hercules.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +roboheart_hercules.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT) +roboheart_hercules.menu.PartitionScheme.fatflash.build.partitions=ffat +roboheart_hercules.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 +roboheart_hercules.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9MB FATFS) +roboheart_hercules.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB +roboheart_hercules.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +roboheart_hercules.menu.PartitionScheme.rainmaker=RainMaker +roboheart_hercules.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +roboheart_hercules.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 + +roboheart_hercules.menu.CPUFreq.240=240MHz (WiFi/BT) +roboheart_hercules.menu.CPUFreq.240.build.f_cpu=240000000L +roboheart_hercules.menu.CPUFreq.160=160MHz (WiFi/BT) +roboheart_hercules.menu.CPUFreq.160.build.f_cpu=160000000L +roboheart_hercules.menu.CPUFreq.80=80MHz (WiFi/BT) +roboheart_hercules.menu.CPUFreq.80.build.f_cpu=80000000L +roboheart_hercules.menu.CPUFreq.40=40MHz +roboheart_hercules.menu.CPUFreq.40.build.f_cpu=40000000L +roboheart_hercules.menu.CPUFreq.20=20MHz +roboheart_hercules.menu.CPUFreq.20.build.f_cpu=20000000L +roboheart_hercules.menu.CPUFreq.10=10MHz +roboheart_hercules.menu.CPUFreq.10.build.f_cpu=10000000L + +roboheart_hercules.menu.FlashMode.qio=QIO +roboheart_hercules.menu.FlashMode.qio.build.flash_mode=dio +roboheart_hercules.menu.FlashMode.qio.build.boot=qio +roboheart_hercules.menu.FlashMode.dio=DIO +roboheart_hercules.menu.FlashMode.dio.build.flash_mode=dio +roboheart_hercules.menu.FlashMode.dio.build.boot=dio +roboheart_hercules.menu.FlashMode.qout=QOUT +roboheart_hercules.menu.FlashMode.qout.build.flash_mode=dout +roboheart_hercules.menu.FlashMode.qout.build.boot=qout +roboheart_hercules.menu.FlashMode.dout=DOUT +roboheart_hercules.menu.FlashMode.dout.build.flash_mode=dout +roboheart_hercules.menu.FlashMode.dout.build.boot=dout + +roboheart_hercules.menu.FlashFreq.80=80MHz +roboheart_hercules.menu.FlashFreq.80.build.flash_freq=80m +roboheart_hercules.menu.FlashFreq.40=40MHz +roboheart_hercules.menu.FlashFreq.40.build.flash_freq=40m + +roboheart_hercules.menu.UploadSpeed.921600=921600 +roboheart_hercules.menu.UploadSpeed.921600.upload.speed=921600 +roboheart_hercules.menu.UploadSpeed.115200=115200 +roboheart_hercules.menu.UploadSpeed.115200.upload.speed=115200 +roboheart_hercules.menu.UploadSpeed.256000.windows=256000 +roboheart_hercules.menu.UploadSpeed.256000.upload.speed=256000 +roboheart_hercules.menu.UploadSpeed.230400.windows.upload.speed=256000 +roboheart_hercules.menu.UploadSpeed.230400=230400 +roboheart_hercules.menu.UploadSpeed.230400.upload.speed=230400 +roboheart_hercules.menu.UploadSpeed.460800.linux=460800 +roboheart_hercules.menu.UploadSpeed.460800.macosx=460800 +roboheart_hercules.menu.UploadSpeed.460800.upload.speed=460800 +roboheart_hercules.menu.UploadSpeed.512000.windows=512000 +roboheart_hercules.menu.UploadSpeed.512000.upload.speed=512000 + +roboheart_hercules.menu.DebugLevel.none=None +roboheart_hercules.menu.DebugLevel.none.build.code_debug=0 +roboheart_hercules.menu.DebugLevel.error=Error +roboheart_hercules.menu.DebugLevel.error.build.code_debug=1 +roboheart_hercules.menu.DebugLevel.warn=Warn +roboheart_hercules.menu.DebugLevel.warn.build.code_debug=2 +roboheart_hercules.menu.DebugLevel.info=Info +roboheart_hercules.menu.DebugLevel.info.build.code_debug=3 +roboheart_hercules.menu.DebugLevel.debug=Debug +roboheart_hercules.menu.DebugLevel.debug.build.code_debug=4 +roboheart_hercules.menu.DebugLevel.verbose=Verbose +roboheart_hercules.menu.DebugLevel.verbose.build.code_debug=5 + +roboheart_hercules.menu.EraseFlash.none=Disabled +roboheart_hercules.menu.EraseFlash.none.upload.erase_cmd= +roboheart_hercules.menu.EraseFlash.all=Enabled +roboheart_hercules.menu.EraseFlash.all.upload.erase_cmd=-e + +############################################################## VALTRACK_V4_VTS_ESP32_C3.name=VALTRACK_V4_VTS_ESP32_C3 VALTRACK_V4_VTS_ESP32_C3.vid.0=0x303a VALTRACK_V4_VTS_ESP32_C3.pid.0=0x1001 @@ -21604,4 +21735,4 @@ crabik_slot_esp32_s3.menu.EraseFlash.none.upload.erase_cmd= crabik_slot_esp32_s3.menu.EraseFlash.all=Enabled crabik_slot_esp32_s3.menu.EraseFlash.all.upload.erase_cmd=-e -############################################################## \ No newline at end of file +############################################################## diff --git a/variants/roboheart_hercules/pins_arduino.h b/variants/roboheart_hercules/pins_arduino.h new file mode 100644 index 00000000000..17a5951773e --- /dev/null +++ b/variants/roboheart_hercules/pins_arduino.h @@ -0,0 +1,104 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define EXTERNAL_NUM_INTERRUPTS 16 +#define NUM_DIGITAL_PINS 20 +#define NUM_ANALOG_INPUTS 16 + +#define analogInputToDigitalPin(p) (((p)<20)?(analogChannelToDigitalPin(p)):-1) +#define digitalPinToInterrupt(p) (((p)<40)?(p):-1) +#define digitalPinHasPWM(p) (p < 34) + + +// Motor driver pins +#define MOTOR_A_IN1 25 // PHASE/IN1 +#define MOTOR_A_IN2 26 // ENABLE/IN2 + +#define MOTOR_B_IN1 27 // PHASE/IN1 +#define MOTOR_B_IN2 32 // ENABLE/IN2 + +#define MOTOR_C_IN1 33 // PHASE/IN1 +#define MOTOR_C_IN2 4 // ENABLE/IN2 + +#define SLEEP_MOTOR_ABC 2 // nSLEEP + +#define LED_ROBOHEART 14 // Built in LED +#define BUILTIN_LED LED_ROBOHEART // backward compatibility +#define LED_BUILTIN LED_ROBOHEART + +#define BUTTON_ROBOHEART 0 // Button + +// I2C IMU sensor +#define IMU_SDA 21 +#define IMU_SCL 22 + +#define RXD1 16 +#define TXD1 17 + +// GSM Vela connector board pins +#define GSM_PWRKEY 12 +#define GSM_DTR 13 +#define GSM_CTS 15 +#define GSM_RTS 14 +#define GSM_TX TXD1 +#define GSM_RX RXD1 +#define BATTERY_PIN 36 // Battery ADC pin + +static const uint8_t TX = 35; +static const uint8_t RX = 34; + +static const uint8_t TXD2 = 17; +static const uint8_t RXD2 = 16; + +static const uint8_t SDA = 21; +static const uint8_t SCL = 22; + +static const uint8_t SS = 5; +static const uint8_t MOSI = 23; +static const uint8_t MISO = 19; +static const uint8_t SCK = 18; + +static const uint8_t G23 = 23; +static const uint8_t G19 = 19; +static const uint8_t G18 = 18; +static const uint8_t G3 = 3; +static const uint8_t G16 = 16; +static const uint8_t G21 = 21; +static const uint8_t G2 = 2; +static const uint8_t G12 = 12; +static const uint8_t G15 = 15; +static const uint8_t G35 = 35; +static const uint8_t G36 = 36; +static const uint8_t G25 = 25; +static const uint8_t G26 = 26; +static const uint8_t G1 = 1; +static const uint8_t G17 = 17; +static const uint8_t G22 = 22; +static const uint8_t G5 = 5; +static const uint8_t G13 = 13; +static const uint8_t G0 = 0; +static const uint8_t G34 = 34; + +static const uint8_t DAC1 = 25; +static const uint8_t DAC2 = 26; + +static const uint8_t A0 = 36; +static const uint8_t A3 = 39; +static const uint8_t A4 = 32; +static const uint8_t A5 = 33; +static const uint8_t A6 = 34; +static const uint8_t A7 = 35; +static const uint8_t A10 = 4; +static const uint8_t A11 = 0; +static const uint8_t A12 = 2; +static const uint8_t A13 = 15; +static const uint8_t A14 = 13; +static const uint8_t A15 = 12; +static const uint8_t A16 = 14; +static const uint8_t A17 = 27; +static const uint8_t A18 = 25; +static const uint8_t A19 = 26; + +#endif /* Pins_Arduino_h */ From c21402dcbaa7dd9d23cf1b18e58fbc1b0ef48772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliv=C3=A9r=20Rem=C3=A9ny?= <25034625+remenyo@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:34:16 +0100 Subject: [PATCH 53/60] Reword "ESP-IDF as Component" (#7812) I think "Arduino as an ESP-IDF component" or just "As ESP-IDF component" instead of "ESP-IDF as Component" is more correct way to name the link. 1. "ESP-IDF as Component" would imply that ESP-IDF is some sort of library for Arduino, which is (IMO) misleading, because it's true the other way around. 2. It's written as "Arduino as an ESP-IDF component" on the webpage it points to as well. - Also I removed the capitalization from "Component" as I have not found a reason why is it capitalized. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00d8334c591..72496f2d170 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ You can use the [Arduino-ESP32 Online Documentation](https://docs.espressif.com/ * [Getting Started](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html) * [Installing (Windows, Linux and macOS)](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html) * [Libraries](https://docs.espressif.com/projects/arduino-esp32/en/latest/libraries.html) -* [ESP-IDF as Component](https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html) +* [Arduino as an ESP-IDF component](https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html) * [FAQ](https://docs.espressif.com/projects/arduino-esp32/en/latest/faq.html) * [Troubleshooting](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html) From 5da0a31b6d7e756c7a26ddfe550621a1bce19c75 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Wed, 8 Feb 2023 17:34:54 +0700 Subject: [PATCH 54/60] add new board Adafruit Feather ESP32-S3 Reverse TFT (#7811) --- boards.txt | 200 ++++++++++++++++++ .../bootloader-tinyuf2.bin | Bin 0 -> 22320 bytes .../partitions-4MB-tinyuf2.csv | 11 + .../pins_arduino.h | 68 ++++++ .../tinyuf2.bin | Bin 0 -> 187808 bytes .../variant.cpp | 42 ++++ 6 files changed, 321 insertions(+) create mode 100644 variants/adafruit_feather_esp32s3_reversetft/bootloader-tinyuf2.bin create mode 100644 variants/adafruit_feather_esp32s3_reversetft/partitions-4MB-tinyuf2.csv create mode 100644 variants/adafruit_feather_esp32s3_reversetft/pins_arduino.h create mode 100644 variants/adafruit_feather_esp32s3_reversetft/tinyuf2.bin create mode 100644 variants/adafruit_feather_esp32s3_reversetft/variant.cpp diff --git a/boards.txt b/boards.txt index 5fd2b4f64de..5464de8c06e 100644 --- a/boards.txt +++ b/boards.txt @@ -9648,6 +9648,206 @@ adafruit_feather_esp32s3_tft.menu.EraseFlash.none.upload.erase_cmd= adafruit_feather_esp32s3_tft.menu.EraseFlash.all=Enabled adafruit_feather_esp32s3_tft.menu.EraseFlash.all.upload.erase_cmd=-e +############################################################## +# Adafruit Feather ESP32-S3 Reverse TFT + +adafruit_feather_esp32s3_reversetft.name=Adafruit Feather ESP32-S3 Reverse TFT +adafruit_feather_esp32s3_reversetft.vid.0=0x239A +adafruit_feather_esp32s3_reversetft.pid.0=0x8123 +adafruit_feather_esp32s3_reversetft.vid.1=0x239A +adafruit_feather_esp32s3_reversetft.pid.1=0x0123 +adafruit_feather_esp32s3_reversetft.vid.2=0x239A +adafruit_feather_esp32s3_reversetft.pid.2=0x8124 + +adafruit_feather_esp32s3_reversetft.bootloader.tool=esptool_py +adafruit_feather_esp32s3_reversetft.bootloader.tool.default=esptool_py + +adafruit_feather_esp32s3_reversetft.upload.tool=esptool_py +adafruit_feather_esp32s3_reversetft.upload.tool.default=esptool_py +adafruit_feather_esp32s3_reversetft.upload.tool.network=esp_ota + +adafruit_feather_esp32s3_reversetft.upload.maximum_size=1310720 +adafruit_feather_esp32s3_reversetft.upload.maximum_data_size=327680 +adafruit_feather_esp32s3_reversetft.upload.flags= +adafruit_feather_esp32s3_reversetft.upload.extra_flags= +adafruit_feather_esp32s3_reversetft.upload.use_1200bps_touch=true +adafruit_feather_esp32s3_reversetft.upload.wait_for_upload_port=true + +adafruit_feather_esp32s3_reversetft.serial.disableDTR=false +adafruit_feather_esp32s3_reversetft.serial.disableRTS=false + +adafruit_feather_esp32s3_reversetft.build.tarch=xtensa +adafruit_feather_esp32s3_reversetft.build.bootloader_addr=0x0 +adafruit_feather_esp32s3_reversetft.build.target=esp32s3 +adafruit_feather_esp32s3_reversetft.build.mcu=esp32s3 +adafruit_feather_esp32s3_reversetft.build.core=esp32 +adafruit_feather_esp32s3_reversetft.build.variant=adafruit_feather_esp32s3_reversetft +adafruit_feather_esp32s3_reversetft.build.board=ADAFRUIT_FEATHER_ESP32S3_REVTFT + +adafruit_feather_esp32s3_reversetft.build.usb_mode=0 +adafruit_feather_esp32s3_reversetft.build.cdc_on_boot=1 +adafruit_feather_esp32s3_reversetft.build.msc_on_boot=0 +adafruit_feather_esp32s3_reversetft.build.dfu_on_boot=0 +adafruit_feather_esp32s3_reversetft.build.f_cpu=240000000L +adafruit_feather_esp32s3_reversetft.build.flash_size=4MB +adafruit_feather_esp32s3_reversetft.build.flash_freq=80m +adafruit_feather_esp32s3_reversetft.build.flash_mode=dio +adafruit_feather_esp32s3_reversetft.build.boot=qio +adafruit_feather_esp32s3_reversetft.build.partitions=default +adafruit_feather_esp32s3_reversetft.build.defines= +adafruit_feather_esp32s3_reversetft.build.loop_core= +adafruit_feather_esp32s3_reversetft.build.event_core= +adafruit_feather_esp32s3_reversetft.build.flash_type=qio +adafruit_feather_esp32s3_reversetft.build.psram_type=qspi +adafruit_feather_esp32s3_reversetft.build.memory_type={build.flash_type}_{build.psram_type} + +adafruit_feather_esp32s3_reversetft.menu.LoopCore.1=Core 1 +adafruit_feather_esp32s3_reversetft.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +adafruit_feather_esp32s3_reversetft.menu.LoopCore.0=Core 0 +adafruit_feather_esp32s3_reversetft.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +adafruit_feather_esp32s3_reversetft.menu.EventsCore.1=Core 1 +adafruit_feather_esp32s3_reversetft.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +adafruit_feather_esp32s3_reversetft.menu.EventsCore.0=Core 0 +adafruit_feather_esp32s3_reversetft.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +adafruit_feather_esp32s3_reversetft.menu.USBMode.default=USB-OTG (TinyUSB) +adafruit_feather_esp32s3_reversetft.menu.USBMode.default.build.usb_mode=0 +adafruit_feather_esp32s3_reversetft.menu.USBMode.hwcdc=Hardware CDC and JTAG +adafruit_feather_esp32s3_reversetft.menu.USBMode.hwcdc.build.usb_mode=1 + +adafruit_feather_esp32s3_reversetft.menu.CDCOnBoot.cdc=Enabled +adafruit_feather_esp32s3_reversetft.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 +adafruit_feather_esp32s3_reversetft.menu.CDCOnBoot.default=Disabled +adafruit_feather_esp32s3_reversetft.menu.CDCOnBoot.default.build.cdc_on_boot=0 + +adafruit_feather_esp32s3_reversetft.menu.MSCOnBoot.default=Disabled +adafruit_feather_esp32s3_reversetft.menu.MSCOnBoot.default.build.msc_on_boot=0 +adafruit_feather_esp32s3_reversetft.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +adafruit_feather_esp32s3_reversetft.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +adafruit_feather_esp32s3_reversetft.menu.DFUOnBoot.default=Disabled +adafruit_feather_esp32s3_reversetft.menu.DFUOnBoot.default.build.dfu_on_boot=0 +adafruit_feather_esp32s3_reversetft.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +adafruit_feather_esp32s3_reversetft.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +adafruit_feather_esp32s3_reversetft.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +adafruit_feather_esp32s3_reversetft.menu.UploadMode.cdc.upload.use_1200bps_touch=true +adafruit_feather_esp32s3_reversetft.menu.UploadMode.cdc.upload.wait_for_upload_port=true +adafruit_feather_esp32s3_reversetft.menu.UploadMode.default=UART0 / Hardware CDC +adafruit_feather_esp32s3_reversetft.menu.UploadMode.default.upload.use_1200bps_touch=false +adafruit_feather_esp32s3_reversetft.menu.UploadMode.default.upload.wait_for_upload_port=false + +adafruit_feather_esp32s3_reversetft.menu.PSRAM.enabled=QSPI PSRAM +adafruit_feather_esp32s3_reversetft.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM +adafruit_feather_esp32s3_reversetft.menu.PSRAM.enabled.build.psram_type=qspi +adafruit_feather_esp32s3_reversetft.menu.PSRAM.disabled=Disabled +adafruit_feather_esp32s3_reversetft.menu.PSRAM.disabled.build.defines= +adafruit_feather_esp32s3_reversetft.menu.PSRAM.disabled.build.psram_type=qspi +adafruit_feather_esp32s3_reversetft.menu.PSRAM.opi=OPI PSRAM +adafruit_feather_esp32s3_reversetft.menu.PSRAM.opi.build.defines=-DBOARD_HAS_PSRAM +adafruit_feather_esp32s3_reversetft.menu.PSRAM.opi.build.psram_type=opi + +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.tinyuf2=TinyUF2 4MB (1.3MB APP/960KB FFAT) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader-tinyuf2 +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.tinyuf2.build.custom_partitions=partitions-4MB-tinyuf2 +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.tinyuf2.upload.maximum_size=1441792 +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x2d0000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.default.build.partitions=default +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.minimal.build.partitions=minimal +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.no_ota.build.partitions=no_ota +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.huge_app.build.partitions=huge_app +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +adafruit_feather_esp32s3_reversetft.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 + +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.240=240MHz (WiFi) +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.240.build.f_cpu=240000000L +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.160=160MHz (WiFi) +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.160.build.f_cpu=160000000L +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.80=80MHz (WiFi) +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.80.build.f_cpu=80000000L +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.40=40MHz +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.40.build.f_cpu=40000000L +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.20=20MHz +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.20.build.f_cpu=20000000L +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.10=10MHz +adafruit_feather_esp32s3_reversetft.menu.CPUFreq.10.build.f_cpu=10000000L + +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio=QIO 80MHz +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio.build.flash_mode=dio +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio.build.boot=qio +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio.build.boot_freq=80m +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio.build.flash_freq=80m +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio120=QIO 120MHz +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio120.build.flash_mode=dio +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio120.build.boot=qio +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio120.build.boot_freq=120m +adafruit_feather_esp32s3_reversetft.menu.FlashMode.qio120.build.flash_freq=80m +adafruit_feather_esp32s3_reversetft.menu.FlashMode.dio=DIO 80MHz +adafruit_feather_esp32s3_reversetft.menu.FlashMode.dio.build.flash_mode=dio +adafruit_feather_esp32s3_reversetft.menu.FlashMode.dio.build.boot=dio +adafruit_feather_esp32s3_reversetft.menu.FlashMode.dio.build.boot_freq=80m +adafruit_feather_esp32s3_reversetft.menu.FlashMode.dio.build.flash_freq=80m +adafruit_feather_esp32s3_reversetft.menu.FlashMode.opi=OPI 80MHz +adafruit_feather_esp32s3_reversetft.menu.FlashMode.opi.build.flash_mode=dout +adafruit_feather_esp32s3_reversetft.menu.FlashMode.opi.build.boot=opi +adafruit_feather_esp32s3_reversetft.menu.FlashMode.opi.build.boot_freq=80m +adafruit_feather_esp32s3_reversetft.menu.FlashMode.opi.build.flash_freq=80m + +adafruit_feather_esp32s3_reversetft.menu.FlashSize.4M=4MB (32Mb) +adafruit_feather_esp32s3_reversetft.menu.FlashSize.4M.build.flash_size=4MB + +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.921600=921600 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.921600.upload.speed=921600 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.115200=115200 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.115200.upload.speed=115200 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.256000.windows=256000 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.256000.upload.speed=256000 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.230400.windows.upload.speed=256000 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.230400=230400 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.230400.upload.speed=230400 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.460800.linux=460800 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.460800.macosx=460800 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.460800.upload.speed=460800 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.512000.windows=512000 +adafruit_feather_esp32s3_reversetft.menu.UploadSpeed.512000.upload.speed=512000 + +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.none=None +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.none.build.code_debug=0 +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.error=Error +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.error.build.code_debug=1 +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.warn=Warn +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.warn.build.code_debug=2 +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.info=Info +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.info.build.code_debug=3 +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.debug=Debug +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.debug.build.code_debug=4 +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.verbose=Verbose +adafruit_feather_esp32s3_reversetft.menu.DebugLevel.verbose.build.code_debug=5 + +adafruit_feather_esp32s3_reversetft.menu.EraseFlash.none=Disabled +adafruit_feather_esp32s3_reversetft.menu.EraseFlash.none.upload.erase_cmd= +adafruit_feather_esp32s3_reversetft.menu.EraseFlash.all=Enabled +adafruit_feather_esp32s3_reversetft.menu.EraseFlash.all.upload.erase_cmd=-e + ############################################################## # Adafruit QT Py ESP32-S3 No PSRAM diff --git a/variants/adafruit_feather_esp32s3_reversetft/bootloader-tinyuf2.bin b/variants/adafruit_feather_esp32s3_reversetft/bootloader-tinyuf2.bin new file mode 100644 index 0000000000000000000000000000000000000000..57df9ed036f403250312e83850f31a777c03f3ea GIT binary patch literal 22320 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 literal 0 HcmV?d00001 diff --git a/variants/adafruit_feather_esp32s3_reversetft/partitions-4MB-tinyuf2.csv b/variants/adafruit_feather_esp32s3_reversetft/partitions-4MB-tinyuf2.csv new file mode 100644 index 00000000000..164ba0d5965 --- /dev/null +++ b/variants/adafruit_feather_esp32s3_reversetft/partitions-4MB-tinyuf2.csv @@ -0,0 +1,11 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +# bootloader.bin,, 0x1000, 32K +# partition table, 0x8000, 4K + +nvs, data, nvs, 0x9000, 20K, +otadata, data, ota, 0xe000, 8K, +ota_0, 0, ota_0, 0x10000, 1408K, +ota_1, 0, ota_1, 0x170000, 1408K, +uf2, app, factory,0x2d0000, 256K, +ffat, data, fat, 0x310000, 960K, diff --git a/variants/adafruit_feather_esp32s3_reversetft/pins_arduino.h b/variants/adafruit_feather_esp32s3_reversetft/pins_arduino.h new file mode 100644 index 00000000000..594940f5710 --- /dev/null +++ b/variants/adafruit_feather_esp32s3_reversetft/pins_arduino.h @@ -0,0 +1,68 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + + +#define USB_VID 0x239A +#define USB_PID 0x8123 +#define USB_MANUFACTURER "Adafruit" +#define USB_PRODUCT "Feather ESP32-S3 Reverse TFT" +#define USB_SERIAL "" // Empty string for MAC adddress + + +#define EXTERNAL_NUM_INTERRUPTS 46 +#define NUM_DIGITAL_PINS 48 +#define NUM_ANALOG_INPUTS 20 + +#define analogInputToDigitalPin(p) (((p)<20)?(analogChannelToDigitalPin(p)):-1) +#define digitalPinToInterrupt(p) (((p)<48)?(p):-1) +#define digitalPinHasPWM(p) (p < 46) + +#define LED_BUILTIN 13 + +#define PIN_NEOPIXEL 33 +#define NEOPIXEL_NUM 1 // number of neopixels +#define NEOPIXEL_POWER 21 // power pin +#define NEOPIXEL_POWER_ON HIGH // power pin state when on + +#define TFT_I2C_POWER 7 +#define TFT_CS 42 +#define TFT_RST 41 +#define TFT_DC 40 +#define TFT_BACKLITE 45 + +static const uint8_t SDA = 3; +static const uint8_t SCL = 4; + +static const uint8_t SS = 42; +static const uint8_t MOSI = 35; +static const uint8_t SCK = 36; +static const uint8_t MISO = 37; + +static const uint8_t A0 = 18; +static const uint8_t A1 = 17; +static const uint8_t A2 = 16; +static const uint8_t A3 = 15; +static const uint8_t A4 = 14; +static const uint8_t A5 = 8; + +static const uint8_t TX = 39; +static const uint8_t RX = 38; +#define TX1 TX +#define RX1 RX + +static const uint8_t T5 = 5; +static const uint8_t T6 = 6; +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; + +#endif /* Pins_Arduino_h */ diff --git a/variants/adafruit_feather_esp32s3_reversetft/tinyuf2.bin b/variants/adafruit_feather_esp32s3_reversetft/tinyuf2.bin new file mode 100644 index 0000000000000000000000000000000000000000..7e852a31efd6eee386d2f998cafea699437a39f7 GIT binary patch literal 187808 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%0AWgWksm^?y-5S(KkbjIj+29TH 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 R`=9i_R(; Date: Wed, 8 Feb 2023 16:42:19 +0100 Subject: [PATCH 55/60] Multi threading examples (tasks, queues, semaphores, mutexes) (#7660) * Moved and renamed example ESP32/FreeRTOS to MultiThreading/BasicMultiThreading * Added dummy files * Modified original example * Fixed BasicMultiThreading.ino * Added Example demonstrating use of queues * Extended info in BasicMultiThreading * Renamed Queues to singular Queue * Added Mutex example * Added Semaphore example * Moved info from example to README * Moved doc from Mutex to README * Added Queue README * Removed unecesary text * Fixed grammar * Increased stack size for Sempahore example * Added headers into .ino files * Added word Example at the end of title in README * removed unused line * Added forgotten README * Modified BasicMultiThreading example * Added missing S3 entry in README * moved location --- .../BasicMultiThreading.ino | 117 +++++++++++++++++ .../FreeRTOS/BasicMultiThreading/README.md | 89 +++++++++++++ .../ESP32/examples/FreeRTOS/FreeRTOS.ino | 102 --------------- .../ESP32/examples/FreeRTOS/Mutex/Mutex.ino | 97 ++++++++++++++ .../ESP32/examples/FreeRTOS/Mutex/README.md | 121 ++++++++++++++++++ .../ESP32/examples/FreeRTOS/Queue/Queue.ino | 120 +++++++++++++++++ .../ESP32/examples/FreeRTOS/Queue/README.md | 75 +++++++++++ .../examples/FreeRTOS/Semaphore/README.md | 81 ++++++++++++ .../examples/FreeRTOS/Semaphore/Semaphore.ino | 56 ++++++++ 9 files changed, 756 insertions(+), 102 deletions(-) create mode 100644 libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino create mode 100644 libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/README.md delete mode 100644 libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino create mode 100644 libraries/ESP32/examples/FreeRTOS/Mutex/Mutex.ino create mode 100644 libraries/ESP32/examples/FreeRTOS/Mutex/README.md create mode 100644 libraries/ESP32/examples/FreeRTOS/Queue/Queue.ino create mode 100644 libraries/ESP32/examples/FreeRTOS/Queue/README.md create mode 100644 libraries/ESP32/examples/FreeRTOS/Semaphore/README.md create mode 100644 libraries/ESP32/examples/FreeRTOS/Semaphore/Semaphore.ino diff --git a/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino b/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino new file mode 100644 index 00000000000..745d5b6a46c --- /dev/null +++ b/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino @@ -0,0 +1,117 @@ +/* Basic Multi Threading Arduino Example + This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +// Please read file README.md in the folder containing this example. + +#if CONFIG_FREERTOS_UNICORE +#define ARDUINO_RUNNING_CORE 0 +#else +#define ARDUINO_RUNNING_CORE 1 +#endif + +#define ANALOG_INPUT_PIN A0 + +#ifndef LED_BUILTIN + #define LED_BUILTIN 13 // Specify the on which is your LED +#endif + +// Define two tasks for Blink & AnalogRead. +void TaskBlink( void *pvParameters ); +void TaskAnalogRead( void *pvParameters ); +TaskHandle_t analog_read_task_handle; // You can (don't have to) use this to be able to manipulate a task from somewhere else. + +// The setup function runs once when you press reset or power on the board. +void setup() { + // Initialize serial communication at 115200 bits per second: + Serial.begin(115200); + // Set up two tasks to run independently. + uint32_t blink_delay = 1000; // Delay between changing state on LED pin + xTaskCreate( + TaskBlink + , "Task Blink" // A name just for humans + , 2048 // The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);` + , (void*) &blink_delay // Task parameter which can modify the task behavior. This must be passed as pointer to void. + , 2 // Priority + , NULL // Task handle is not used here - simply pass NULL + ); + + // This variant of task creation can also specify on which core it will be run (only relevant for multi-core ESPs) + xTaskCreatePinnedToCore( + TaskAnalogRead + , "Analog Read" + , 2048 // Stack size + , NULL // When no parameter is used, simply pass NULL + , 1 // Priority + , &analog_read_task_handle // With task handle we will be able to manipulate with this task. + , ARDUINO_RUNNING_CORE // Core on which the task will run + ); + + Serial.printf("Basic Multi Threading Arduino Example\n"); + // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started. +} + +void loop(){ + if(analog_read_task_handle != NULL){ // Make sure that the task actually exists + delay(10000); + vTaskDelete(analog_read_task_handle); // Delete task + analog_read_task_handle = NULL; // prevent calling vTaskDelete on non-existing task + } +} + +/*--------------------------------------------------*/ +/*---------------------- Tasks ---------------------*/ +/*--------------------------------------------------*/ + +void TaskBlink(void *pvParameters){ // This is a task. + uint32_t blink_delay = *((uint32_t*)pvParameters); + +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + If you want to know what pin the on-board LED is connected to on your ESP32 model, check + the Technical Specs of your board. +*/ + + // initialize digital LED_BUILTIN on pin 13 as an output. + pinMode(LED_BUILTIN, OUTPUT); + + for (;;){ // A Task shall never return or exit. + digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) + // arduino-esp32 has FreeRTOS configured to have a tick-rate of 1000Hz and portTICK_PERIOD_MS + // refers to how many milliseconds the period between each ticks is, ie. 1ms. + delay(blink_delay); + digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW + delay(blink_delay); + } +} + +void TaskAnalogRead(void *pvParameters){ // This is a task. + (void) pvParameters; + // Check if the given analog pin is usable - if not - delete this task + if(!adcAttachPin(ANALOG_INPUT_PIN)){ + Serial.printf("TaskAnalogRead cannot work because the given pin %d cannot be used for ADC - the task will delete itself.\n", ANALOG_INPUT_PIN); + analog_read_task_handle = NULL; // Prevent calling vTaskDelete on non-existing task + vTaskDelete(NULL); // Delete this task + } + +/* + AnalogReadSerial + Reads an analog input on pin A3, prints the result to the serial monitor. + Graphical representation is available using serial plotter (Tools > Serial Plotter menu) + Attach the center pin of a potentiometer to pin A3, and the outside pins to +5V and ground. + + This example code is in the public domain. +*/ + + for (;;){ + // read the input on analog pin: + int sensorValue = analogRead(ANALOG_INPUT_PIN); + // print out the value you read: + Serial.println(sensorValue); + delay(100); // 100ms delay + } +} diff --git a/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/README.md b/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/README.md new file mode 100644 index 00000000000..c7112e8b4f9 --- /dev/null +++ b/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/README.md @@ -0,0 +1,89 @@ +# Basic Multi Threading Example + +This example demonstrates the basic usage of FreeRTOS Tasks for multi threading. + +Please refer to other examples in this folder to better utilize their full potential and safeguard potential problems. +It is also advised to read the documentation on FreeRTOS web pages: +[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) + +This example will blink the built-in LED and read analog data. +Additionally, this example demonstrates the usage of the task handle, simply by deleting the analog +read task after 10 seconds from the main loop by calling the function `vTaskDelete`. + +### Theory: +A task is simply a function that runs when the operating system (FreeeRTOS) sees fit. +This task can have an infinite loop inside if you want to do some work periodically for the entirety of the program run. +This, however, can create a problem - no other task will ever run and also the Watch Dog will trigger and your program will restart. +A nice behaving tasks know when it is useless to keep the processor for itself and give it away for other tasks to be used. +This can be achieved in many ways, but the simplest is called `delay(`milliseconds)`. +During that delay, any other task may run and do its job. +When the delay runs out the Operating System gives the processor the task which can continue. +For other ways to yield the CPU in a task please see other examples in this folder. +It is also worth mentioning that two or more tasks running the same function will run them with separate stacks, so if you want to run the same code (which could be differentiated by the argument) there is no need to have multiple copies of the same function. + +**Task creation has a few parameters you should understand:** +``` + xTaskCreate(TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) +``` + - **pxTaskCode** is the name of your function which will run as a task + - **pcName** is a string of human-readable descriptions for your task + - **usStackDepth** is the number of words (word = 4B) available to the task. If you see an error similar to this "Debug exception reason: Stack canary watchpoint triggered (Task Blink)" you should increase it + - **pvParameters** is a parameter that will be passed to the task function - it must be explicitly converted to (void*) and in your function explicitly converted back to the intended data type. + - **uxPriority** is a number from 0 to configMAX_PRIORITIES which determines how the FreeRTOS will allow the tasks to run. 0 is the lowest priority. + - **pxCreatedTask** task handle is a pointer to the task which allows you to manipulate the task - delete it, suspend and resume. + If you don't need to do anything special with your task, simply pass NULL for this parameter. + You can read more about task control here: https://www.freertos.org/a00112.html + +# Supported Targets + +This example supports all SoCs. + +### Hardware Connection + +If your board does not have a built-in LED, please connect one to the pin specified by the `LED_BUILTIN` in the code (you can also change the number and connect it to the pin you desire). + +Optionally you can connect the analog element to the pin. such as a variable resistor, analog input such as an audio signal, or any signal generator. However, if the pin is left unconnected it will receive background noise and you will also see a change in the signal when the pin is touched by a finger. +Please refer to the ESP-IDF ADC documentation for specific SoC for info on which pins are available: +[ESP32](https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32/api-reference/peripherals/adc.html), + [ESP32-S2](https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32s2/api-reference/peripherals/adc.html), + [ESP32-S3](https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32s3/api-reference/peripherals/adc.html), + [ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32c3/api-reference/peripherals/adc.html) + + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino b/libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino deleted file mode 100644 index 67dde03b0e7..00000000000 --- a/libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino +++ /dev/null @@ -1,102 +0,0 @@ -#ifdef ARDUINO_RUNNING_CORE -#undef ARDUINO_RUNNING_CORE -#endif -#if CONFIG_FREERTOS_UNICORE -#define ARDUINO_RUNNING_CORE 0 -#else -#define ARDUINO_RUNNING_CORE 1 -#endif - -#ifndef LED_BUILTIN -#define LED_BUILTIN 13 -#endif - -// define two tasks for Blink & AnalogRead -void TaskBlink( void *pvParameters ); -void TaskAnalogReadA3( void *pvParameters ); - -// the setup function runs once when you press reset or power the board -void setup() { - - // initialize serial communication at 115200 bits per second: - Serial.begin(115200); - - // Now set up two tasks to run independently. - xTaskCreatePinnedToCore( - TaskBlink - , "TaskBlink" // A name just for humans - , 1024 // This stack size can be checked & adjusted by reading the Stack Highwater - , NULL - , 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest. - , NULL - , ARDUINO_RUNNING_CORE); - - xTaskCreatePinnedToCore( - TaskAnalogReadA3 - , "AnalogReadA3" - , 1024 // Stack size - , NULL - , 1 // Priority - , NULL - , ARDUINO_RUNNING_CORE); - - // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started. -} - -void loop() -{ - // Empty. Things are done in Tasks. -} - -/*--------------------------------------------------*/ -/*---------------------- Tasks ---------------------*/ -/*--------------------------------------------------*/ - -void TaskBlink(void *pvParameters) // This is a task. -{ - (void) pvParameters; - -/* - Blink - Turns on an LED on for one second, then off for one second, repeatedly. - - If you want to know what pin the on-board LED is connected to on your ESP32 model, check - the Technical Specs of your board. -*/ - - // initialize digital LED_BUILTIN on pin 13 as an output. - pinMode(LED_BUILTIN, OUTPUT); - - for (;;) // A Task shall never return or exit. - { - digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) - // arduino-esp32 has FreeRTOS configured to have a tick-rate of 1000Hz and portTICK_PERIOD_MS - // refers to how many milliseconds the period between each ticks is, ie. 1ms. - vTaskDelay(1000 / portTICK_PERIOD_MS ); // vTaskDelay wants ticks, not milliseconds - digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW - vTaskDelay(1000 / portTICK_PERIOD_MS); // 1 second delay - } -} - -void TaskAnalogReadA3(void *pvParameters) // This is a task. -{ - (void) pvParameters; - -/* - AnalogReadSerial - Reads an analog input on pin A3, prints the result to the serial monitor. - Graphical representation is available using serial plotter (Tools > Serial Plotter menu) - Attach the center pin of a potentiometer to pin A3, and the outside pins to +5V and ground. - - This example code is in the public domain. -*/ - - for (;;) - { - // read the input on analog pin A3: - int sensorValueA3 = analogRead(A3); - // print out the value you read: - Serial.println(sensorValueA3); - vTaskDelay(100 / portTICK_PERIOD_MS); // 100ms delay - } -} diff --git a/libraries/ESP32/examples/FreeRTOS/Mutex/Mutex.ino b/libraries/ESP32/examples/FreeRTOS/Mutex/Mutex.ino new file mode 100644 index 00000000000..157c5742e69 --- /dev/null +++ b/libraries/ESP32/examples/FreeRTOS/Mutex/Mutex.ino @@ -0,0 +1,97 @@ +/* Basic Multi Threading Arduino Example + This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +// Please read file README.md in the folder containing this example. + +#define USE_MUTEX +int shared_variable = 0; +SemaphoreHandle_t shared_var_mutex = NULL; + +// Define a task function +void Task( void *pvParameters ); + +// The setup function runs once when you press reset or power on the board. +void setup() { + // Initialize serial communication at 115200 bits per second: + Serial.begin(115200); + while(!Serial) delay(100); + Serial.printf(" Task 0 | Task 1\n"); + +#ifdef USE_MUTEX + shared_var_mutex = xSemaphoreCreateMutex(); // Create the mutex +#endif + + // Set up two tasks to run the same function independently. + static int task_number0 = 0; + xTaskCreate( + Task + , "Task 0" // A name just for humans + , 2048 // The stack size + , (void*)&task_number0 // Pass reference to a variable describing the task number + //, 5 // High priority + , 1 // priority + , NULL // Task handle is not used here - simply pass NULL + ); + + static int task_number1 = 1; + xTaskCreate( + Task + , "Task 1" + , 2048 // Stack size + , (void*)&task_number1 // Pass reference to a variable describing the task number + , 1 // Low priority + , NULL // Task handle is not used here - simply pass NULL + ); + + // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started. +} + +void loop(){ +} + +/*--------------------------------------------------*/ +/*---------------------- Tasks ---------------------*/ +/*--------------------------------------------------*/ + +void Task(void *pvParameters){ // This is a task. + int task_num = *((int*)pvParameters); + Serial.printf("%s\n", task_num ? " Starting |" : " | Starting"); + for (;;){ // A Task shall never return or exit. +#ifdef USE_MUTEX + if(shared_var_mutex != NULL){ // Sanity check if the mutex exists + // Try to take the mutex and wait indefintly if needed + if(xSemaphoreTake(shared_var_mutex, portMAX_DELAY) == pdTRUE){ + // Mutex successfully taken +#endif + int new_value = random(1000); + + char str0[32]; sprintf(str0, " %d <- %d |", shared_variable, new_value); + char str1[32]; sprintf(str1, " | %d <- %d", shared_variable, new_value); + Serial.printf("%s\n", task_num ? str0 : str1); + + shared_variable = new_value; + delay(random(100)); // wait random time of max 100 ms - simulating some computation + + sprintf(str0, " R: %d |", shared_variable); + sprintf(str1, " | R: %d", shared_variable); + Serial.printf("%s\n", task_num ? str0 : str1); + //Serial.printf("Task %d after write: reading %d\n", task_num, shared_variable); + + if(shared_variable != new_value){ + Serial.printf("%s\n", task_num ? " Mismatch! |" : " | Mismatch!"); + //Serial.printf("Task %d: detected race condition - the value changed!\n", task_num); + } + +#ifdef USE_MUTEX + xSemaphoreGive(shared_var_mutex); // After accessing the shared resource give the mutex and allow other processes to access it + }else{ + // We could not obtain the semaphore and can therefore not access the shared resource safely. + } // mutex take + } // sanity check +#endif + delay(10); // Allow other task to be scheduled + } // Infinite loop +} \ No newline at end of file diff --git a/libraries/ESP32/examples/FreeRTOS/Mutex/README.md b/libraries/ESP32/examples/FreeRTOS/Mutex/README.md new file mode 100644 index 00000000000..d1c8c19e3be --- /dev/null +++ b/libraries/ESP32/examples/FreeRTOS/Mutex/README.md @@ -0,0 +1,121 @@ +# Mutex Example + +This example demonstrates the basic usage of FreeRTOS Mutually Exclusive Locks (Mutex) for securing access to shared resources in multi-threading. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +https://www.freertos.org/a00106.html + +This example creates 2 tasks with the same implementation - they write into a shared variable and then read it and check if it is the same as what they have written. +In single-thread programming like on Arduino this is of no concern and will be always ok, however when multi-threading is used the execution of the task is switched by the FreeRTOS and the value can be rewritten from another task before reading again. +The tasks print write and read operation - each in their column for better reading. Task 0 is on the left and Task 1 is on the right. +Watch the writes and read in secure mode when using the mutex (default) as the results are as you would expect them. +Then try to comment the USE_MUTEX and watch again - there will be a lot of mismatches! + +### Theory: +Mutex is a specialized version of Semaphore (please see the Semaphore example for more info). +In essence, the mutex is a variable whose value determines if the mute is taken (locked) or given (unlocked). +When two or more processes access the same resource (variable, peripheral, etc) it might happen, for example, that when one task starts to read a variable and the operating system (FreeRTOS) will schedule the execution of another task +which will write to this variable and when the previous task runs again it will read something different. + +Mutexes and binary semaphores are very similar but have some subtle differences: +Mutexes include a priority inheritance mechanism, whereas binary semaphores do not. +This makes binary semaphores the better choice for implementing synchronization (between tasks or between tasks and an interrupt), and mutexes the better +choice for implementing simple mutual exclusion. +What is priority inheritance? +If a low-priority task holds the Mutex but gets interrupted by a Higher priority task, which +then tries to take the Mutex, the low-priority task will temporarily ‘inherit’ the high priority so a middle-priority task can't block the low-priority task, and thus also block the high priority task. +Semaphores don't have the logic to handle this, in part because Semaphores aren't 'owned' by the task that takes them. + +A mutex can also be recursive - if a task that holds the mutex takes it again, it will succeed, and the mutex will be released +for other tasks only when it is given the same number of times that it was taken. + +You can check the danger by commenting on the definition of USE_MUTEX which will disable the mutex and present the danger of concurrent access. + + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Flash and observe the serial output. + +Comment the `USE_MUTEX` definition, save and flash again and observe the behavior of unprotected access to the shared variable. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. + +## Example Log Output + +The expected output of shared variables protected by mutex demonstrates mutually exclusive access from tasks - they do not interrupt each other and do not rewrite the value before the other task has read it back. + +``` + Task 0 | Task 1 + | Starting + | 0 <- 227 + Starting | + | R: 227 + 227 <- 737 | + R: 737 | + | 737 <- 282 + | R: 282 + 282 <- 267 | +``` + +The output of unprotected access to shared variable - it happens often that a task is interrupted after writing and before reading the other task write a different value - a corruption occurred! + +``` + Task 0 | Task 1 + | Starting + | 0 <- 333 + Starting | + 333 <- 620 | + R: 620 | + 620 <- 244 | + | R: 244 + | Mismatch! + | 244 <- 131 + R: 131 | + Mismatch! | + 131 <- 584 | + | R: 584 + | Mismatch! + | 584 <- 134 + | R: 134 + | 134 <- 554 + R: 554 | + Mismatch! | + 554 <- 313 | +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/FreeRTOS/Queue/Queue.ino b/libraries/ESP32/examples/FreeRTOS/Queue/Queue.ino new file mode 100644 index 00000000000..a26ee3310d6 --- /dev/null +++ b/libraries/ESP32/examples/FreeRTOS/Queue/Queue.ino @@ -0,0 +1,120 @@ +/* Basic Multi Threading Arduino Example + This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +// Please read file README.md in the folder containing this example./* + +#define MAX_LINE_LENGTH (64) + +// Define two tasks for reading and writing from and to the serial port. +void TaskWriteToSerial(void *pvParameters); +void TaskReadFromSerial(void *pvParameters); + +// Define Queue handle +QueueHandle_t QueueHandle; +const int QueueElementSize = 10; +typedef struct{ + char line[MAX_LINE_LENGTH]; + uint8_t line_length; +} message_t; + +// The setup function runs once when you press reset or power on the board. +void setup() { + // Initialize serial communication at 115200 bits per second: + Serial.begin(115200); + while(!Serial){delay(10);} + + // Create the queue which will have number of elements, each of size `message_t` and pass the address to . + QueueHandle = xQueueCreate(QueueElementSize, sizeof(message_t)); + + // Check if the queue was successfully created + if(QueueHandle == NULL){ + Serial.println("Queue could not be created. Halt."); + while(1) delay(1000); // Halt at this point as is not possible to continue + } + + // Set up two tasks to run independently. + xTaskCreate( + TaskWriteToSerial + , "Task Write To Serial" // A name just for humans + , 2048 // The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);` + , NULL // No parameter is used + , 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest. + , NULL // Task handle is not used here + ); + + xTaskCreate( + TaskReadFromSerial + , "Task Read From Serial" + , 2048 // Stack size + , NULL // No parameter is used + , 1 // Priority + , NULL // Task handle is not used here + ); + + // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started. + Serial.printf("\nAnything you write will return as echo.\nMaximum line length is %d characters (+ terminating '0').\nAnything longer will be sent as a separate line.\n\n", MAX_LINE_LENGTH-1); +} + +void loop(){ + // Loop is free to do any other work + + delay(1000); // While not being used yield the CPU to other tasks +} + +/*--------------------------------------------------*/ +/*---------------------- Tasks ---------------------*/ +/*--------------------------------------------------*/ + +void TaskWriteToSerial(void *pvParameters){ // This is a task. + message_t message; + for (;;){ // A Task shall never return or exit. + // One approach would be to poll the function (uxQueueMessagesWaiting(QueueHandle) and call delay if nothing is waiting. + // The other approach is to use infinite time to wait defined by constant `portMAX_DELAY`: + if(QueueHandle != NULL){ // Sanity check just to make sure the queue actually exists + int ret = xQueueReceive(QueueHandle, &message, portMAX_DELAY); + if(ret == pdPASS){ + // The message was successfully received - send it back to Serial port and "Echo: " + Serial.printf("Echo line of size %d: \"%s\"\n", message.line_length, message.line); + // The item is queued by copy, not by reference, so lets free the buffer after use. + }else if(ret == pdFALSE){ + Serial.println("The `TaskWriteToSerial` was unable to receive data from the Queue"); + } + } // Sanity check + } // Infinite loop +} + +void TaskReadFromSerial(void *pvParameters){ // This is a task. + message_t message; + for (;;){ + // Check if any data are waiting in the Serial buffer + message.line_length = Serial.available(); + if(message.line_length > 0){ + // Check if the queue exists AND if there is any free space in the queue + if(QueueHandle != NULL && uxQueueSpacesAvailable(QueueHandle) > 0){ + int max_length = message.line_length < MAX_LINE_LENGTH ? message.line_length : MAX_LINE_LENGTH-1; + for(int i = 0; i < max_length; ++i){ + message.line[i] = Serial.read(); + } + message.line_length = max_length; + message.line[message.line_length] = 0; // Add the terminating nul char + + // The line needs to be passed as pointer to void. + // The last parameter states how many milliseconds should wait (keep trying to send) if is not possible to send right away. + // When the wait parameter is 0 it will not wait and if the send is not possible the function will return errQUEUE_FULL + int ret = xQueueSend(QueueHandle, (void*) &message, 0); + if(ret == pdTRUE){ + // The message was successfully sent. + }else if(ret == errQUEUE_FULL){ + // Since we are checking uxQueueSpacesAvailable this should not occur, however if more than one task should + // write into the same queue it can fill-up between the test and actual send attempt + Serial.println("The `TaskReadFromSerial` was unable to send data into the Queue"); + } // Queue send check + } // Queue sanity check + }else{ + delay(100); // Allow other tasks to run when there is nothing to read + } // Serial buffer check + } // Infinite loop +} diff --git a/libraries/ESP32/examples/FreeRTOS/Queue/README.md b/libraries/ESP32/examples/FreeRTOS/Queue/README.md new file mode 100644 index 00000000000..745ce9e8db6 --- /dev/null +++ b/libraries/ESP32/examples/FreeRTOS/Queue/README.md @@ -0,0 +1,75 @@ +# Queue Example + +This example demonstrates the basic usage of FreeRTOS Queues which enables tasks to pass data between each other in a secure asynchronous way. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) + +This example reads data received on the serial port (sent by the user) pass it via queue to another task which will send it back on Serial Output. + +### Theory: +A queue is a simple-to-use data structure (in the most basic way) controlled by `xQueueSend` and `xQueueReceive` functions. +Usually, one task writes into the queue and the other task reads from it. +Usage of queues enables the reading task to yield the CPU until there are data in the queue and therefore not waste precious computation time. + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Flash and write anything to serial input. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. + +## Example Log Output + +``` +Anything you write will return as echo. +Maximum line length is 63 characters (+ terminating '0'). +Anything longer will be sent as a separate line. + +``` +< Input text "Short input" + +``Echo line of size 11: "Short input"`` + +< Input text "An example of very long input which is longer than default 63 characters will be split." + +``` +Echo line of size 63: "An example of very long input which is longer than default 63 c" +Echo line of size 24: "haracters will be split." +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md b/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md new file mode 100644 index 00000000000..8f860a52db5 --- /dev/null +++ b/libraries/ESP32/examples/FreeRTOS/Semaphore/README.md @@ -0,0 +1,81 @@ +# Semaphore Example + +This example demonstrates the basic usage of FreeRTOS Semaphores and queue sets for coordination between tasks for multi-threading. +Please refer to other examples in this folder to better understand the usage of tasks. +It is also advised to read the documentation on FreeRTOS web pages: +[https://www.freertos.org/a00106.html](https://www.freertos.org/a00106.html) + +### Theory: +Semaphore is in essence a variable. Tasks can set the value, wait until one or more +semaphores are set and thus communicate between each other their state. +A binary semaphore is a semaphore that has a maximum count of 1, hence the 'binary' name. +A task can only 'take' the semaphore if it is available, and the semaphore is only available if its count is 1. + +Semaphores can be controlled by any number of tasks. If you use semaphore as a one-way +signalization with only one task giving and only one task taking there is a much faster option +called Task Notifications - please see FreeRTOS documentation and read more about them: [https://www.freertos.org/RTOS-task-notifications.html](https://www.freertos.org/RTOS-task-notifications.html) + +This example uses a semaphore to signal when a package is delivered to a warehouse by multiple +delivery trucks, and multiple workers are waiting to receive the package. + +# Supported Targets + +This example supports all ESP32 SoCs. + +## How to Use Example + +Read the code and try to understand it, then flash and observe the Serial output. + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file. + +## Example Log Output + +``` +Anything you write will return as echo. +Maximum line length is 63 characters (+ terminating '0'). +Anything longer will be sent as a separate line. + +``` +< Input text "Short input" + +``Echo line of size 11: "Short input"`` + +< Input text "An example of very long input which is longer than default 63 characters will be split." + +``` +Echo line of size 63: "An example of very long input which is longer than default 63 c" +Echo line of size 24: "haracters will be split." +``` + +## Troubleshooting + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/ESP32/examples/FreeRTOS/Semaphore/Semaphore.ino b/libraries/ESP32/examples/FreeRTOS/Semaphore/Semaphore.ino new file mode 100644 index 00000000000..ae3b3fd1bf7 --- /dev/null +++ b/libraries/ESP32/examples/FreeRTOS/Semaphore/Semaphore.ino @@ -0,0 +1,56 @@ +/* Basic Multi Threading Arduino Example + This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +// Please read file README.md in the folder containing this example. + +#include + +SemaphoreHandle_t package_delivered_semaphore; + +void delivery_truck_task(void *pvParameters) { + int truck_number = (int) pvParameters; + while(1) { + // Wait for a package to be delivered + // ... + // Notify the warehouse that a package has been delivered + xSemaphoreGive(package_delivered_semaphore); + Serial.printf("Package delivered by truck: %d\n", truck_number); + //wait for some time + vTaskDelay(1000 / portTICK_PERIOD_MS); + } +} + +void warehouse_worker_task(void *pvParameters) { + int worker_number = (int) pvParameters; + while(1) { + // Wait for a package to be delivered + xSemaphoreTake(package_delivered_semaphore, portMAX_DELAY); + Serial.printf("Package received by worker: %d\n", worker_number); + // Receive the package + // ... + } +} + +void setup() { + Serial.begin(115200); + while(!Serial){ delay(100); } + // Create the semaphore + package_delivered_semaphore = xSemaphoreCreateCounting(10, 0); + + // Create multiple delivery truck tasks + for (int i = 0; i < 5; i++) { + xTaskCreate(delivery_truck_task, "Delivery Truck", 2048, (void *)i, tskIDLE_PRIORITY, NULL); + } + + // Create multiple warehouse worker tasks + for (int i = 0; i < 3; i++) { + xTaskCreate(warehouse_worker_task, "Warehouse Worker", 2048, (void *)i, tskIDLE_PRIORITY, NULL); + } +} + +void loop() { + // Empty loop +} \ No newline at end of file From 418ec21b64793ac90eb15d9d8023f6f523309ecf Mon Sep 17 00:00:00 2001 From: davidk88 Date: Fri, 10 Feb 2023 00:03:14 +0100 Subject: [PATCH 56/60] Add function timerAttachInterruptFlag (#7809) --- cores/esp32/esp32-hal-timer.c | 8 ++++++-- cores/esp32/esp32-hal-timer.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-timer.c b/cores/esp32/esp32-hal-timer.c index b6552b89377..87f48e5409c 100644 --- a/cores/esp32/esp32-hal-timer.c +++ b/cores/esp32/esp32-hal-timer.c @@ -221,11 +221,15 @@ bool IRAM_ATTR timerFnWrapper(void *arg){ return false; } -void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){ +void timerAttachInterruptFlag(hw_timer_t *timer, void (*fn)(void), bool edge, int intr_alloc_flags){ if(edge){ log_w("EDGE timer interrupt is not supported! Setting to LEVEL..."); } - timer_isr_callback_add(timer->group, timer->num, timerFnWrapper, fn, 0); + timer_isr_callback_add(timer->group, timer->num, timerFnWrapper, fn, intr_alloc_flags); +} + +void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){ + timerAttachInterruptFlag(timer, fn, edge, 0); } void timerDetachInterrupt(hw_timer_t *timer){ diff --git a/cores/esp32/esp32-hal-timer.h b/cores/esp32/esp32-hal-timer.h index 5bbed623586..5f0413b7445 100644 --- a/cores/esp32/esp32-hal-timer.h +++ b/cores/esp32/esp32-hal-timer.h @@ -36,6 +36,7 @@ void timerEnd(hw_timer_t *timer); void timerSetConfig(hw_timer_t *timer, uint32_t config); uint32_t timerGetConfig(hw_timer_t *timer); +void timerAttachInterruptFlag(hw_timer_t *timer, void (*fn)(void), bool edge, int intr_alloc_flags); void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge); void timerDetachInterrupt(hw_timer_t *timer); From 7c680bc9c3df40021853ce6786bad9b8d15d27b0 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 10 Feb 2023 00:50:06 +0200 Subject: [PATCH 57/60] Update CMakeLists.txt --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0fae8853b7d..b95765e1aa8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,7 +208,7 @@ set(includedirs set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS}) set(priv_includes cores/esp32/libb64) set(requires spi_flash mbedtls mdns wifi_provisioning wpa_supplicant esp_adc esp_eth http_parser) -set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support bt esp_hid esp_insights) +set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support bt esp_hid) idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires}) @@ -251,6 +251,9 @@ endfunction() maybe_add_component(esp-dsp) +if(CONFIG_ESP_INSIGHTS_ENABLED) + maybe_add_component(esp_insights) +endif() if(CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK) maybe_add_component(esp_rainmaker) maybe_add_component(qrcode) From 5cfe912147d49628580b10760113f7d72b7b24fd Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 10 Feb 2023 01:00:26 +0200 Subject: [PATCH 58/60] Update esptool to v4.4 --- package/package_esp32_index.template.json | 71 ++++++++++------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index 922c776fd63..63ae545ae02 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -64,7 +64,7 @@ { "packager": "esp32", "name": "esptool_py", - "version": "4.2.1" + "version": "4.4" }, { "packager": "esp32", @@ -385,56 +385,49 @@ }, { "name": "esptool_py", - "version": "4.2.1", + "version": "4.4", "systems": [ { - "host": "i686-mingw32", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.4/esptool-4.2.1-windows.zip", - "archiveFileName": "esptool-4.2.1-windows.zip", - "checksum": "SHA-256:582560067bfbd9895f4862eb5fdf87558ddee5d4d30e7575c9b8bcb0dd60fd94", - "size": "6368279" - }, - { - "host": "x86_64-mingw32", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.4/esptool-4.2.1-windows.zip", - "archiveFileName": "esptool-4.2.1-windows.zip", - "checksum": "SHA-256:582560067bfbd9895f4862eb5fdf87558ddee5d4d30e7575c9b8bcb0dd60fd94", - "size": "6368279" + "host": "x86_64-pc-linux-gnu", + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-src.tar.gz", + "archiveFileName": "esptool-v4.4-src.tar.gz", + "checksum": "SHA-256:185570792b9518fb5b90b6f9c25f66f07771afbb7e51175366b0e6b89c0a4129", + "size": "86666" }, { - "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.4/esptool-4.2.1-macos.tar.gz", - "archiveFileName": "esptool-4.2.1-macos.tar.gz", - "checksum": "SHA-256:a984f7ad8bdb40c42d0d368bf4bb21b69a9587aed46b7b6d7de23ca58a3f150d", - "size": "5816598" + "host": "i686-pc-linux-gnu", + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-src.tar.gz", + "archiveFileName": "esptool-v4.4-src.tar.gz", + "checksum": "SHA-256:185570792b9518fb5b90b6f9c25f66f07771afbb7e51175366b0e6b89c0a4129", + "size": "86666" }, { - "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.4/esptool-4.2.1-linux.tar.gz", - "archiveFileName": "esptool-4.2.1-linux.tar.gz", - "checksum": "SHA-256:5a45fb77eb6574554ec2f45230d0b350f26f9c24ab3b6c13c4031ebdf72a34ab", - "size": "90123" + "host": "aarch64-linux-gnu", + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-src.tar.gz", + "archiveFileName": "esptool-v4.4-src.tar.gz", + "checksum": "SHA-256:185570792b9518fb5b90b6f9c25f66f07771afbb7e51175366b0e6b89c0a4129", + "size": "86666" }, { - "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.4/esptool-4.2.1-linux.tar.gz", - "archiveFileName": "esptool-4.2.1-linux.tar.gz", - "checksum": "SHA-256:5a45fb77eb6574554ec2f45230d0b350f26f9c24ab3b6c13c4031ebdf72a34ab", - "size": "90123" + "host": "arm-linux-gnueabihf", + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-src.tar.gz", + "archiveFileName": "esptool-v4.4-src.tar.gz", + "checksum": "SHA-256:185570792b9518fb5b90b6f9c25f66f07771afbb7e51175366b0e6b89c0a4129", + "size": "86666" }, { - "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.4/esptool-4.2.1-linux.tar.gz", - "archiveFileName": "esptool-4.2.1-linux.tar.gz", - "checksum": "SHA-256:5a45fb77eb6574554ec2f45230d0b350f26f9c24ab3b6c13c4031ebdf72a34ab", - "size": "90123" + "host": "x86_64-apple-darwin", + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-macos.tar.gz", + "archiveFileName": "esptool-v4.4-macos.tar.gz", + "checksum": "SHA-256:a719a4207438e79c1c83e8b233019995b17f1311905bad83066fce2917da8fee", + "size": "5822370" }, { - "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.4/esptool-4.2.1-linux.tar.gz", - "archiveFileName": "esptool-4.2.1-linux.tar.gz", - "checksum": "SHA-256:5a45fb77eb6574554ec2f45230d0b350f26f9c24ab3b6c13c4031ebdf72a34ab", - "size": "90123" + "host": "x86_64-mingw32", + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-win64.zip", + "archiveFileName": "esptool-v4.4-win64.zip", + "checksum": "SHA-256:83cd533bf2e4716ba861d1c40b4adba7e75032e3eca488c72c05ac128a18e771", + "size": "6627040" } ] }, From cc3bcee452640750311b5e54354383257b637a57 Mon Sep 17 00:00:00 2001 From: davidk88 Date: Fri, 10 Feb 2023 00:03:14 +0100 Subject: [PATCH 59/60] Add function timerAttachInterruptFlag (#7809) From 8e939b01e53f2da53f31083de7098aa5469ec205 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 13 Feb 2023 12:21:21 +0200 Subject: [PATCH 60/60] Update esptool to v4.5 --- package/package_esp32_index.template.json | 52 +++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index 63ae545ae02..d960dcbcbc3 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -64,7 +64,7 @@ { "packager": "esp32", "name": "esptool_py", - "version": "4.4" + "version": "4.5" }, { "packager": "esp32", @@ -385,49 +385,49 @@ }, { "name": "esptool_py", - "version": "4.4", + "version": "4.5", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-src.tar.gz", - "archiveFileName": "esptool-v4.4-src.tar.gz", - "checksum": "SHA-256:185570792b9518fb5b90b6f9c25f66f07771afbb7e51175366b0e6b89c0a4129", - "size": "86666" + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.5-src.tar.gz", + "archiveFileName": "esptool-v4.5-src.tar.gz", + "checksum": "SHA-256:0f5d20c4624d913c3c994db57da3c4e5a43bd8437351d9b789f79d3f1b057292", + "size": "96621" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-src.tar.gz", - "archiveFileName": "esptool-v4.4-src.tar.gz", - "checksum": "SHA-256:185570792b9518fb5b90b6f9c25f66f07771afbb7e51175366b0e6b89c0a4129", - "size": "86666" + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.5-src.tar.gz", + "archiveFileName": "esptool-v4.5-src.tar.gz", + "checksum": "SHA-256:0f5d20c4624d913c3c994db57da3c4e5a43bd8437351d9b789f79d3f1b057292", + "size": "96621" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-src.tar.gz", - "archiveFileName": "esptool-v4.4-src.tar.gz", - "checksum": "SHA-256:185570792b9518fb5b90b6f9c25f66f07771afbb7e51175366b0e6b89c0a4129", - "size": "86666" + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.5-src.tar.gz", + "archiveFileName": "esptool-v4.5-src.tar.gz", + "checksum": "SHA-256:0f5d20c4624d913c3c994db57da3c4e5a43bd8437351d9b789f79d3f1b057292", + "size": "96621" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-src.tar.gz", - "archiveFileName": "esptool-v4.4-src.tar.gz", - "checksum": "SHA-256:185570792b9518fb5b90b6f9c25f66f07771afbb7e51175366b0e6b89c0a4129", - "size": "86666" + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.5-src.tar.gz", + "archiveFileName": "esptool-v4.5-src.tar.gz", + "checksum": "SHA-256:0f5d20c4624d913c3c994db57da3c4e5a43bd8437351d9b789f79d3f1b057292", + "size": "96621" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-macos.tar.gz", - "archiveFileName": "esptool-v4.4-macos.tar.gz", - "checksum": "SHA-256:a719a4207438e79c1c83e8b233019995b17f1311905bad83066fce2917da8fee", - "size": "5822370" + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.5-macos.tar.gz", + "archiveFileName": "esptool-v4.5-macos.tar.gz", + "checksum": "SHA-256:adcce051f282a19f78da30717ff0e4334b0edaf16a7f14d185ba4cae464586e2", + "size": "5850835" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.4-win64.zip", - "archiveFileName": "esptool-v4.4-win64.zip", - "checksum": "SHA-256:83cd533bf2e4716ba861d1c40b4adba7e75032e3eca488c72c05ac128a18e771", - "size": "6627040" + "url": "https://github.com/espressif/arduino-esp32/releases/download/2.0.6/esptool-v4.5-win64.zip", + "archiveFileName": "esptool-v4.5-win64.zip", + "checksum": "SHA-256:a55c5f7d490fbd2cd5fdf486d71f2ed13e3304482d54374b6aa23d42c9b98a96", + "size": "6639416" } ] },