diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 30ea1d013..4980f48c4 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,6 +22,7 @@ jobs: - "examples/espidf-hello-world" - "examples/espidf-http-request" - "examples/espidf-peripherals-uart" + - "examples/espidf-peripherals-usb" - "examples/espidf-storage-sdcard" - "examples/espidf-ulp-adc" - "examples/espidf-ulp-pulse" 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/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/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/m5stack-fire.json b/boards/m5stack-fire.json index 36ad0a619..a7a51b1c4 100644 --- a/boards/m5stack-fire.json +++ b/boards/m5stack-fire.json @@ -1,7 +1,8 @@ { "build": { "arduino":{ - "ldscript": "esp32_out.ld" + "ldscript": "esp32_out.ld", + "partitions": "default_16MB.csv" }, "core": "esp32", "extra_flags": "-DARDUINO_M5STACK_FIRE", @@ -9,7 +10,6 @@ "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "default_16MB.csv", "variant": "m5stack_fire" }, "connectivity": [ 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/ttgo-t-watch.json b/boards/ttgo-t-watch.json index a47a4a07d..aaf47c0cb 100644 --- a/boards/ttgo-t-watch.json +++ b/boards/ttgo-t-watch.json @@ -1,7 +1,8 @@ { "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", @@ -9,7 +10,6 @@ "f_flash": "40000000L", "flash_mode": "dio", "mcu": "esp32", - "partitions": "default_16MB.csv", "variant": "twatch" }, "connectivity": [ 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 494139a82..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 @@ -566,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), ) ) @@ -835,7 +855,12 @@ def generate_empty_partition_image(binary_path, image_size): def get_partition_info(pt_path, pt_offset, pt_params): - assert os.path.isfile(pt_path) + 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"), @@ -885,6 +910,105 @@ def get_app_partition_offset(pt_table, pt_offset): 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 @@ -986,6 +1110,7 @@ def get_app_partition_offset(pt_table, pt_offset): BUILD_DIR, [ "-DIDF_TARGET=" + idf_variant, + "-DPYTHON_DEPS_CHECKED=1", "-DEXTRA_COMPONENT_DIRS:PATH=" + ";".join(extra_components), "-DPYTHON=" + env.subst("$PYTHONEXE"), ] @@ -1002,7 +1127,6 @@ def get_app_partition_offset(pt_table, pt_offset): 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") @@ -1152,6 +1276,23 @@ def _skip_prj_source_files(node): ], ) +# 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 # 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 6faed8e2c..383c197c7 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']) @@ -371,9 +372,10 @@ 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_esp {{$SOURCE}} %s verify" % - board.get("upload.offset_address", "$ESP32_APP_OFFSET") + board.get("upload.offset_address", "$ESP32_APP_OFFSET"), ]) for image in env.get("FLASH_EXTRA_IMAGES", []): openocd_args.extend([ 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-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 61a5f83de..f8d2e066d 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/platformio/platform-espressif32.git" }, - "version": "2.1.0", + "version": "3.0.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", @@ -86,7 +87,8 @@ "type": "framework", "optional": true, "owner": "platformio", - "version": "~3.40100.0" + "version": "~3.40200.0", + "optionalVersions": ["~3.40001.0"] }, "framework-simba": { "type": "framework", diff --git a/platform.py b/platform.py index 81af44c8e..e6cfd4ca2 100644 --- a/platform.py +++ b/platform.py @@ -21,48 +21,45 @@ 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 + self.packages["tool-openocd-esp32"]["optional"] = False if os.path.isdir("ulp"): - self.packages['toolchain-esp32ulp']['optional'] = False + 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_) @@ -78,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", {}) @@ -94,45 +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"), - "-c", "adapter_khz %d" % debug.get("adapter_speed", 20000) + "-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": [ @@ -146,28 +152,34 @@ 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_options(self, initial_debug_options, ide_data): 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 initial_debug_options + return debug_options - debug_options = copy.deepcopy(initial_debug_options) load_cmds = [ 'monitor program_esp "{{{path}}}" {offset} verify'.format( path=fs.to_unix_path(item["path"]), offset=item["offset"]