Initial updates for ESP-IDF v4.2

This commit is contained in:
valeros
2021-01-21 13:42:23 +02:00
parent e542df17d1
commit 7e5f3f56fa
26 changed files with 754 additions and 110 deletions
+1
View File
@@ -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"
+39
View File
@@ -0,0 +1,39 @@
{
"build": {
"arduino":{
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"mcu": "esp32s2",
"variant": "esp32s2"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"default_tool": "esp32s2_kaluga_v1",
"onboard_tools": [
"esp32s2_kaluga_v1"
],
"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"
}
+35
View File
@@ -0,0 +1,35 @@
{
"build": {
"arduino":{
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"mcu": "esp32s2",
"variant": "esp32s2"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"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"
}
+35
View File
@@ -0,0 +1,35 @@
{
"build": {
"arduino":{
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"mcu": "esp32s2",
"variant": "esp32s2"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"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"
}
+2 -2
View File
@@ -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 @@ env.Append(
"Generating assembly for $TARGET",
),
emitter=transform_to_asm,
single_source=True
single_source=True,
),
)
)
+165 -28
View File
@@ -45,9 +45,7 @@ env.SConscript("_embed_files.py", exports="env")
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),
)
)
@@ -837,7 +857,8 @@ def generate_empty_partition_image(binary_path, image_size):
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))
"Missing partition table file `%s`\n" % os.path.basename(pt_path)
)
env.Exit(1)
cmd = [
@@ -889,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=[
"-<*>",
"+<port/common/src/descriptors_control.c>",
"+<port/common/src/usb_descriptors.c>",
"+<port/common/src/usbd.c>",
"+<port/esp32s2/src/device_controller_driver.c>",
"+<port/esp32s2/src/tinyusb.c>",
"+<tinyusb/src/common/tusb_fifo.c>",
"+<tinyusb/src/device/usbd_control.c>",
"+<tinyusb/src/class/msc/msc_device.c>",
"+<tinyusb/src/class/cdc/cdc_device.c>",
"+<tinyusb/src/class/hid/hid_device.c>",
"+<tinyusb/src/class/midi/midi_device.c>",
"+<tinyusb/src/tusb.c>",
],
)
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
@@ -990,6 +1110,7 @@ project_codemodel = get_cmake_code_model(
BUILD_DIR,
[
"-DIDF_TARGET=" + idf_variant,
"-DPYTHON_DEPS_CHECKED=1",
"-DEXTRA_COMPONENT_DIRS:PATH=" + ";".join(extra_components),
"-DPYTHON=" + env.subst("$PYTHONEXE"),
]
@@ -1006,7 +1127,6 @@ target_configs = load_target_configurations(
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")
@@ -1156,6 +1276,23 @@ env.Prepend(
],
)
# 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 (
idf_variant.startswith("esp32s2")
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
#
+14 -5
View File
@@ -26,15 +26,24 @@ platform = ulp_env.PioPlatform()
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",
@@ -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()
@@ -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
@@ -36,7 +36,7 @@ protected:
};
/* 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;
@@ -0,0 +1 @@
.pio
@@ -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
@@ -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)
@@ -0,0 +1,32 @@
.. Copyright 2014-present PlatformIO <contact@platformio.org>
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 <http://docs.platformio.org/page/core.html>`_
2. Download `development platform with examples <https://github.com/platformio/platform-espressif32/archive/develop.zip>`_
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
@@ -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
@@ -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 <Foo.h>
#include <Bar.h>
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
@@ -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
@@ -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
@@ -0,0 +1,2 @@
idf_component_register(SRCS "tusb_sample_descriptor.c"
INCLUDE_DIRS . ${COMPONENT_DIR})
@@ -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
@@ -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 <stdlib.h>
#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;
}
@@ -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
@@ -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.
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = PIN_NUM_CS;
slot_config.host_id = host.slot;
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
#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
};
// 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);
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
}
@@ -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;
+5 -3
View File
@@ -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",
+42 -37
View File
@@ -21,48 +21,45 @@ 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
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 @@ class Espressif32Platform(PlatformBase):
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,24 +91,24 @@ class Espressif32Platform(PlatformBase):
"olimex-arm-usb-ocd-h",
"olimex-arm-usb-ocd",
"olimex-jtag-tiny",
"tumpa"
"tumpa",
"esp32s2_kaluga_v1",
]
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":
@@ -122,17 +119,26 @@ class Espressif32Platform(PlatformBase):
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"))
),
"-c",
"adapter_khz %d" % debug.get("adapter_speed", 5000),
]
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,14 +152,13 @@ class Espressif32Platform(PlatformBase):
"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):