diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 30ea1d013..cfed461f2 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -8,7 +8,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-16.04, windows-latest, macos-latest] - python-version: [2.7, 3.7] + python-version: [3.7] example: - "examples/arduino-blink" - "examples/arduino-briki-internal-libs" @@ -22,7 +22,9 @@ jobs: - "examples/espidf-hello-world" - "examples/espidf-http-request" - "examples/espidf-peripherals-uart" + - "examples/espidf-peripherals-usb" - "examples/espidf-storage-sdcard" + - "examples/espidf-storage-spiffs" - "examples/espidf-ulp-adc" - "examples/espidf-ulp-pulse" - "examples/pumbaa-blink" diff --git a/README.md b/README.md index ffcbdd3d1..cd538167b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Espressif 32: development platform for [PlatformIO](http://platformio.org) -![alt text](https://github.com/platformio/platform-espressif32/workflows/Examples/badge.svg "Espressif 32 development platform") +[![Build Status](https://github.com/platformio/platform-espressif32/workflows/Examples/badge.svg)](https://github.com/platformio/platform-espressif32/actions) Espressif Systems is a privately held fabless semiconductor company. They provide wireless communications and Wi-Fi chips which are widely used in mobile devices and the Internet of Things applications. diff --git a/boards/esp32-s2-kaluga-1.json b/boards/esp32-s2-kaluga-1.json new file mode 100644 index 000000000..ae785b77c --- /dev/null +++ b/boards/esp32-s2-kaluga-1.json @@ -0,0 +1,36 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32s2_out.ld" + }, + "core": "esp32", + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "mcu": "esp32s2", + "variant": "esp32s2" + }, + "connectivity": [ + "wifi" + ], + "debug": { + "default_tool": "ftdi", + "onboard_tools": [ + "ftdi" + ], + "openocd_target": "esp32s2.cfg" + }, + "frameworks": [ + "espidf" + ], + "name": "Espressif ESP32-S2-Kaluga-1 Kit", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html", + "vendor": "Espressif" +} diff --git a/boards/esp32-s2-saola-1.json b/boards/esp32-s2-saola-1.json new file mode 100644 index 000000000..ab4f9fe09 --- /dev/null +++ b/boards/esp32-s2-saola-1.json @@ -0,0 +1,32 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32s2_out.ld" + }, + "core": "esp32", + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "mcu": "esp32s2", + "variant": "esp32s2" + }, + "connectivity": [ + "wifi" + ], + "debug": { + "openocd_target": "esp32s2.cfg" + }, + "frameworks": [ + "espidf" + ], + "name": "Espressif ESP32-S2-Saola-1", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html", + "vendor": "Espressif" +} diff --git a/boards/esp32cam.json b/boards/esp32cam.json index 49c00e690..f7129392c 100644 --- a/boards/esp32cam.json +++ b/boards/esp32cam.json @@ -1,7 +1,8 @@ { "build": { "arduino":{ - "ldscript": "esp32_out.ld" + "ldscript": "esp32_out.ld", + "partitions": "huge_app.csv" }, "core": "esp32", "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", @@ -9,7 +10,6 @@ "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "huge_app.csv", "variant": "esp32" }, "connectivity": [ diff --git a/boards/esp32doit-espduino.json b/boards/esp32doit-espduino.json new file mode 100644 index 000000000..1cadd7e9a --- /dev/null +++ b/boards/esp32doit-espduino.json @@ -0,0 +1,37 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_ESP32_DEV", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "doitESPduino32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "debug": { + "openocd_board": "esp-wroom-32.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "DOIT ESPduino32", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://www.doit.am/", + "vendor": "DOIT" +} diff --git a/boards/esp32thing_plus.json b/boards/esp32thing_plus.json new file mode 100644 index 000000000..cf1a74d68 --- /dev/null +++ b/boards/esp32thing_plus.json @@ -0,0 +1,38 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld", + "partitions": "default_16MB.csv" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_ESP32_THING_PLUS", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "esp32thing_plus" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "debug": { + "openocd_board": "esp-wroom-32.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "SparkFun ESP32 Thing Plus", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.sparkfun.com/products/15663", + "vendor": "SparkFun Electronics" +} diff --git a/boards/etboard.json b/boards/etboard.json new file mode 100644 index 000000000..8ae9775d0 --- /dev/null +++ b/boards/etboard.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_ETBoard", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "ET-Board" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "ETBoard", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://et.ketri.re.kr", + "vendor": "ETBoard" +} diff --git a/boards/featheresp32-s2.json b/boards/featheresp32-s2.json new file mode 100644 index 000000000..00bf22d46 --- /dev/null +++ b/boards/featheresp32-s2.json @@ -0,0 +1,32 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32s2_out.ld" + }, + "core": "esp32", + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "mcu": "esp32s2", + "variant": "esp32s2" + }, + "connectivity": [ + "wifi" + ], + "debug": { + "openocd_target": "esp32s2.cfg" + }, + "frameworks": [ + "espidf" + ], + "name": "Adafruit ESP32-S2 Feather Development Board", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.adafruit.com/product/4769", + "vendor": "Adafruit" +} diff --git a/boards/healthypi4.json b/boards/healthypi4.json new file mode 100644 index 000000000..bfebc98a8 --- /dev/null +++ b/boards/healthypi4.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_HEALTHYPI_4", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "healthypi4" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "ProtoCentral HealthyPi 4", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://healthypi.protocentral.com", + "vendor": "ProtoCentral" +} diff --git a/boards/heltec_wifi_kit_32_v2.json b/boards/heltec_wifi_kit_32_v2.json new file mode 100644 index 000000000..eb80db671 --- /dev/null +++ b/boards/heltec_wifi_kit_32_v2.json @@ -0,0 +1,35 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld", + "partitions": "default_8MB.csv" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_HELTEC_WIFI_KIT_32", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "heltec_wifi_kit_32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Heltec WiFi Kit 32 (V2)", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 8388608, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://www.heltec.cn/project/wifi-kit-32/?lang=en", + "vendor": "Heltec Automation" +} diff --git a/boards/heltec_wifi_lora_32_V2.json b/boards/heltec_wifi_lora_32_V2.json index 4fa8a6434..c2a0f950a 100644 --- a/boards/heltec_wifi_lora_32_V2.json +++ b/boards/heltec_wifi_lora_32_V2.json @@ -1,7 +1,8 @@ { "build": { "arduino":{ - "ldscript": "esp32_out.ld" + "ldscript": "esp32_out.ld", + "partitions": "default_8MB.csv" }, "core": "esp32", "extra_flags": "-DARDUINO_HELTEC_WIFI_LORA_32_V2", @@ -9,7 +10,6 @@ "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "default_8MB.csv", "variant": "heltec_wifi_lora_32_V2" }, "connectivity": [ diff --git a/boards/heltec_wireless_stick.json b/boards/heltec_wireless_stick.json index f3a101627..1f09ca497 100644 --- a/boards/heltec_wireless_stick.json +++ b/boards/heltec_wireless_stick.json @@ -1,7 +1,8 @@ { "build": { "arduino":{ - "ldscript": "esp32_out.ld" + "ldscript": "esp32_out.ld", + "partitions": "default_8MB.csv" }, "core": "esp32", "extra_flags": "-DARDUINO_HELTEC_WIRELESS_STICK", @@ -9,7 +10,6 @@ "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "default_8MB.csv", "variant": "heltec_wireless_stick" }, "connectivity": [ diff --git a/boards/heltec_wireless_stick_lite.json b/boards/heltec_wireless_stick_lite.json new file mode 100644 index 000000000..6ffac9acf --- /dev/null +++ b/boards/heltec_wireless_stick_lite.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_HELTEC_WIRELESS_STICK_LITE", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "heltec_wireless_stick_lite" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Heltec Wireless Stick Lite", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://heltec.org/project/wireless-stick-lite/", + "vendor": "Heltec Automation" +} diff --git a/boards/honeylemon.json b/boards/honeylemon.json new file mode 100644 index 000000000..c3796dfe0 --- /dev/null +++ b/boards/honeylemon.json @@ -0,0 +1,37 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_HONEYLEMON", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "honeylemon" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "debug": { + "openocd_board": "esp-wroom-32.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "HONEYLemon", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://en.wikipedia.org/wiki/ESP32", + "vendor": "HONEYLemon" +} diff --git a/boards/imbrios-logsens-v1p1.json b/boards/imbrios-logsens-v1p1.json new file mode 100644 index 000000000..a65362f98 --- /dev/null +++ b/boards/imbrios-logsens-v1p1.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_IMBRIOS_LOGSENS_V1P1", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "imbrios-logsens-v1p1" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Imbrios LogSens V1P1", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.imbrios.com/products/logsens", + "vendor": "Imbrios" +} diff --git a/boards/inex_openkb.json b/boards/inex_openkb.json new file mode 100644 index 000000000..8f326d5f3 --- /dev/null +++ b/boards/inex_openkb.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_openkb", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "openkb" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "INEX OpenKB", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://inex.co.th/home/product/openkb/", + "vendor": "INEX" +} diff --git a/boards/kits-edu.json b/boards/kits-edu.json new file mode 100644 index 000000000..6ec72aef9 --- /dev/null +++ b/boards/kits-edu.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_ESP32_PICO", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "pico32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "KITS ESP32 EDU", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://www.koreaits.com/new/product/summary.htm?goods_no=468&mid_no=103&no=17", + "vendor": "KITS" +} diff --git a/boards/labplus_mpython.json b/boards/labplus_mpython.json new file mode 100644 index 000000000..255edcc9b --- /dev/null +++ b/boards/labplus_mpython.json @@ -0,0 +1,35 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld", + "partitions": "huge_app.csv" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_ESP32_DEV", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "mpython" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Labplus mPython", + "upload": { + "flash_size": "8MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/labplus-cn/mpython", + "vendor": "Labplus" +} diff --git a/boards/lolin32_lite.json b/boards/lolin32_lite.json new file mode 100644 index 000000000..5e16bc85a --- /dev/null +++ b/boards/lolin32_lite.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_LOLIN32_LITE", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "lolin32-lite" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "WEMOS LOLIN32 Lite", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://diyprojects.io/wemos-lolin32-lite-compact-revision-lolin32-4-90/", + "vendor": "WEMOS" +} diff --git a/boards/lolin_d32_pro.json b/boards/lolin_d32_pro.json index 18bfcf8a4..732b07318 100644 --- a/boards/lolin_d32_pro.json +++ b/boards/lolin_d32_pro.json @@ -4,7 +4,7 @@ "ldscript": "esp32_out.ld" }, "core": "esp32", - "extra_flags": "-DARDUINO_LOLIN_D32_PRO", + "extra_flags": "-DARDUINO_LOLIN_D32_PRO -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", "f_cpu": "240000000L", "f_flash": "40000000L", "flash_mode": "dio", @@ -18,7 +18,7 @@ "can" ], "debug": { - "openocd_board": "esp-wroom-32.cfg" + "openocd_board": "esp32-wrover.cfg" }, "frameworks": [ "arduino", @@ -32,6 +32,6 @@ "require_upload_port": true, "speed": 460800 }, - "url": "https://wiki.wemos.cc/products:d32:d32_pro", + "url": "https://www.wemos.cc/en/latest/d32/d32_pro.html", "vendor": "WEMOS" } diff --git a/boards/m5stack-atom.json b/boards/m5stack-atom.json new file mode 100644 index 000000000..fd704b0d1 --- /dev/null +++ b/boards/m5stack-atom.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_M5Stack_ATOM", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "m5stack_atom" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "M5Stack-ATOM", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 1500000 + }, + "url": "http://www.m5stack.com", + "vendor": "M5Stack" +} diff --git a/boards/m5stack-core2.json b/boards/m5stack-core2.json new file mode 100644 index 000000000..97fd5a35d --- /dev/null +++ b/boards/m5stack-core2.json @@ -0,0 +1,35 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld", + "partitions": "default_16MB.csv" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_M5STACK_Core2 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "m5stack_core2" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "M5Stack Core2", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 6553600, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://www.m5stack.com", + "vendor": "M5Stack" +} diff --git a/boards/m5stack-coreink.json b/boards/m5stack-coreink.json new file mode 100644 index 000000000..f5aee0d7b --- /dev/null +++ b/boards/m5stack-coreink.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_M5Stack_CoreInk", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "m5stack_coreink" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "M5Stick-Core Ink", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://www.m5stack.com", + "vendor": "M5Stack" +} diff --git a/boards/m5stack-fire.json b/boards/m5stack-fire.json index 36ad0a619..59001916c 100644 --- a/boards/m5stack-fire.json +++ b/boards/m5stack-fire.json @@ -1,15 +1,15 @@ { "build": { "arduino":{ - "ldscript": "esp32_out.ld" + "ldscript": "esp32_out.ld", + "partitions": "default_16MB.csv" }, "core": "esp32", - "extra_flags": "-DARDUINO_M5STACK_FIRE", + "extra_flags": "-DARDUINO_M5STACK_FIRE -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", "f_cpu": "240000000L", "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "default_16MB.csv", "variant": "m5stack_fire" }, "connectivity": [ diff --git a/boards/m5stack-timer-cam.json b/boards/m5stack-timer-cam.json new file mode 100644 index 000000000..41ff2a809 --- /dev/null +++ b/boards/m5stack-timer-cam.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_M5Stack_Timer_CAM -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "m5stack_timer_cam" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "M5Stack Timer CAM", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://www.m5stack.com", + "vendor": "M5Stack" +} diff --git a/boards/mgbot-iotik32a.json b/boards/mgbot-iotik32a.json new file mode 100644 index 000000000..7cab2a56e --- /dev/null +++ b/boards/mgbot-iotik32a.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_MGBOT_IOTIK32A", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "mgbot-iotik32a" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "MGBOT IOTIK 32A", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://iotik.ru/en/iotik32a/", + "vendor": "MGBOT" +} diff --git a/boards/mgbot-iotik32b.json b/boards/mgbot-iotik32b.json new file mode 100644 index 000000000..86e1cce2c --- /dev/null +++ b/boards/mgbot-iotik32b.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_MGBOT_IOTIK32B", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "mgbot-iotik32b" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "MGBOT IOTIK 32B", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://iotik.ru/en/iotik32b/", + "vendor": "MGBOT" +} diff --git a/boards/nina_w10.json b/boards/nina_w10.json index 3cc9a3873..a0041df2f 100644 --- a/boards/nina_w10.json +++ b/boards/nina_w10.json @@ -1,7 +1,8 @@ { "build": { "arduino":{ - "ldscript": "esp32_out.ld" + "ldscript": "esp32_out.ld", + "partitions": "minimal.csv" }, "core": "esp32", "extra_flags": "-DARDUINO_UBLOX_NINA_W10", @@ -9,7 +10,6 @@ "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "minimal.csv", "variant": "nina_w10" }, "connectivity": [ diff --git a/boards/nscreen-32.json b/boards/nscreen-32.json new file mode 100644 index 000000000..07cfcc83b --- /dev/null +++ b/boards/nscreen-32.json @@ -0,0 +1,40 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_ESP32_DEV", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "hwids": [ + [ + "0x0403", + "0x6010" + ] + ], + "mcu": "esp32", + "variant": "esp32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "YeaCreate NSCREEN-32", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://yeacreate.com", + "vendor": "YeaCreate" +} diff --git a/boards/odroid_esp32.json b/boards/odroid_esp32.json index cfeb7359f..74a9398c3 100644 --- a/boards/odroid_esp32.json +++ b/boards/odroid_esp32.json @@ -4,7 +4,7 @@ "ldscript": "esp32_out.ld" }, "core": "esp32", - "extra_flags": "-DARDUINO_ODROID_ESP32", + "extra_flags": "-DARDUINO_ODROID_ESP32 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", "f_cpu": "240000000L", "f_flash": "40000000L", "flash_mode": "dio", diff --git a/boards/oroca_edubot.json b/boards/oroca_edubot.json index 52e21491f..2a99c8c6c 100644 --- a/boards/oroca_edubot.json +++ b/boards/oroca_edubot.json @@ -1,7 +1,8 @@ { "build": { "arduino":{ - "ldscript": "esp32_out.ld" + "ldscript": "esp32_out.ld", + "partitions": "huge_app.csv" }, "core": "esp32", "extra_flags": "-DARDUINO_OROCA_EDUBOT", @@ -9,7 +10,6 @@ "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "huge_app.csv", "variant": "oroca_edubot" }, "connectivity": [ diff --git a/boards/piranha_esp32.json b/boards/piranha_esp32.json new file mode 100644 index 000000000..acd8a231a --- /dev/null +++ b/boards/piranha_esp32.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_Piranha", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "piranha_esp-32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Fishino Piranha ESP-32", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://fishino.it/boards.html", + "vendor": "Fishino" +} diff --git a/boards/s_odi_ultra.json b/boards/s_odi_ultra.json new file mode 100644 index 000000000..3a0307867 --- /dev/null +++ b/boards/s_odi_ultra.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_ESP32_DEV", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "S_ODI_Ultra_v1" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "S.ODI Ultra v1", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.espressif.com/en/products/socs/esp32", + "vendor": "S.ODI" +} diff --git a/boards/sensesiot_weizen.json b/boards/sensesiot_weizen.json new file mode 100644 index 000000000..4492655c4 --- /dev/null +++ b/boards/sensesiot_weizen.json @@ -0,0 +1,37 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_sensesiot_weizen", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "esp32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "debug": { + "openocd_board": "esp32-wrover.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "LOGISENSES Senses Weizen", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.logisenses.com/index.php/product/senses-weizen/", + "vendor": "LOGISENSES" +} diff --git a/boards/tinypico.json b/boards/tinypico.json index 883abb412..6a8b88c87 100644 --- a/boards/tinypico.json +++ b/boards/tinypico.json @@ -4,7 +4,7 @@ "ldscript": "esp32_out.ld" }, "core": "esp32", - "extra_flags": "-DARDUINO_ESP32_PICO -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", + "extra_flags": "-DARDUINO_TINYPICO -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", "f_cpu": "240000000L", "f_flash": "40000000L", "flash_mode": "qio", diff --git a/boards/ttgo-lora32-v21.json b/boards/ttgo-lora32-v21.json new file mode 100644 index 000000000..c2fb118b3 --- /dev/null +++ b/boards/ttgo-lora32-v21.json @@ -0,0 +1,37 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_TTGO_LoRa32_v21new", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "ttgo-lora32-v21new" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "debug": { + "openocd_board": "esp-wroom-32.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "TTGO LoRa32-OLED v2.1.6", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/LilyGO/TTGO-LoRa32-V2.1", + "vendor": "TTGO" +} diff --git a/boards/ttgo-t-beam.json b/boards/ttgo-t-beam.json index 4bd5fe004..f2d144aa2 100644 --- a/boards/ttgo-t-beam.json +++ b/boards/ttgo-t-beam.json @@ -9,7 +9,7 @@ "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "variant": "t-beam" + "variant": "tbeam" }, "connectivity": [ "wifi", diff --git a/boards/ttgo-t-watch.json b/boards/ttgo-t-watch.json index a47a4a07d..c58c273f3 100644 --- a/boards/ttgo-t-watch.json +++ b/boards/ttgo-t-watch.json @@ -1,15 +1,15 @@ { "build": { "arduino":{ - "ldscript": "esp32_out.ld" + "ldscript": "esp32_out.ld", + "partitions": "default_16MB.csv" }, "core": "esp32", - "extra_flags": "-DARDUINO_T-Watch -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", + "extra_flags": "-DARDUINO_TWATCH_BASE -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue", "f_cpu": "240000000L", "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "default_16MB.csv", "variant": "twatch" }, "connectivity": [ diff --git a/boards/ttgo-t7-v13-mini32.json b/boards/ttgo-t7-v13-mini32.json new file mode 100644 index 000000000..531dbb78b --- /dev/null +++ b/boards/ttgo-t7-v13-mini32.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_TTGO_T7_V13_Mini32", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "ttgo-t7-v13-mini32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "can", + "ethernet" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "TTGO T7 V1.3 Mini32", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 1310720, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/LilyGO/ESP32-MINI-32-V1.3", + "vendor": "TTGO" +} diff --git a/boards/ttgo-t7-v14-mini32.json b/boards/ttgo-t7-v14-mini32.json new file mode 100644 index 000000000..a5d5a7aaa --- /dev/null +++ b/boards/ttgo-t7-v14-mini32.json @@ -0,0 +1,37 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_TTGO_T7_V14_Mini32", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "ttgo-t7-v14-mini32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "can", + "ethernet" + ], + "debug": { + "openocd_board": "esp32-wrover.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "TTGO T7 V1.4 Mini32", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 1310720, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "http://www.lilygo.cn/prod_view.aspx?TypeId=50033&Id=978&FId=t3:50033:3", + "vendor": "TTGO" +} diff --git a/boards/wifiduino32.json b/boards/wifiduino32.json new file mode 100644 index 000000000..53ca00942 --- /dev/null +++ b/boards/wifiduino32.json @@ -0,0 +1,34 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_Wifiduino32", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "wifiduino32" + }, + "connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" + ], + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Blinker WiFiduino32", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://diandeng.tech", + "vendor": "Blinker" +} diff --git a/builder/frameworks/_embed_files.py b/builder/frameworks/_embed_files.py index 75d1a8639..d64db75a3 100644 --- a/builder/frameworks/_embed_files.py +++ b/builder/frameworks/_embed_files.py @@ -104,9 +104,9 @@ def embed_files(files, files_type): def transform_to_asm(target, source, env): files = [join("$BUILD_DIR", s.name + ".S") for s in source] - env.AppendUnique(PIOBUILDFILES=files) return files, source + env.Append( BUILDERS=dict( TxtToBin=Builder( @@ -155,7 +155,7 @@ def transform_to_asm(target, source, env): "Generating assembly for $TARGET", ), emitter=transform_to_asm, - single_source=True + single_source=True, ), ) ) diff --git a/builder/frameworks/espidf.py b/builder/frameworks/espidf.py index cb7487e7d..a8526500a 100644 --- a/builder/frameworks/espidf.py +++ b/builder/frameworks/espidf.py @@ -45,9 +45,7 @@ platform = env.PioPlatform() board = env.BoardConfig() mcu = board.get("build.mcu", "esp32") -idf_variant = board.get( - "build.esp-idf.variant", "esp32s2beta" if mcu == "esp32s2" else "esp32" -) +idf_variant = mcu.lower() FRAMEWORK_DIR = platform.get_package_dir("framework-espidf") TOOLCHAIN_DIR = platform.get_package_dir( @@ -136,7 +134,7 @@ def is_cmake_reconfigure_required(cmake_api_reply_dir): return True if any( os.path.getmtime(f) > os.path.getmtime(cmake_cache_file) - for f in cmake_txt_files + [cmake_preconf_dir] + for f in cmake_txt_files + [cmake_preconf_dir, FRAMEWORK_DIR] ): return True @@ -313,6 +311,16 @@ def get_app_defines(app_config): def extract_link_args(target_config): + def _add_to_libpath(lib_path, link_args): + if lib_path not in link_args["LIBPATH"]: + link_args["LIBPATH"].append(lib_path) + + def _add_archive(archive_path, link_args): + archive_name = os.path.basename(archive_path) + if archive_name not in link_args["LIBS"]: + _add_to_libpath(os.path.dirname(archive_path), link_args) + link_args["LIBS"].append(archive_name) + link_args = {"LINKFLAGS": [], "LIBS": [], "LIBPATH": [], "__LIB_DEPS": []} for f in target_config.get("link", {}).get("commandFragments", []): @@ -328,23 +336,27 @@ def extract_link_args(target_config): link_args["LIBS"].extend(args) elif fragment.startswith("-L"): lib_path = fragment.replace("-L", "").strip() - if lib_path not in link_args["LIBPATH"]: - link_args["LIBPATH"].append(lib_path) + _add_to_libpath(lib_path, link_args) elif fragment.startswith("-") and not fragment.startswith("-l"): # CMake mistakenly marks LINKFLAGS as libraries link_args["LINKFLAGS"].extend(args) - elif os.path.isfile(fragment) and os.path.isabs(fragment): - # In case of precompiled archives from framework package - lib_path = os.path.dirname(fragment) - if lib_path not in link_args["LIBPATH"]: - link_args["LIBPATH"].append(os.path.dirname(fragment)) - link_args["LIBS"].extend( - [os.path.basename(lib) for lib in args if lib.endswith(".a")] - ) elif fragment.endswith(".a"): - link_args["__LIB_DEPS"].extend( - [os.path.basename(lib) for lib in args if lib.endswith(".a")] - ) + archive_path = fragment + # process static archives + if archive_path.startswith(FRAMEWORK_DIR): + # In case of precompiled archives from framework package + _add_archive(archive_path, link_args) + else: + # In case of archives within project + if archive_path.startswith(".."): + # Precompiled archives from project component + _add_archive( + os.path.normpath(os.path.join(BUILD_DIR, archive_path)), + link_args, + ) + else: + # Internally built libraries used for dependency resolution + link_args["__LIB_DEPS"].append(os.path.basename(archive_path)) return link_args @@ -499,7 +511,9 @@ def generate_project_ld_script(sdk_config, ignore_targets=None): "env_file": os.path.join("$BUILD_DIR", "config.env"), "libraries_list": libraries_list, "objdump": os.path.join( - TOOLCHAIN_DIR, "bin", env.subst("$CC").replace("-gcc", "-objdump"), + TOOLCHAIN_DIR, + "bin", + env.subst("$CC").replace("-gcc", "-objdump"), ), } @@ -564,26 +578,34 @@ def prepare_build_envs(config, default_env): def compile_source_files(config, default_env, project_src_dir, prepend_dir=None): build_envs = prepare_build_envs(config, default_env) objects = [] + components_dir = fs.to_unix_path(os.path.join(FRAMEWORK_DIR, "components")) for source in config.get("sources", []): if source["path"].endswith(".rule"): continue compile_group_idx = source.get("compileGroupIndex") if compile_group_idx is not None: + src_dir = config["paths"]["source"] + if not os.path.isabs(src_dir): + src_dir = os.path.join(project_src_dir, config["paths"]["source"]) src_path = source.get("path") if not os.path.isabs(src_path): # For cases when sources are located near CMakeLists.txt src_path = os.path.join(project_src_dir, src_path) - local_path = config["paths"]["source"] - if not os.path.isabs(local_path): - local_path = os.path.join(project_src_dir, config["paths"]["source"]) - obj_path = os.path.join( - "$BUILD_DIR", prepend_dir or "", config["paths"]["build"] - ) + + obj_path = os.path.join("$BUILD_DIR", prepend_dir or "") + if src_path.startswith(components_dir): + obj_path = os.path.join( + obj_path, os.path.relpath(src_path, components_dir) + ) + else: + if not os.path.isabs(source["path"]): + obj_path = os.path.join(obj_path, source["path"]) + else: + obj_path = os.path.join(obj_path, os.path.basename(src_path)) + objects.append( build_envs[compile_group_idx].StaticObject( - target=os.path.join( - obj_path, os.path.relpath(src_path, local_path) + ".o" - ), + target=os.path.splitext(obj_path)[0] + ".o", source=os.path.realpath(src_path), ) ) @@ -803,19 +825,194 @@ def find_default_component(target_configs): return "" -def create_verion_file(): +def create_version_file(): version_file = os.path.join(FRAMEWORK_DIR, "version.txt") if not os.path.isfile(version_file): with open(version_file, "w") as fp: fp.write(platform.get_package_version("framework-espidf")) -# +def generate_empty_partition_image(binary_path, image_size): + empty_partition = env.Command( + binary_path, + None, + env.VerboseAction( + '"$PYTHONEXE" "%s" %s $TARGET' + % ( + os.path.join( + FRAMEWORK_DIR, + "components", + "partition_table", + "gen_empty_partition.py", + ), + image_size, + ), + "Generating an empty partition $TARGET", + ), + ) + + env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", empty_partition) + + +def get_partition_info(pt_path, pt_offset, pt_params): + if not os.path.isfile(pt_path): + sys.stderr.write( + "Missing partition table file `%s`\n" % os.path.basename(pt_path) + ) + env.Exit(1) + + cmd = [ + env.subst("$PYTHONEXE"), + os.path.join(FRAMEWORK_DIR, "components", "partition_table", "parttool.py"), + "-q", + "--partition-table-offset", + hex(pt_offset), + "--partition-table-file", + pt_path, + "get_partition_info", + "--info", + "size", + "offset", + ] + + if pt_params["name"] == "boot": + cmd.append("--partition-boot-default") + else: + cmd.extend( + [ + "--partition-type", + pt_params["type"], + "--partition-subtype", + pt_params["subtype"], + ] + ) + + result = exec_command(cmd) + if result["returncode"] != 0: + sys.stderr.write( + "Couldn't extract information for %s/%s from the partition table\n" + % (pt_params["type"], pt_params["subtype"]) + ) + sys.stderr.write(result["out"] + "\n") + sys.stderr.write(result["err"] + "\n") + env.Exit(1) + + size = offset = 0 + if result["out"].strip(): + size, offset = result["out"].strip().split(" ", 1) + + return {"size": size, "offset": offset} + + +def get_app_partition_offset(pt_table, pt_offset): + # Get the default boot partition offset + app_params = get_partition_info(pt_table, pt_offset, {"name": "boot"}) + return app_params.get("offset", "0x10000") + + +def build_tinyusb_lib(env): + tinyusb_dir = os.path.join(FRAMEWORK_DIR, "components", "tinyusb") + if not os.path.isdir(tinyusb_dir): + return + + envsafe = env.Clone() + envsafe.Replace( + CFLAGS=[], + CXXFLAGS=[], + CCFLAGS=["-mlongcalls"], + CPPDEFINES=[ + "HAVE_CONFIG_H", + ("MBEDTLS_CONFIG_FILE", '\\"mbedtls/esp_config.h\\"'), + "UNITY_INCLUDE_CONFIG_H", + "WITH_POSIX", + ("CFG_TUSB_MCU", "OPT_MCU_ESP32_S2"), + ], + ) + + envsafe.BuildSources( + os.path.join("$BUILD_DIR", "tinyusb"), + tinyusb_dir, + src_filter=[ + "-<*>", + "+", + "+", + "+", + "+", + "+", + "+", + "+", + "+", + "+", + "+", + "+", + "+", + ], + ) + + +def generate_mbedtls_bundle(sdk_config): + bundle_path = os.path.join("$BUILD_DIR", "x509_crt_bundle") + if os.path.isfile(env.subst(bundle_path)): + return + + default_crt_dir = os.path.join( + FRAMEWORK_DIR, "components", "mbedtls", "esp_crt_bundle" + ) + + cmd = [env.subst("$PYTHONEXE"), os.path.join(default_crt_dir, "gen_crt_bundle.py")] + + crt_args = ["--input"] + if sdk_config.get("MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL", False): + crt_args.append(os.path.join(default_crt_dir, "cacrt_all.pem")) + elif sdk_config.get("MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN", False): + crt_args.append(os.path.join(default_crt_dir, "cacrt_all.pem")) + cmd.extend( + ["--filter", os.path.join(default_crt_dir, "cmn_crt_authorities.csv")] + ) + + if sdk_config.get("MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE", False): + cert_path = sdk_config.get("MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH", "") + if os.path.isfile(cert_path) or os.path.isdir(cert_path): + crt_args.append(os.path.abspath(cert_path)) + else: + print("Warning! Couldn't find custom certificate bundle %s" % cert_path) + + crt_args.append("-q") + + # Use exec_command to change working directory + exec_command(cmd + crt_args, cwd=env.subst("$BUILD_DIR")) + bundle_path = os.path.join("$BUILD_DIR", "x509_crt_bundle") + env.Execute( + env.VerboseAction( + " ".join( + [ + os.path.join( + env.PioPlatform().get_package_dir("tool-cmake"), + "bin", + "cmake", + ), + "-DDATA_FILE=" + bundle_path, + "-DSOURCE_FILE=%s.S" % bundle_path, + "-DFILE_TYPE=BINARY", + "-P", + os.path.join( + FRAMEWORK_DIR, + "tools", + "cmake", + "scripts", + "data_file_embed_asm.cmake", + ), + ] + ), + "Generating assembly for certificate bundle...", + ) + ) + + # ESP-IDF package doesn't contain .git folder, instead package version is specified # in a special file "version.h" in the root folder of the package -# -create_verion_file() +create_version_file() # # Generate final linker script @@ -845,6 +1042,7 @@ def create_verion_file(): fwpartitions_dir = os.path.join(FRAMEWORK_DIR, "components", "partition_table") partitions_csv = board.get("build.partitions", "partitions_singleapp.csv") + env.Replace( PARTITIONS_TABLE_CSV=os.path.abspath( os.path.join(fwpartitions_dir, partitions_csv) @@ -912,7 +1110,9 @@ def create_verion_file(): BUILD_DIR, [ "-DIDF_TARGET=" + idf_variant, + "-DPYTHON_DEPS_CHECKED=1", "-DEXTRA_COMPONENT_DIRS:PATH=" + ";".join(extra_components), + "-DPYTHON=" + env.subst("$PYTHONEXE"), ] + click.parser.split_arg_string(board.get("build.cmake_extra_args", "")), ) @@ -927,7 +1127,6 @@ def create_verion_file(): sdk_config = get_sdk_configuration() - project_target_name = "__idf_%s" % os.path.basename(env.subst("$PROJECT_SRC_DIR")) if project_target_name not in target_configs: sys.stderr.write("Error: Couldn't find the main target of the project!\n") @@ -1057,6 +1256,7 @@ def _skip_prj_source_files(node): ) ) +partition_table_offset = sdk_config.get("PARTITION_TABLE_OFFSET", 0x8000) project_flags.update(link_args) env.MergeFlags(project_flags) env.Prepend( @@ -1067,16 +1267,32 @@ def _skip_prj_source_files(node): FLASH_EXTRA_IMAGES=[ ( board.get("upload.bootloader_offset", "0x1000"), - os.path.join("$BUILD_DIR", "bootloader.bin") + os.path.join("$BUILD_DIR", "bootloader.bin"), ), ( - board.get("upload.partition_table_offset", hex( - sdk_config.get("PARTITION_TABLE_OFFSET", 0x8000))), - os.path.join("$BUILD_DIR", "partitions.bin") + board.get("upload.partition_table_offset", hex(partition_table_offset)), + os.path.join("$BUILD_DIR", "partitions.bin"), ), ], ) +# USB stack for ESP32-S2 is implemented using tinyusb library. In IDF v4.2 it's added as +# an INTERFACE library which means that CMake doesn't export build information for it +# in File-API hence it's not present in components map. As a workaround we can build +# the lib using project build environment with additional flags from CMakeLists.txt +if ( + sdk_config.get("USB_ENABLED", False) + and "__idf_tinyusb" not in framework_components_map +): + build_tinyusb_lib(env) + +# +# Generate mbedtls bundle +# + +if sdk_config.get("MBEDTLS_CERTIFICATE_BUNDLE", False): + generate_mbedtls_bundle(sdk_config) + # # To embed firmware checksum a special argument for esptool.py is required # @@ -1094,3 +1310,42 @@ def _skip_prj_source_files(node): ulp_dir = os.path.join(env.subst("$PROJECT_DIR"), "ulp") if os.path.isdir(ulp_dir) and os.listdir(ulp_dir): env.SConscript("ulp.py", exports="env project_config idf_variant") + +# +# Process OTA partition and image +# + +ota_partition_params = get_partition_info( + env.subst("$PARTITIONS_TABLE_CSV"), + partition_table_offset, + {"name": "ota", "type": "data", "subtype": "ota"}, +) + +if ota_partition_params["size"] and ota_partition_params["offset"]: + # Generate an empty image if OTA is enabled in partition table + ota_partition_image = os.path.join("$BUILD_DIR", "ota_data_initial.bin") + generate_empty_partition_image(ota_partition_image, ota_partition_params["size"]) + + env.Append( + FLASH_EXTRA_IMAGES=[ + ( + board.get( + "upload.ota_partition_offset", ota_partition_params["offset"] + ), + ota_partition_image, + ) + ] + ) + +# +# Configure application partition offset +# + +env.Replace( + ESP32_APP_OFFSET=get_app_partition_offset( + env.subst("$PARTITIONS_TABLE_CSV"), partition_table_offset + ) +) + +# Propagate application offset to debug configurations +env["IDE_EXTRA_DATA"].update({"application_offset": env.subst("$ESP32_APP_OFFSET")}) diff --git a/builder/frameworks/ulp.py b/builder/frameworks/ulp.py index ffd80bcea..d849c0c76 100644 --- a/builder/frameworks/ulp.py +++ b/builder/frameworks/ulp.py @@ -26,15 +26,24 @@ FRAMEWORK_DIR = platform.get_package_dir("framework-espidf") BUILD_DIR = ulp_env.subst("$BUILD_DIR") ULP_BUILD_DIR = os.path.join( - BUILD_DIR, "esp-idf", project_config["name"].replace("__idf_", ""), "ulp_main") + BUILD_DIR, "esp-idf", project_config["name"].replace("__idf_", ""), "ulp_main" +) def prepare_ulp_env_vars(env): - ulp_env.PrependENVPath("IDF_PATH", platform.get_package_dir("framework-espidf")) + ulp_env.PrependENVPath("IDF_PATH", FRAMEWORK_DIR) additional_packages = [ - os.path.join(platform.get_package_dir("toolchain-xtensa32"), "bin"), - os.path.join(platform.get_package_dir("toolchain-esp32ulp"), "bin"), + os.path.join( + platform.get_package_dir( + "toolchain-xtensa%s" % ("32s2" if idf_variant == "esp32s2" else "32") + ), + "bin", + ), + os.path.join( + platform.get_package_dir("toolchain-%sulp" % idf_variant), + "bin", + ), platform.get_package_dir("tool-ninja"), os.path.join(platform.get_package_dir("tool-cmake"), "bin"), os.path.dirname(where_is_program("python")), @@ -74,7 +83,7 @@ def generate_ulp_config(target_config): "-DCMAKE_GENERATOR=Ninja", "-DCMAKE_TOOLCHAIN_FILE=" + os.path.join( - platform.get_package_dir("framework-espidf"), + FRAMEWORK_DIR, "components", "ulp", "cmake", diff --git a/builder/main.py b/builder/main.py index bff5d70a0..0172f327a 100644 --- a/builder/main.py +++ b/builder/main.py @@ -112,8 +112,9 @@ def fetch_spiffs_size(env): spiffs = p if not spiffs: sys.stderr.write( - env.subst("Could not find the `spiffs` section in the partitions " - "table $PARTITIONS_TABLE_CSV\n")) + "Could not find the `spiffs` section in the partitions " + "table %s\n" % env.subst("$PARTITIONS_TABLE_CSV") + ) env.Exit(1) return env["SPIFFS_START"] = _parse_size(spiffs['offset']) @@ -163,6 +164,7 @@ def __fetch_spiffs_size(target, source, env): MKSPIFFSTOOL="mkspiffs_${PIOPLATFORM}_" + ("espidf" if "espidf" in env.subst( "$PIOFRAMEWORK") else "${PIOFRAMEWORK}"), ESP32_SPIFFS_IMAGE_NAME=env.get("ESP32_SPIFFS_IMAGE_NAME", "spiffs"), + ESP32_APP_OFFSET="0x10000", PROGSUFFIX=".elf" ) @@ -229,8 +231,9 @@ def __fetch_spiffs_size(target, source, env): else: target_firm = env.ElfToBin( join("$BUILD_DIR", "${PROGNAME}"), target_elf) + env.Depends(target_firm, "checkprogsize") -env.AddPlatformTarget("buildfs", target_firm, None, "Build Filesystem Image") +env.AddPlatformTarget("buildfs", target_firm, target_firm, "Build Filesystem Image") AlwaysBuild(env.Alias("nobuild", target_firm)) target_buildprog = env.Alias("buildprog", target_firm, target_firm) @@ -291,8 +294,8 @@ def __fetch_spiffs_size(target, source, env): UPLOADERFLAGS=["--debug", "--progress", "-i", "$UPLOAD_PORT"], UPLOADCMD='"$PYTHONEXE" "$UPLOADER" $UPLOADERFLAGS -f $SOURCE' ) - if "uploadfs" in COMMAND_LINE_TARGETS: - env.Append(UPLOADERFLAGS=["-s"]) + if set(["uploadfs", "uploadfsota"]) & set(COMMAND_LINE_TARGETS): + env.Append(UPLOADERFLAGS=["--spiffs"]) upload_actions = [env.VerboseAction("$UPLOADCMD", "Uploading $SOURCE")] elif upload_protocol == "esptool": @@ -310,7 +313,7 @@ def __fetch_spiffs_size(target, source, env): "--flash_freq", "${__get_board_f_flash(__env__)}", "--flash_size", "detect" ], - UPLOADCMD='"$PYTHONEXE" "$UPLOADER" $UPLOADERFLAGS 0x10000 $SOURCE' + UPLOADCMD='"$PYTHONEXE" "$UPLOADER" $UPLOADERFLAGS $ESP32_APP_OFFSET $SOURCE' ) for image in env.get("FLASH_EXTRA_IMAGES", []): env.Append(UPLOADERFLAGS=[image[0], env.subst(image[1])]) @@ -370,14 +373,15 @@ def __fetch_spiffs_size(target, source, env): openocd_args.extend( debug_tools.get(upload_protocol).get("server").get("arguments", [])) openocd_args.extend([ + "-c", "adapter_khz %s" % env.GetProjectOption("debug_speed", "5000"), "-c", - "program_esp32 {{$SOURCE}} %s verify" % - board.get("upload.offset_address", "0x10000") + "program_esp {{$SOURCE}} %s verify" % + board.get("upload.offset_address", "$ESP32_APP_OFFSET"), ]) for image in env.get("FLASH_EXTRA_IMAGES", []): openocd_args.extend([ "-c", - 'program_esp32 {{%s}} %s verify' % + 'program_esp {{%s}} %s verify' % (_to_unix_slashes(image[1]), image[0]) ]) openocd_args.extend(["-c", "reset run; shutdown"]) diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index ad383a4f3..b9bd7f537 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -27,3 +27,8 @@ platform = espressif32 framework = arduino board = lolin32 monitor_speed = 115200 + +[env:ttgo-lora32-v21] +platform = espressif32 +framework = arduino +board = ttgo-lora32-v21 diff --git a/examples/espidf-aws-iot/src/CMakeLists.txt b/examples/espidf-aws-iot/src/CMakeLists.txt index 2d7bac1e6..807ad6ea0 100644 --- a/examples/espidf-aws-iot/src/CMakeLists.txt +++ b/examples/espidf-aws-iot/src/CMakeLists.txt @@ -3,3 +3,9 @@ set(COMPONENT_ADD_INCLUDEDIRS ".") register_component() + +if(CONFIG_EXAMPLE_EMBEDDED_CERTS) +target_add_binary_data(${COMPONENT_TARGET} "certs/aws-root-ca.pem" TEXT) +target_add_binary_data(${COMPONENT_TARGET} "certs/certificate.pem.crt" TEXT) +target_add_binary_data(${COMPONENT_TARGET} "certs/private.pem.key" TEXT) +endif() diff --git a/examples/espidf-coap-server/sdkconfig.defaults b/examples/espidf-coap-server/sdkconfig.defaults index e970d9687..19e6d679b 100644 --- a/examples/espidf-coap-server/sdkconfig.defaults +++ b/examples/espidf-coap-server/sdkconfig.defaults @@ -1,2 +1,5 @@ CONFIG_EXAMPLE_WIFI_SSID="MYSSID" CONFIG_EXAMPLE_WIFI_PASSWORD="MYPASS" +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_PSK_MODES=y +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y diff --git a/examples/espidf-exceptions/src/exception_example_main.cpp b/examples/espidf-exceptions/src/exception_example_main.cpp index 24ada9de6..29045beb4 100644 --- a/examples/espidf-exceptions/src/exception_example_main.cpp +++ b/examples/espidf-exceptions/src/exception_example_main.cpp @@ -36,7 +36,7 @@ class Throwing }; /* Inside .cpp file, app_main function must be declared with C linkage */ -extern "C" void app_main() +extern "C" void app_main(void) { cout << "app_main starting" << endl; diff --git a/examples/espidf-http-request/platformio.ini b/examples/espidf-http-request/platformio.ini index cfaa13219..146e0dd5c 100644 --- a/examples/espidf-http-request/platformio.ini +++ b/examples/espidf-http-request/platformio.ini @@ -21,5 +21,5 @@ board = nano32 [env:espea32] board = espea32 -[env:esp320] -board = esp320 +[env:esp32-s2-saola-1] +board = esp32-s2-saola-1 diff --git a/examples/espidf-peripherals-usb/.gitignore b/examples/espidf-peripherals-usb/.gitignore new file mode 100644 index 000000000..03f4a3c19 --- /dev/null +++ b/examples/espidf-peripherals-usb/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/examples/espidf-peripherals-usb/.travis.yml b/examples/espidf-peripherals-usb/.travis.yml new file mode 100644 index 000000000..7c486f183 --- /dev/null +++ b/examples/espidf-peripherals-usb/.travis.yml @@ -0,0 +1,67 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < https://docs.platformio.org/page/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < https://docs.platformio.org/page/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < https://docs.platformio.org/page/userguide/cmd_ci.html > +# +# +# Please choose one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to be used as a library with examples. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N diff --git a/examples/espidf-peripherals-usb/CMakeLists.txt b/examples/espidf-peripherals-usb/CMakeLists.txt new file mode 100644 index 000000000..dcf556f08 --- /dev/null +++ b/examples/espidf-peripherals-usb/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(tusb_sample_descriptor) diff --git a/examples/espidf-peripherals-usb/README.rst b/examples/espidf-peripherals-usb/README.rst new file mode 100644 index 000000000..b6d181bec --- /dev/null +++ b/examples/espidf-peripherals-usb/README.rst @@ -0,0 +1,32 @@ +.. Copyright 2014-present PlatformIO + 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. + +How to build PlatformIO based project +===================================== + +1. `Install PlatformIO Core `_ +2. Download `development platform with examples `_ +3. Extract ZIP archive +4. Run these commands: + +.. code-block:: bash + + # Change directory to example + > cd platform-espressif32/examples/espidf-peripherals-usb + + # Build project + > platformio run + + # Upload firmware + > platformio run --target upload + + # Clean build files + > platformio run --target clean diff --git a/examples/espidf-peripherals-usb/include/README b/examples/espidf-peripherals-usb/include/README new file mode 100644 index 000000000..194dcd432 --- /dev/null +++ b/examples/espidf-peripherals-usb/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/espidf-peripherals-usb/lib/README b/examples/espidf-peripherals-usb/lib/README new file mode 100644 index 000000000..6debab1e8 --- /dev/null +++ b/examples/espidf-peripherals-usb/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/espidf-peripherals-usb/platformio.ini b/examples/espidf-peripherals-usb/platformio.ini new file mode 100644 index 000000000..8591d4b45 --- /dev/null +++ b/examples/espidf-peripherals-usb/platformio.ini @@ -0,0 +1,19 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + +[env] +platform = espressif32 +framework = espidf +monitor_speed = 115200 + +[env:esp32-s2-saola-1] +board = esp32-s2-saola-1 + +[env:esp32-s2-kaluga-1] +board = esp32-s2-kaluga-1 diff --git a/examples/espidf-peripherals-usb/sdkconfig.defaults b/examples/espidf-peripherals-usb/sdkconfig.defaults new file mode 100644 index 000000000..4d3be6399 --- /dev/null +++ b/examples/espidf-peripherals-usb/sdkconfig.defaults @@ -0,0 +1,6 @@ +CONFIG_IDF_TARGET="esp32s2" +CONFIG_USB_ENABLED=y +CONFIG_USB_DESC_USE_ESPRESSIF_VID=n +CONFIG_USB_DESC_CUSTOM_VID=0x303A +CONFIG_USB_DESC_USE_DEFAULT_PID=n +CONFIG_USB_DESC_CUSTOM_PID=0x3000 diff --git a/examples/espidf-peripherals-usb/src/CMakeLists.txt b/examples/espidf-peripherals-usb/src/CMakeLists.txt new file mode 100644 index 000000000..649d1f761 --- /dev/null +++ b/examples/espidf-peripherals-usb/src/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "tusb_sample_descriptor.c" + INCLUDE_DIRS . ${COMPONENT_DIR}) diff --git a/examples/espidf-peripherals-usb/src/Kconfig.projbuild b/examples/espidf-peripherals-usb/src/Kconfig.projbuild new file mode 100644 index 000000000..49a79fe59 --- /dev/null +++ b/examples/espidf-peripherals-usb/src/Kconfig.projbuild @@ -0,0 +1,10 @@ +menu "Example Configuration" + + config EXAMPLE_MANUAL_DESC + bool "Set up a USB descriptor manually in code" + default y + help + You can set up a descriptor using Menuconfig or independently of + your project configuration - manually in code + +endmenu diff --git a/examples/espidf-peripherals-usb/src/tusb_sample_descriptor.c b/examples/espidf-peripherals-usb/src/tusb_sample_descriptor.c new file mode 100644 index 000000000..1d82721db --- /dev/null +++ b/examples/espidf-peripherals-usb/src/tusb_sample_descriptor.c @@ -0,0 +1,84 @@ +/* USB 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. +*/ + +#include +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/gpio.h" +#include "sdkconfig.h" +#include "tinyusb.h" + +static const char *TAG = "example"; + +// USB Device Driver task +// This top level thread processes all usb events and invokes callbacks +static void usb_device_task(void *param) { + (void)param; + ESP_LOGI(TAG, "USB task started"); + while (1) { + tud_task(); // RTOS forever loop + } +} + +void app_main(void) { + + ESP_LOGI(TAG, "USB initialization"); + +#if CONFIG_EXAMPLE_MANUAL_DESC + // Setting of descriptor. You can use descriptor_tinyusb and + // descriptor_str_tinyusb as a reference + tusb_desc_device_t my_descriptor = { + .bLength = sizeof(my_descriptor), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, // USB version. 0x0200 means version 2.0 + .bDeviceClass = TUSB_CLASS_UNSPECIFIED, + .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + + .idVendor = 0x303A, + .idProduct = 0x3000, + .bcdDevice = 0x0101, // Device FW version + + .iManufacturer = 0x01, // see string_descriptor[1] bellow + .iProduct = 0x02, // see string_descriptor[2] bellow + .iSerialNumber = 0x03, // see string_descriptor[3] bellow + + .bNumConfigurations = 0x01}; + + tusb_desc_strarray_device_t my_string_descriptor = { + // array of pointer to string descriptors + (char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) + "I", // 1: Manufacturer + "My Custom Device", // 2: Product + "012-345", // 3: Serials, should use chip ID + }; + + tinyusb_config_t tusb_cfg = { + .descriptor = &my_descriptor, + .string_descriptor = my_string_descriptor, + .external_phy = false // In the most cases you need to use a `false` value + }; + +#else + + tinyusb_config_t tusb_cfg = { + .descriptor = NULL, + .string_descriptor = NULL, + .external_phy = false // In the most cases you need to use a `false` value + }; + +#endif + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + ESP_LOGI(TAG, "USB initialization DONE"); + + // Create a task for tinyusb device stack: + xTaskCreate(usb_device_task, "usbd", 4096, NULL, 5, NULL); + return; +} diff --git a/examples/espidf-peripherals-usb/test/README b/examples/espidf-peripherals-usb/test/README new file mode 100644 index 000000000..df5066e64 --- /dev/null +++ b/examples/espidf-peripherals-usb/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html diff --git a/examples/espidf-storage-sdcard/src/sd_card_example_main.c b/examples/espidf-storage-sdcard/src/sd_card_example_main.c index 3cec5cdb5..e3ff6639e 100644 --- a/examples/espidf-storage-sdcard/src/sd_card_example_main.c +++ b/examples/espidf-storage-sdcard/src/sd_card_example_main.c @@ -13,18 +13,39 @@ #include "esp_err.h" #include "esp_log.h" #include "esp_vfs_fat.h" -#include "driver/sdmmc_host.h" #include "driver/sdspi_host.h" +#include "driver/spi_common.h" #include "sdmmc_cmd.h" +#include "sdkconfig.h" + +#ifdef CONFIG_IDF_TARGET_ESP32 +#include "driver/sdmmc_host.h" +#endif static const char *TAG = "example"; +#define MOUNT_POINT "/sdcard" + // This example can use SDMMC and SPI peripherals to communicate with SD card. // By default, SDMMC peripheral is used. // To enable SPI mode, uncomment the following line: // #define USE_SPI_MODE +// ESP32-S2 doesn't have an SD Host peripheral, always use SPI: +#ifdef CONFIG_IDF_TARGET_ESP32S2 +#ifndef USE_SPI_MODE +#define USE_SPI_MODE +#endif // USE_SPI_MODE +// on ESP32-S2, DMA channel must be the same as host id +#define SPI_DMA_CHAN host.slot +#endif //CONFIG_IDF_TARGET_ESP32S2 + +// DMA channel to be used by the SPI peripheral +#ifndef SPI_DMA_CHAN +#define SPI_DMA_CHAN 1 +#endif //SPI_DMA_CHAN + // When testing SD and SPI modes, keep in mind that once the card has been // initialized in SPI mode, it can not be reinitialized in SD mode without // toggling power to the card. @@ -41,8 +62,27 @@ static const char *TAG = "example"; void app_main(void) { + esp_err_t ret; + // Options for mounting the filesystem. + // If format_if_mount_failed is set to true, SD card will be partitioned and + // formatted in case when mounting fails. + esp_vfs_fat_sdmmc_mount_config_t mount_config = { +#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED + .max_files = 5, + .allocation_unit_size = 16 * 1024 + }; + sdmmc_card_t* card; + const char mount_point[] = MOUNT_POINT; ESP_LOGI(TAG, "Initializing SD card"); + // Use settings defined above to initialize SD card and mount FAT filesystem. + // Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions. + // Please check its source code and implement error recovery when developing + // production applications. #ifndef USE_SPI_MODE ESP_LOGI(TAG, "Using SDMMC peripheral"); sdmmc_host_t host = SDMMC_HOST_DEFAULT(); @@ -63,39 +103,38 @@ void app_main(void) gpio_set_pull_mode(12, GPIO_PULLUP_ONLY); // D2, needed in 4-line mode only gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); // D3, needed in 4- and 1-line modes + ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card); #else ESP_LOGI(TAG, "Using SPI peripheral"); sdmmc_host_t host = SDSPI_HOST_DEFAULT(); - sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT(); - slot_config.gpio_miso = PIN_NUM_MISO; - slot_config.gpio_mosi = PIN_NUM_MOSI; - slot_config.gpio_sck = PIN_NUM_CLK; - slot_config.gpio_cs = PIN_NUM_CS; + spi_bus_config_t bus_cfg = { + .mosi_io_num = PIN_NUM_MOSI, + .miso_io_num = PIN_NUM_MISO, + .sclk_io_num = PIN_NUM_CLK, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = 4000, + }; + ret = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CHAN); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize bus."); + return; + } + // This initializes the slot without card detect (CD) and write protect (WP) signals. // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. -#endif //USE_SPI_MODE - - // Options for mounting the filesystem. - // If format_if_mount_failed is set to true, SD card will be partitioned and - // formatted in case when mounting fails. - esp_vfs_fat_sdmmc_mount_config_t mount_config = { - .format_if_mount_failed = false, - .max_files = 5, - .allocation_unit_size = 16 * 1024 - }; + sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); + slot_config.gpio_cs = PIN_NUM_CS; + slot_config.host_id = host.slot; - // Use settings defined above to initialize SD card and mount FAT filesystem. - // Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function. - // Please check its source code and implement error recovery when developing - // production applications. - sdmmc_card_t* card; - esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card); + ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card); +#endif //USE_SPI_MODE if (ret != ESP_OK) { if (ret == ESP_FAIL) { ESP_LOGE(TAG, "Failed to mount filesystem. " - "If you want the card to be formatted, set format_if_mount_failed = true."); + "If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option."); } else { ESP_LOGE(TAG, "Failed to initialize the card (%s). " "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret)); @@ -109,7 +148,7 @@ void app_main(void) // Use POSIX and C standard library functions to work with files. // First create a file. ESP_LOGI(TAG, "Opening file"); - FILE* f = fopen("/sdcard/hello.txt", "w"); + FILE* f = fopen(MOUNT_POINT"/hello.txt", "w"); if (f == NULL) { ESP_LOGE(TAG, "Failed to open file for writing"); return; @@ -120,21 +159,21 @@ void app_main(void) // Check if destination file exists before renaming struct stat st; - if (stat("/sdcard/foo.txt", &st) == 0) { + if (stat(MOUNT_POINT"/foo.txt", &st) == 0) { // Delete it if it exists - unlink("/sdcard/foo.txt"); + unlink(MOUNT_POINT"/foo.txt"); } // Rename original file ESP_LOGI(TAG, "Renaming file"); - if (rename("/sdcard/hello.txt", "/sdcard/foo.txt") != 0) { + if (rename(MOUNT_POINT"/hello.txt", MOUNT_POINT"/foo.txt") != 0) { ESP_LOGE(TAG, "Rename failed"); return; } // Open renamed file for reading ESP_LOGI(TAG, "Reading file"); - f = fopen("/sdcard/foo.txt", "r"); + f = fopen(MOUNT_POINT"/foo.txt", "r"); if (f == NULL) { ESP_LOGE(TAG, "Failed to open file for reading"); return; @@ -150,6 +189,10 @@ void app_main(void) ESP_LOGI(TAG, "Read from file: '%s'", line); // All done, unmount partition and disable SDMMC or SPI peripheral - esp_vfs_fat_sdmmc_unmount(); + esp_vfs_fat_sdcard_unmount(mount_point, card); ESP_LOGI(TAG, "Card unmounted"); +#ifdef USE_SPI_MODE + //deinitialize the bus after all devices are removed + spi_bus_free(host.slot); +#endif } diff --git a/examples/espidf-storage-spiffs/.gitignore b/examples/espidf-storage-spiffs/.gitignore new file mode 100644 index 000000000..03f4a3c19 --- /dev/null +++ b/examples/espidf-storage-spiffs/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/examples/espidf-storage-spiffs/CMakeLists.txt b/examples/espidf-storage-spiffs/CMakeLists.txt new file mode 100644 index 000000000..1894b31ca --- /dev/null +++ b/examples/espidf-storage-spiffs/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(spiffs) diff --git a/examples/espidf-storage-spiffs/README.rst b/examples/espidf-storage-spiffs/README.rst new file mode 100644 index 000000000..25efc94a5 --- /dev/null +++ b/examples/espidf-storage-spiffs/README.rst @@ -0,0 +1,35 @@ +.. Copyright 2014-present PlatformIO + 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. + +How to build PlatformIO based project +===================================== + +1. `Install PlatformIO Core `_ +2. Download `development platform with examples `_ +3. Extract ZIP archive +4. Run these commands: + +.. code-block:: bash + + # Change directory to example + > cd platform-espressif32/examples/espidf-storage-spiffs + + # Build project + > platformio run + + # Upload firmware + > platformio run --target upload + + # Upload SPIFFS image + > platformio run --target uploadfs + + # Clean build files + > platformio run --target clean diff --git a/examples/espidf-storage-spiffs/data/hello.txt b/examples/espidf-storage-spiffs/data/hello.txt new file mode 100644 index 000000000..5a8367719 --- /dev/null +++ b/examples/espidf-storage-spiffs/data/hello.txt @@ -0,0 +1 @@ +Hello World from SPIFFS. diff --git a/examples/espidf-storage-spiffs/include/README b/examples/espidf-storage-spiffs/include/README new file mode 100644 index 000000000..194dcd432 --- /dev/null +++ b/examples/espidf-storage-spiffs/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/espidf-storage-spiffs/lib/README b/examples/espidf-storage-spiffs/lib/README new file mode 100644 index 000000000..6debab1e8 --- /dev/null +++ b/examples/espidf-storage-spiffs/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/espidf-storage-spiffs/partitions_example.csv b/examples/espidf-storage-spiffs/partitions_example.csv new file mode 100644 index 000000000..92db904e0 --- /dev/null +++ b/examples/espidf-storage-spiffs/partitions_example.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +spiffs, data, spiffs, , 0xF0000, diff --git a/examples/espidf-storage-spiffs/platformio.ini b/examples/espidf-storage-spiffs/platformio.ini new file mode 100644 index 000000000..83870a9a3 --- /dev/null +++ b/examples/espidf-storage-spiffs/platformio.ini @@ -0,0 +1,15 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + +[env:esp32dev] +platform = espressif32 +framework = espidf +board = esp32dev +monitor_speed = 115200 +board_build.partitions = partitions_example.csv diff --git a/examples/espidf-storage-spiffs/sdkconfig.defaults b/examples/espidf-storage-spiffs/sdkconfig.defaults new file mode 100644 index 000000000..b9bb0c0a5 --- /dev/null +++ b/examples/espidf-storage-spiffs/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv" diff --git a/examples/espidf-storage-spiffs/src/CMakeLists.txt b/examples/espidf-storage-spiffs/src/CMakeLists.txt new file mode 100644 index 000000000..026db1313 --- /dev/null +++ b/examples/espidf-storage-spiffs/src/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "spiffs_example_main.c" + INCLUDE_DIRS ".") \ No newline at end of file diff --git a/examples/espidf-storage-spiffs/src/spiffs_example_main.c b/examples/espidf-storage-spiffs/src/spiffs_example_main.c new file mode 100644 index 000000000..279f3df19 --- /dev/null +++ b/examples/espidf-storage-spiffs/src/spiffs_example_main.c @@ -0,0 +1,73 @@ +/* SPIFFS filesystem 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. +*/ + +#include +#include +#include +#include +#include "esp_err.h" +#include "esp_log.h" +#include "esp_spiffs.h" + +static const char *TAG = "example"; + +void app_main(void) +{ + ESP_LOGI(TAG, "Initializing SPIFFS"); + + esp_vfs_spiffs_conf_t conf = { + .base_path = "/spiffs", + .partition_label = NULL, + .max_files = 5, + .format_if_mount_failed = true + }; + + // Use settings defined above to initialize and mount SPIFFS filesystem. + // Note: esp_vfs_spiffs_register is an all-in-one convenience function. + esp_err_t ret = esp_vfs_spiffs_register(&conf); + + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, "Failed to mount or format filesystem"); + } else if (ret == ESP_ERR_NOT_FOUND) { + ESP_LOGE(TAG, "Failed to find SPIFFS partition"); + } else { + ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret)); + } + return; + } + + size_t total = 0, used = 0; + ret = esp_spiffs_info(conf.partition_label, &total, &used); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret)); + } else { + ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used); + } + + // Open renamed file for reading + ESP_LOGI(TAG, "Reading file"); + FILE* f = fopen("/spiffs/hello.txt", "r"); + if (f == NULL) { + ESP_LOGI(TAG, "Failed to open file for reading"); + return; + } + char line[64]; + fgets(line, sizeof(line), f); + fclose(f); + // strip newline + char* pos = strchr(line, '\n'); + if (pos) { + *pos = '\0'; + } + ESP_LOGI(TAG, "Read from file: '%s'", line); + + // All done, unmount partition and disable SPIFFS + esp_vfs_spiffs_unregister(conf.partition_label); + ESP_LOGI(TAG, "SPIFFS unmounted"); +} diff --git a/examples/espidf-storage-spiffs/test/README b/examples/espidf-storage-spiffs/test/README new file mode 100644 index 000000000..df5066e64 --- /dev/null +++ b/examples/espidf-storage-spiffs/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html diff --git a/examples/espidf-ulp-adc/main/ulp_adc_example_main.c b/examples/espidf-ulp-adc/main/ulp_adc_example_main.c index 80f9fc1eb..9e38e9ff7 100644 --- a/examples/espidf-ulp-adc/main/ulp_adc_example_main.c +++ b/examples/espidf-ulp-adc/main/ulp_adc_example_main.c @@ -27,14 +27,14 @@ extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end"); /* This function is called once after power-on reset, to load ULP program into * RTC memory and configure the ADC. */ -static void init_ulp_program(); +static void init_ulp_program(void); /* This function is called every time before going into deep sleep. * It starts the ULP program and resets measurement counter. */ -static void start_ulp_program(); +static void start_ulp_program(void); -void app_main() +void app_main(void) { esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); if (cause != ESP_SLEEP_WAKEUP_ULP) { @@ -54,7 +54,7 @@ void app_main() esp_deep_sleep_start(); } -static void init_ulp_program() +static void init_ulp_program(void) { esp_err_t err = ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t)); @@ -64,7 +64,11 @@ static void init_ulp_program() /* Note: when changing channel here, also change 'adc_channel' constant in adc.S */ adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11); +#if CONFIG_IDF_TARGET_ESP32 adc1_config_width(ADC_WIDTH_BIT_12); +#elif CONFIG_IDF_TARGET_ESP32S2 + adc1_config_width(ADC_WIDTH_BIT_13); +#endif adc1_ulp_enable(); /* Set low and high thresholds, approx. 1.35V - 1.75V*/ @@ -80,10 +84,12 @@ static void init_ulp_program() */ rtc_gpio_isolate(GPIO_NUM_12); rtc_gpio_isolate(GPIO_NUM_15); +#if CONFIG_IDF_TARGET_ESP32 esp_deep_sleep_disable_rom_logging(); // suppress boot messages +#endif } -static void start_ulp_program() +static void start_ulp_program(void) { /* Reset sample counter */ ulp_sample_counter = 0; diff --git a/platform.json b/platform.json index 6f309b654..15792397b 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/platformio/platform-espressif32.git" }, - "version": "2.0.0", + "version": "3.2.0", "frameworks": { "arduino": { "package": "framework-arduinoespressif32", @@ -50,13 +50,14 @@ "toolchain-xtensa32": { "type": "toolchain", "owner": "platformio", - "version": "~2.50200.0" + "version": "~2.50200.0", + "optionalVersions": ["~2.80400.0"] }, "toolchain-xtensa32s2": { "type": "toolchain", "optional": true, "owner": "platformio", - "version": "~1.80200.0" + "version": "~1.80400.0" }, "toolchain-esp32ulp": { "type": "toolchain", @@ -74,19 +75,20 @@ "type": "framework", "optional": true, "owner": "platformio", - "version": "~3.10004.191002" + "version": "~3.10006.0" }, "framework-arduino-mbcwb": { "type": "framework", "optional": true, - "owner": "platformio", + "owner": "meteca", "version": ">=2.1.1" }, "framework-espidf": { "type": "framework", "optional": true, "owner": "platformio", - "version": "~3.40100.0" + "version": "~3.40200.0", + "optionalVersions": ["~3.40001.0"] }, "framework-simba": { "type": "framework", @@ -103,18 +105,18 @@ "tool-esptoolpy": { "type": "uploader", "owner": "platformio", - "version": "~1.20600.0" + "version": "~1.30000.0" }, "tool-mbctool": { "optional": true, - "owner": "platformio", + "owner": "meteca", "version": ">=2.0.0" }, "tool-openocd-esp32": { "type": "debugger", "optional": true, "owner": "platformio", - "version": "~1.1000.20181026" + "version": "~2.1000.0" }, "tool-mkspiffs": { "type": "uploader", diff --git a/platform.py b/platform.py index 8f8561692..65e6505b3 100644 --- a/platform.py +++ b/platform.py @@ -12,55 +12,54 @@ # See the License for the specific language governing permissions and # limitations under the License. -from os.path import isdir +import copy +import os +from platformio import fs from platformio.managers.platform import PlatformBase from platformio.util import get_systype class Espressif32Platform(PlatformBase): - def configure_default_packages(self, variables, targets): if not variables.get("board"): - return PlatformBase.configure_default_packages( - self, variables, targets) + return PlatformBase.configure_default_packages(self, variables, targets) board_config = self.board_config(variables.get("board")) mcu = variables.get("board_build.mcu", board_config.get("build.mcu", "esp32")) frameworks = variables.get("pioframework", []) if "buildfs" in targets: - self.packages['tool-mkspiffs']['optional'] = False + self.packages["tool-mkspiffs"]["optional"] = False if variables.get("upload_protocol"): - self.packages['tool-openocd-esp32']['optional'] = False - if isdir("ulp"): - self.packages['toolchain-esp32ulp']['optional'] = False + self.packages["tool-openocd-esp32"]["optional"] = False + if os.path.isdir("ulp"): + self.packages["toolchain-esp32ulp"]["optional"] = False if "espidf" in frameworks: for p in self.packages: if p in ("tool-cmake", "tool-ninja", "toolchain-%sulp" % mcu): self.packages[p]["optional"] = False elif p in ("tool-mconf", "tool-idf") and "windows" in get_systype(): - self.packages[p]['optional'] = False - self.packages['toolchain-xtensa32']['version'] = "~2.80200.0" + self.packages[p]["optional"] = False + self.packages["toolchain-xtensa32"]["version"] = "~2.80400.0" if "arduino" in frameworks: # Arduino component is not compatible with ESP-IDF >=4.1 - self.packages['framework-espidf']['version'] = "~3.40001.0" + self.packages["framework-espidf"]["version"] = "~3.40001.0" # ESP32-S2 toolchain is identical for both Arduino and ESP-IDF if mcu == "esp32s2": self.packages.pop("toolchain-xtensa32", None) - self.packages['toolchain-xtensa32s2']['optional'] = False - self.packages['toolchain-esp32s2ulp']['optional'] = False - self.packages['tool-esptoolpy']['version'] = "~1.30000.0" + self.packages["toolchain-xtensa32s2"]["optional"] = False + self.packages["toolchain-esp32s2ulp"]["optional"] = False build_core = variables.get( - "board_build.core", board_config.get("build.core", "arduino")).lower() + "board_build.core", board_config.get("build.core", "arduino") + ).lower() if build_core == "mbcwb": - self.packages['framework-arduinoespressif32']['optional'] = True - self.packages['framework-arduino-mbcwb']['optional'] = False - self.packages['tool-mbctool']['type'] = "uploader" - self.packages['tool-mbctool']['optional'] = False + self.packages["framework-arduinoespressif32"]["optional"] = True + self.packages["framework-arduino-mbcwb"]["optional"] = False + self.packages["tool-mbctool"]["type"] = "uploader" + self.packages["tool-mbctool"]["optional"] = False - return PlatformBase.configure_default_packages(self, variables, - targets) + return PlatformBase.configure_default_packages(self, variables, targets) def get_boards(self, id_=None): result = PlatformBase.get_boards(self, id_) @@ -76,9 +75,9 @@ def get_boards(self, id_=None): def _add_dynamic_options(self, board): # upload protocols if not board.get("upload.protocols", []): - board.manifest['upload']['protocols'] = ["esptool", "espota"] + board.manifest["upload"]["protocols"] = ["esptool", "espota"] if not board.get("upload.protocol", ""): - board.manifest['upload']['protocol'] = "esptool" + board.manifest["upload"]["protocol"] = "esptool" # debug tools debug = board.manifest.get("debug", {}) @@ -92,44 +91,54 @@ def _add_dynamic_options(self, board): "olimex-arm-usb-ocd-h", "olimex-arm-usb-ocd", "olimex-jtag-tiny", - "tumpa" + "tumpa", ] upload_protocol = board.manifest.get("upload", {}).get("protocol") - upload_protocols = board.manifest.get("upload", {}).get( - "protocols", []) + upload_protocols = board.manifest.get("upload", {}).get("protocols", []) if debug: upload_protocols.extend(supported_debug_tools) if upload_protocol and upload_protocol not in upload_protocols: upload_protocols.append(upload_protocol) - board.manifest['upload']['protocols'] = upload_protocols + board.manifest["upload"]["protocols"] = upload_protocols if "tools" not in debug: - debug['tools'] = {} + debug["tools"] = {} # Only FTDI based debug probes for link in upload_protocols: - if link in non_debug_protocols or link in debug['tools']: + if link in non_debug_protocols or link in debug["tools"]: continue if link == "jlink": openocd_interface = link elif link in ("esp-prog", "ftdi"): - openocd_interface = "ftdi/esp32_devkitj_v1" + if board.id == "esp32-s2-kaluga-1": + openocd_interface = "ftdi/esp32s2_kaluga_v1" + else: + openocd_interface = "ftdi/esp32_devkitj_v1" else: openocd_interface = "ftdi/" + link server_args = [ - "-s", "$PACKAGE_DIR/share/openocd/scripts", - "-f", "interface/%s.cfg" % openocd_interface, - "-f", "board/%s" % debug.get("openocd_board") + "-s", + "$PACKAGE_DIR/share/openocd/scripts", + "-f", + "interface/%s.cfg" % openocd_interface, + "-f", + "%s/%s" + % ( + ("target", debug.get("openocd_target")) + if "openocd_target" in debug + else ("board", debug.get("openocd_board")) + ), ] - debug['tools'][link] = { + debug["tools"][link] = { "server": { "package": "tool-openocd-esp32", "executable": "bin/openocd", - "arguments": server_args + "arguments": server_args, }, "init_break": "thb app_main", "init_cmds": [ @@ -143,12 +152,82 @@ def _add_dynamic_options(self, board): "target extended-remote $DEBUG_PORT", "$LOAD_CMDS", "pio_reset_halt_target", - "$INIT_BREAK" + "$INIT_BREAK", ], "onboard": link in debug.get("onboard_tools", []), - "default": link == debug.get("default_tool") - + "default": link == debug.get("default_tool"), } - board.manifest['debug'] = debug + board.manifest["debug"] = debug return board + + def configure_debug_session(self, debug_config): + build_extra_data = debug_config.build_data.get("extra", {}) + flash_images = build_extra_data.get("flash_images", []) + + if "openocd" in (debug_config.server or {}).get("executable", ""): + debug_config.server["arguments"].extend( + ["-c", "adapter_khz %s" % (debug_config.speed or "5000")] + ) + + ignore_conds = [ + debug_config.load_cmds != ["load"], + not flash_images, + not all([os.path.isfile(item["path"]) for item in flash_images]), + ] + + if any(ignore_conds): + return + + load_cmds = [ + 'monitor program_esp "{{{path}}}" {offset} verify'.format( + path=fs.to_unix_path(item["path"]), offset=item["offset"] + ) + for item in flash_images + ] + load_cmds.append( + 'monitor program_esp "{%s.bin}" %s verify' + % ( + fs.to_unix_path(debug_config.build_data["prog_path"][:-4]), + build_extra_data.get("application_offset", "0x10000"), + ) + ) + debug_config.load_cmds = load_cmds + + def configure_debug_options(self, initial_debug_options, ide_data): + """ + Deprecated. Remove method when PlatformIO Core 5.2 is released + """ + ide_extra_data = ide_data.get("extra", {}) + flash_images = ide_extra_data.get("flash_images", []) + debug_options = copy.deepcopy(initial_debug_options) + + if "openocd" in debug_options["server"].get("executable", ""): + debug_options["server"]["arguments"].extend( + ["-c", "adapter_khz %s" % (initial_debug_options.get("speed") or "5000")] + ) + + ignore_conds = [ + initial_debug_options["load_cmds"] != ["load"], + not flash_images, + not all([os.path.isfile(item["path"]) for item in flash_images]), + ] + + if any(ignore_conds): + return debug_options + + load_cmds = [ + 'monitor program_esp "{{{path}}}" {offset} verify'.format( + path=fs.to_unix_path(item["path"]), offset=item["offset"] + ) + for item in flash_images + ] + load_cmds.append( + 'monitor program_esp "{%s.bin}" %s verify' + % ( + fs.to_unix_path(ide_data["prog_path"][:-4]), + ide_extra_data.get("application_offset", "0x10000"), + ) + ) + debug_options["load_cmds"] = load_cmds + return debug_options