Merge branch 'master' of github.com:adafruit/arduino-esp32

This commit is contained in:
ladyada 2024-12-30 21:04:36 -05:00
commit a1b0493802
385 changed files with 13990 additions and 3157 deletions

View file

@ -41,6 +41,8 @@ body:
options:
- latest master (checkout manually)
- latest development Release Candidate (RC-X)
- v3.1.0
- v3.0.7
- v3.0.6
- v3.0.5
- v3.0.4
@ -100,8 +102,8 @@ body:
label: PSRAM enabled
description: Is PSRAM enabled?
options:
- 'yes'
- 'no'
- "yes"
- "no"
validations:
required: true
- type: input
@ -116,8 +118,8 @@ body:
id: Description
attributes:
label: Description
description: Please describe your problem here and expected behaviour
placeholder: ex. Can't connect/weird behaviour/wrong function/missing parameter..
description: Please describe your problem here and expected behavior
placeholder: ex. Can't connect/weird behavior/wrong function/missing parameter..
validations:
required: true
- type: textarea

View file

@ -1,4 +1,5 @@
#!/bin/bash
#
# This script is used in the CI workflow. It checks all non-examples source files in libraries/ and cores/ are listed in
# CMakeLists.txt for the cmake-based IDF component
@ -12,10 +13,10 @@ set -e
git submodule update --init --recursive
# find all source files in repo
REPO_SRCS=`find cores/esp32/ libraries/ -name 'examples' -prune -o -name '*.c' -print -o -name '*.cpp' -print | sort`
REPO_SRCS=$(find cores/esp32/ libraries/ -name 'examples' -prune -o -name '*.c' -print -o -name '*.cpp' -print | sort)
# find all source files named in CMakeLists.txt COMPONENT_SRCS
CMAKE_SRCS=`cmake --trace-expand -P CMakeLists.txt 2>&1 | grep set\(srcs | cut -d'(' -f3 | sed 's/ )//' | sed 's/srcs //' | tr ' ;' '\n' | sort`
CMAKE_SRCS=$(cmake --trace-expand -P CMakeLists.txt 2>&1 | grep set\(srcs | cut -d'(' -f3 | sed 's/ )//' | sed 's/srcs //' | tr ' ;' '\n' | sort)
if ! diff -u0 --label "Repo Files" --label "srcs" <(echo "$REPO_SRCS") <(echo "$CMAKE_SRCS"); then
echo "Source files in repo (-) and source files in CMakeLists.txt (+) don't match"

View file

@ -3,7 +3,9 @@
# Get all boards
boards_array=()
for line in `grep '.tarch=' boards.txt`; do
boards_list=$(grep '.tarch=' boards.txt)
while read -r line; do
board_name=$(echo "$line" | cut -d '.' -f1 | cut -d '#' -f1)
# skip esp32c2 as we dont build libs for it
if [ "$board_name" == "esp32c2" ]; then
@ -12,29 +14,26 @@ for line in `grep '.tarch=' boards.txt`; do
fi
boards_array+=("espressif:esp32:$board_name")
echo "Added 'espressif:esp32:$board_name' to array"
done
done <<< "$boards_list"
# Create JSON like string with all boards found and pass it to env variable
board_count=${#boards_array[@]}
echo "Boards found: $board_count"
echo "BOARD-COUNT=$board_count" >> $GITHUB_ENV
echo "BOARD-COUNT=$board_count" >> "$GITHUB_ENV"
if [ $board_count -gt 0 ]
then
if [ "$board_count" -gt 0 ]; then
json_matrix='['
for board in ${boards_array[@]}
do
for board in "${boards_array[@]}"; do
json_matrix+='"'$board'"'
if [ $board_count -gt 1 ]
then
if [ "$board_count" -gt 1 ]; then
json_matrix+=","
fi
board_count=$(($board_count - 1))
board_count=$((board_count - 1))
done
json_matrix+=']'
echo $json_matrix
echo "FQBNS=${json_matrix}" >> $GITHUB_ENV
echo "$json_matrix"
echo "FQBNS=${json_matrix}" >> "$GITHUB_ENV"
else
echo "FQBNS=" >> $GITHUB_ENV
echo "FQBNS=" >> "$GITHUB_ENV"
fi

View file

@ -5,14 +5,13 @@ owner_repository=$1
base_ref=$2
# Download the boards.txt file from the base branch
curl -L -o boards_base.txt https://raw.githubusercontent.com/$owner_repository/$base_ref/boards.txt
curl -L -o boards_base.txt https://raw.githubusercontent.com/"$owner_repository"/"$base_ref"/boards.txt
# Compare boards.txt file in the repo with the modified file from PR
diff=$(diff -u boards_base.txt boards.txt)
# Check if the diff is empty
if [ -z "$diff" ]
then
if [ -z "$diff" ]; then
echo "No changes in boards.txt file"
echo "FQBNS="
exit 0
@ -21,7 +20,7 @@ fi
# Extract added or modified lines (lines starting with '+' or '-')
modified_lines=$(echo "$diff" | grep -E '^[+-][^+-]')
# Print the modified lines for debugging
# Print the modified lines for debugging
echo "Modified lines:"
echo "$modified_lines"
@ -29,15 +28,12 @@ boards_array=()
previous_board=""
# Extract board names from the modified lines, and add them to the boards_array
while read -r line
do
while read -r line; do
board_name=$(echo "$line" | cut -d '.' -f1 | cut -d '#' -f1)
# remove + or - from the board name at the beginning
board_name=$(echo "$board_name" | sed 's/^[+-]//')
if [ "$board_name" != "" ] && [ "$board_name" != "+" ] && [ "$board_name" != "-" ] && [ "$board_name" != "esp32_family" ]
then
if [ "$board_name" != "$previous_board" ]
then
board_name=${board_name#[-+]}
if [ "$board_name" != "" ] && [ "$board_name" != "+" ] && [ "$board_name" != "-" ] && [ "$board_name" != "esp32_family" ]; then
if [ "$board_name" != "$previous_board" ]; then
boards_array+=("espressif:esp32:$board_name")
previous_board="$board_name"
echo "Added 'espressif:esp32:$board_name' to array"
@ -48,22 +44,19 @@ done <<< "$modified_lines"
# Create JSON like string with all boards found and pass it to env variable
board_count=${#boards_array[@]}
if [ $board_count -gt 0 ]
then
if [ "$board_count" -gt 0 ]; then
json_matrix='{"fqbn": ['
for board in ${boards_array[@]}
do
for board in "${boards_array[@]}"; do
json_matrix+='"'$board'"'
if [ $board_count -gt 1 ]
then
if [ "$board_count" -gt 1 ]; then
json_matrix+=","
fi
board_count=$(($board_count - 1))
board_count=$((board_count - 1))
done
json_matrix+=']}'
echo $json_matrix
echo "FQBNS=${json_matrix}" >> $GITHUB_ENV
echo "$json_matrix"
echo "FQBNS=${json_matrix}" >> "$GITHUB_ENV"
else
echo "FQBNS=" >> $GITHUB_ENV
echo "FQBNS=" >> "$GITHUB_ENV"
fi

View file

@ -1,6 +1,6 @@
#!/bin/bash
OSBITS=`uname -m`
OSBITS=$(uname -m)
if [[ "$OSTYPE" == "linux"* ]]; then
export OS_IS_LINUX="1"
if [[ "$OSBITS" == "i686" ]]; then
@ -49,4 +49,3 @@ if [ ! -d "$ARDUINO_IDE_PATH" ] || [ ! -f "$ARDUINO_IDE_PATH/arduino-cli" ]; the
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR="$ARDUINO_IDE_PATH" sh
fi
fi

View file

@ -5,7 +5,7 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
echo "Installing ESP32 Arduino Core ..."
script_init_path="$PWD"
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif"
cd "$ARDUINO_USR_PATH/hardware/espressif"
cd "$ARDUINO_USR_PATH/hardware/espressif" || exit
echo "Installing Python Serial ..."
pip install pyserial > /dev/null
@ -15,16 +15,16 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
pip install requests > /dev/null
fi
if [ ! -z "$GITHUB_REPOSITORY" ]; then
if [ -n "$GITHUB_REPOSITORY" ]; then
echo "Linking Core..."
ln -s $GITHUB_WORKSPACE esp32
ln -s "$GITHUB_WORKSPACE" esp32
else
echo "Cloning Core Repository..."
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
fi
#echo "Updating Submodules ..."
cd esp32
cd esp32 || exit
#git submodule update --init --recursive > /dev/null 2>&1
echo "Installing Platform Tools ..."
@ -33,7 +33,7 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
else
cd tools && python get.py
fi
cd $script_init_path
cd "$script_init_path" || exit
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"
echo ""

View file

@ -4,7 +4,7 @@
#OSTYPE: 'msys', ARCH: 'x86_64' => win32
#OSTYPE: 'darwin18', ARCH: 'i386' => macos
OSBITS=`uname -m`
OSBITS=$(uname -m)
if [[ "$OSTYPE" == "linux"* ]]; then
export OS_IS_LINUX="1"
ARCHIVE_FORMAT="tar.xz"
@ -77,4 +77,3 @@ if [ ! -d "$ARDUINO_IDE_PATH" ]; then
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
echo ""
fi

View file

@ -1,170 +0,0 @@
#!/bin/bash
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git"
TOOLCHAIN_VERSION="12.2.0+20230208"
ESPTOOLPY_VERSION="~1.40501.0"
ESPRESSIF_ORGANIZATION_NAME="espressif"
SDKCONFIG_DIR="$PLATFORMIO_ESP32_PATH/tools/esp32-arduino-libs"
SCRIPTS_DIR="./.github/scripts"
COUNT_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh count"
CHECK_REQUIREMENTS="${SCRIPTS_DIR}/sketch_utils.sh check_requirements"
echo "Installing Python Wheel ..."
pip install wheel > /dev/null 2>&1
echo "Installing PlatformIO ..."
pip install -U https://github.com/platformio/platformio/archive/master.zip > /dev/null 2>&1
echo "Installing Platform ESP32 ..."
python -m platformio platform install $PLATFORMIO_ESP32_URL > /dev/null 2>&1
echo "Replacing the package versions ..."
replace_script="import json; import os;"
replace_script+="fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+');"
replace_script+="data=json.load(fp);"
# Use framework sources from the repository
replace_script+="data['packages']['framework-arduinoespressif32']['version'] = '*';"
replace_script+="del data['packages']['framework-arduinoespressif32']['owner'];"
# Use toolchain packages from the "espressif" organization
replace_script+="data['packages']['toolchain-xtensa-esp32']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
replace_script+="data['packages']['toolchain-riscv32-esp']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
# Update versions to use the upstream
replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$TOOLCHAIN_VERSION';"
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$TOOLCHAIN_VERSION';"
replace_script+="data['packages']['toolchain-xtensa-esp32s3']['version']='$TOOLCHAIN_VERSION';"
replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$TOOLCHAIN_VERSION';"
# Add new "framework-arduinoespressif32-libs" package
# Read "package_esp32_index.template.json" to extract a url to a zip package for "esp32-arduino-libs"
replace_script+="fpackage=open(os.path.join('package', 'package_esp32_index.template.json'), 'r+');"
replace_script+="package_data=json.load(fpackage);"
replace_script+="fpackage.close();"
replace_script+="libs_package_archive_url=next(next(system['url'] for system in tool['systems'] if system['host'] == 'x86_64-pc-linux-gnu') for tool in package_data['packages'][0]['tools'] if tool['name'] == 'esp32-arduino-libs');"
replace_script+="data['packages'].update({'framework-arduinoespressif32-libs':{'type':'framework','optional':False,'version':libs_package_archive_url}});"
replace_script+="data['packages']['toolchain-xtensa-esp32'].update({'optional':False});"
# esptool.py may require an upstream version (for now platformio is the owner)
replace_script+="data['packages']['tool-esptoolpy']['version']='$ESPTOOLPY_VERSION';"
# Save results
replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close()"
python -c "$replace_script"
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
echo "Linking Core..."
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
else
echo "Cloning Core Repository ..."
git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
fi
echo "PlatformIO for ESP32 has been installed"
echo ""
function build_pio_sketch(){ # build_pio_sketch <board> <options> <path-to-ino>
if [ "$#" -lt 3 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketch <board> <options> <path-to-ino>"
return 1
fi
local board="$1"
local options="$2"
local sketch="$3"
local sketch_dir=$(dirname "$sketch")
echo ""
echo "Compiling '"$(basename "$sketch")"' ..."
python -m platformio ci --board "$board" "$sketch_dir" --project-option="$options"
}
function build_pio_sketches(){ # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks>
if [ "$#" -lt 3 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketches <board> <options> <examples-path> [<chunk> <total-chunks>]"
return 1
fi
local board=$1
local options="$2"
local examples=$3
local chunk_idex=$4
local chunks_num=$5
if [ "$#" -lt 5 ]; then
chunk_idex="0"
chunks_num="1"
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
set +e
${COUNT_SKETCHES} "$examples" "esp32"
local sketchcount=$?
set -e
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
local start_num=$(( $start_index + 1 ))
echo "Found $sketchcount Sketches";
echo "Chunk Count : $chunks_num"
echo "Chunk Size : $chunk_size"
echo "Start Sketch: $start_num"
echo "End Sketch : $end_index"
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "$sketchdirname.ino" != "$sketchname" ]]; then
continue
elif [ -f $sketchdir/ci.json ]; then
# If the target is listed as false, skip the sketch. Otherwise, include it.
is_target=$(jq -r '.targets[esp32]' $sketchdir/ci.json)
if [[ "$is_target" == "false" ]]; then
continue
fi
local has_requirements=$(${CHECK_REQUIREMENTS} $sketchdir "$SDKCONFIG_DIR/esp32/sdkconfig")
if [ "$has_requirements" == "0" ]; then
continue
fi
fi
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
build_pio_sketch "$board" "$options" "$sketch"
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
done
return 0
}

View file

@ -1,46 +1,54 @@
#!/usr/bin/env python
# This script merges two Arduino Board Manager package json files.
# Usage:
# python merge_packages.py package_esp8266com_index.json version/new/package_esp8266com_index.json
# Written by Ivan Grokhotkov, 2015
#
from __future__ import print_function
# from distutils.version import LooseVersion
from packaging.version import Version
import re
import json
import sys
def load_package(filename):
pkg = json.load(open(filename))['packages'][0]
print("Loaded package {0} from {1}".format(pkg['name'], filename), file=sys.stderr)
print("{0} platform(s), {1} tools".format(len(pkg['platforms']), len(pkg['tools'])), file=sys.stderr)
pkg = json.load(open(filename))["packages"][0]
print("Loaded package {0} from {1}".format(pkg["name"], filename), file=sys.stderr)
print("{0} platform(s), {1} tools".format(len(pkg["platforms"]), len(pkg["tools"])), file=sys.stderr)
return pkg
def merge_objects(versions, obj):
for o in obj:
name = o['name'].encode('ascii')
ver = o['version'].encode('ascii')
if not name in versions:
name = o["name"].encode("ascii")
ver = o["version"].encode("ascii")
if name not in versions:
print("found new object, {0}".format(name), file=sys.stderr)
versions[name] = {}
if not ver in versions[name]:
if ver not in versions[name]:
print("found new version {0} for object {1}".format(ver, name), file=sys.stderr)
versions[name][ver] = o
return versions
# Normalize ESP release version string (x.x.x) by adding '-rc<MAXINT>' (x.x.x-rc9223372036854775807) to ensure having REL above any RC
# Dummy approach, functional anyway for current ESP package versioning (unlike NormalizedVersion/LooseVersion/StrictVersion & similar crap)
# Normalize ESP release version string (x.x.x) by adding '-rc<MAXINT>' (x.x.x-rc9223372036854775807)
# to ensure having REL above any RC
# Dummy approach, functional anyway for current ESP package versioning
# (unlike NormalizedVersion/LooseVersion/StrictVersion & similar crap)
def pkgVersionNormalized(versionString):
verStr = str(versionString)
verParts = re.split('\.|-rc|-alpha', verStr, flags=re.IGNORECASE)
verParts = re.split(r"\.|-rc|-alpha", verStr, flags=re.IGNORECASE)
if len(verParts) == 3:
if (sys.version_info > (3, 0)): # Python 3
verStr = str(versionString) + '-rc' + str(sys.maxsize)
if sys.version_info > (3, 0): # Python 3
verStr = str(versionString) + "-rc" + str(sys.maxsize)
else: # Python 2
verStr = str(versionString) + '-rc' + str(sys.maxint)
verStr = str(versionString) + "-rc" + str(sys.maxint)
elif len(verParts) != 4:
print("pkgVersionNormalized WARNING: unexpected version format: {0})".format(verStr), file=sys.stderr)
@ -56,29 +64,35 @@ def main(args):
tools = {}
platforms = {}
pkg1 = load_package(args[1])
tools = merge_objects(tools, pkg1['tools']);
platforms = merge_objects(platforms, pkg1['platforms']);
tools = merge_objects(tools, pkg1["tools"])
platforms = merge_objects(platforms, pkg1["platforms"])
pkg2 = load_package(args[2])
tools = merge_objects(tools, pkg2['tools']);
platforms = merge_objects(platforms, pkg2['platforms']);
tools = merge_objects(tools, pkg2["tools"])
platforms = merge_objects(platforms, pkg2["platforms"])
pkg1['tools'] = []
pkg1['platforms'] = []
pkg1["tools"] = []
pkg1["platforms"] = []
for name in tools:
for version in tools[name]:
print("Adding tool {0}-{1}".format(name, version), file=sys.stderr)
pkg1['tools'].append(tools[name][version])
pkg1["tools"].append(tools[name][version])
for name in platforms:
for version in platforms[name]:
print("Adding platform {0}-{1}".format(name, version), file=sys.stderr)
pkg1['platforms'].append(platforms[name][version])
pkg1["platforms"].append(platforms[name][version])
#pkg1['platforms'] = sorted(pkg1['platforms'], key=lambda k: LooseVersion(pkgVersionNormalized(k['version'])), reverse=True)
pkg1['platforms'] = sorted(pkg1['platforms'], key=lambda k: Version(pkgVersionNormalized(k['version'])), reverse=True)
# pkg1["platforms"] = sorted(
# pkg1["platforms"], key=lambda k: LooseVersion(pkgVersionNormalized(k["version"])), reverse=True
# )
json.dump({'packages':[pkg1]}, sys.stdout, indent=2)
pkg1["platforms"] = sorted(
pkg1["platforms"], key=lambda k: Version(pkgVersionNormalized(k["version"])), reverse=True
)
if __name__ == '__main__':
json.dump({"packages": [pkg1]}, sys.stdout, indent=2)
if __name__ == "__main__":
sys.exit(main(sys.argv))

View file

@ -1,12 +1,13 @@
#/bin/bash
#!/bin/bash
set -e
function get_file_size(){
function get_file_size {
local file="$1"
if [[ "$OSTYPE" == "darwin"* ]]; then
eval `stat -s "$file"`
eval "$(stat -s "$file")"
local res="$?"
echo "$st_size"
echo "${st_size:?}"
return $res
else
stat --printf="%s" "$file"
@ -15,25 +16,32 @@ function get_file_size(){
}
#git_remove_from_pages <file>
function git_remove_from_pages(){
function git_remove_from_pages {
local path=$1
local info=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages"`
local type=`echo "$info" | jq -r '.type'`
if [ ! $type == "file" ]; then
if [ ! $type == "null" ]; then
local info
local type
local sha
local message
info=$(curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages")
type=$(echo "$info" | jq -r '.type')
if [ ! "$type" == "file" ]; then
if [ ! "$type" == "null" ]; then
echo "Wrong type '$type'"
else
echo "File is not on Pages"
fi
return 0
fi
local sha=`echo "$info" | jq -r '.sha'`
local message="Deleting "$(basename $path)
sha=$(echo "$info" | jq -r '.sha')
message="Deleting "$(basename "$path")
local json="{\"branch\":\"gh-pages\",\"message\":\"$message\",\"sha\":\"$sha\"}"
echo "$json" | curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" -X DELETE --data @- "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path"
}
function git_upload_to_pages(){
function git_upload_to_pages {
local path=$1
local src=$2
@ -42,41 +50,50 @@ function git_upload_to_pages(){
return 1
fi
local info=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages"`
local type=`echo "$info" | jq -r '.type'`
local message=$(basename $path)
local info
local type
local message
local sha=""
local content=""
if [ $type == "file" ]; then
sha=`echo "$info" | jq -r '.sha'`
info=$(curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages")
type=$(echo "$info" | jq -r '.type')
message=$(basename "$path")
if [ "$type" == "file" ]; then
sha=$(echo "$info" | jq -r '.sha')
sha=",\"sha\":\"$sha\""
message="Updating $message"
elif [ ! $type == "null" ]; then
elif [ ! "$type" == "null" ]; then
>&2 echo "Wrong type '$type'"
return 1
else
message="Creating $message"
fi
content=`base64 -i "$src"`
content=$(base64 -i "$src")
data="{\"branch\":\"gh-pages\",\"message\":\"$message\",\"content\":\"$content\"$sha}"
echo "$data" | curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" -X PUT --data @- "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path"
}
function git_safe_upload_to_pages(){
function git_safe_upload_to_pages {
local path=$1
local file="$2"
local name=$(basename "$file")
local size=`get_file_size "$file"`
local upload_res=`git_upload_to_pages "$path" "$file"`
if [ $? -ne 0 ]; then
local name
local size
local upload_res
name=$(basename "$file")
size=$(get_file_size "$file")
if ! upload_res=$(git_upload_to_pages "$path" "$file"); then
>&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1
fi
up_size=`echo "$upload_res" | jq -r '.content.size'`
if [ $up_size -ne $size ]; then
up_size=$(echo "$upload_res" | jq -r '.content.size')
if [ "$up_size" -ne "$size" ]; then
>&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset
return 1

View file

@ -4,43 +4,45 @@ set -e
export ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
function build(){
function build {
local target=$1
local chunk_index=$2
local chunks_cnt=$3
local build_log=$4
local sketches_file=$5
shift; shift; shift; shift; shift;
local sketches=$*
local log_level=${5:-none}
local sketches_file=$6
shift 6
local sketches=("$@")
local BUILD_SKETCH="${SCRIPTS_DIR}/sketch_utils.sh build"
local BUILD_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
local args="-ai $ARDUINO_IDE_PATH -au $ARDUINO_USR_PATH"
args+=" -t $target"
local args=("-ai" "$ARDUINO_IDE_PATH" "-au" "$ARDUINO_USR_PATH" "-t" "$target")
if [ "$OS_IS_LINUX" == "1" ]; then
args+=" -p $ARDUINO_ESP32_PATH/libraries"
args+=" -i $chunk_index -m $chunks_cnt"
args+=("-p" "$ARDUINO_ESP32_PATH/libraries" "-i" "$chunk_index" "-m" "$chunks_cnt" "-d" "$log_level")
if [ -n "$sketches_file" ]; then
args+=" -f $sketches_file"
args+=("-f" "$sketches_file")
fi
if [ $build_log -eq 1 ]; then
args+=" -l $build_log"
if [ "$build_log" -eq 1 ]; then
args+=("-l" "$build_log")
fi
${BUILD_SKETCHES} ${args}
${BUILD_SKETCHES} "${args[@]}"
else
for sketch in ${sketches}; do
local sargs="$args -s $(dirname $sketch)"
for sketch in "${sketches[@]}"; do
local sargs=("${args[@]}")
local ctags_version
local preprocessor_version
sargs+=("-s" "$(dirname "$sketch")")
if [ "$OS_IS_WINDOWS" == "1" ] && [ -d "$ARDUINO_IDE_PATH/tools-builder" ]; then
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version
-prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
sargs+=" ${win_opts}"
ctags_version=$(ls "$ARDUINO_IDE_PATH/tools-builder/ctags/")
preprocessor_version=$(ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/")
sargs+=(
"-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version"
"-prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
)
fi
${BUILD_SKETCH} ${sargs}
${BUILD_SKETCH} "${sargs[@]}"
done
fi
}
@ -53,15 +55,13 @@ fi
CHUNK_INDEX=$1
CHUNKS_CNT=$2
BUILD_LOG=$3
SKETCHES_FILE=$4
BUILD_PIO=0
LOG_LEVEL=$4
SKETCHES_FILE=$5
if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then
CHUNK_INDEX=0
CHUNKS_CNT=1
elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ] && [ "$CHUNKS_CNT" -ge 2 ]; then
CHUNK_INDEX=$CHUNKS_CNT
elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
BUILD_PIO=1
fi
if [ -z "$BUILD_LOG" ] || [ "$BUILD_LOG" -le 0 ]; then
@ -72,54 +72,35 @@ fi
#git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
SCRIPTS_DIR="./.github/scripts"
if [ "$BUILD_PIO" -eq 0 ]; then
source ${SCRIPTS_DIR}/install-arduino-cli.sh
source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
source "${SCRIPTS_DIR}/install-arduino-cli.sh"
source "${SCRIPTS_DIR}/install-arduino-core-esp32.sh"
SKETCHES_ESP32="\
$ARDUINO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\
$ARDUINO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino\
$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\
$ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino\
"
SKETCHES_ESP32=(
"$ARDUINO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
"$ARDUINO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino"
"$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
"$ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino"
)
#create sizes_file
sizes_file="$GITHUB_WORKSPACE/cli_compile_$CHUNK_INDEX.json"
if [ "$BUILD_LOG" -eq 1 ]; then
#create sizes_file and echo start of JSON array with "boards" key
echo "{\"boards\": [" > $sizes_file
echo "{\"boards\": [" > "$sizes_file"
fi
#build sketches for different targets
build "esp32s3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32"
build "esp32s2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32"
build "esp32c3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32"
build "esp32c6" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32"
build "esp32h2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32"
build "esp32" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$SKETCHES_FILE" "$SKETCHES_ESP32"
build "esp32p4" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32s3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32s2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32c3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32c6" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32h2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
if [ "$BUILD_LOG" -eq 1 ]; then
#remove last comma from the last JSON object
sed -i '$ s/,$//' "$sizes_file"
#echo end of JSON array
echo "]}" >> $sizes_file
fi
else
source ${SCRIPTS_DIR}/install-platformio-esp32.sh
# PlatformIO ESP32 Test
BOARD="esp32dev"
OPTIONS="board_build.partitions = huge_app.csv"
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
# Basic sanity testing for other series
for board in "esp32-c3-devkitm-1" "esp32-s2-saola-1" "esp32-s3-devkitc-1"
do
python -m platformio ci --board "$board" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.partitions = huge_app.csv"
done
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
echo "]}" >> "$sizes_file"
fi

View file

@ -1,29 +1,34 @@
#!/bin/bash
# Disable shellcheck warning about using 'cat' to read a file.
# Disable shellcheck warning about using individual redirections for each command.
# Disable shellcheck warning about $? uses.
# shellcheck disable=SC2002,SC2129,SC2181,SC2319
if [ ! $GITHUB_EVENT_NAME == "release" ]; then
if [ ! "$GITHUB_EVENT_NAME" == "release" ]; then
echo "Wrong event '$GITHUB_EVENT_NAME'!"
exit 1
fi
EVENT_JSON=`cat $GITHUB_EVENT_PATH`
EVENT_JSON=$(cat "$GITHUB_EVENT_PATH")
action=`echo $EVENT_JSON | jq -r '.action'`
if [ ! $action == "published" ]; then
action=$(echo "$EVENT_JSON" | jq -r '.action')
if [ ! "$action" == "published" ]; then
echo "Wrong action '$action'. Exiting now..."
exit 0
fi
draft=`echo $EVENT_JSON | jq -r '.release.draft'`
if [ $draft == "true" ]; then
draft=$(echo "$EVENT_JSON" | jq -r '.release.draft')
if [ "$draft" == "true" ]; then
echo "It's a draft release. Exiting now..."
exit 0
fi
RELEASE_PRE=`echo $EVENT_JSON | jq -r '.release.prerelease'`
RELEASE_TAG=`echo $EVENT_JSON | jq -r '.release.tag_name'`
RELEASE_BRANCH=`echo $EVENT_JSON | jq -r '.release.target_commitish'`
RELEASE_ID=`echo $EVENT_JSON | jq -r '.release.id'`
RELEASE_PRE=$(echo "$EVENT_JSON" | jq -r '.release.prerelease')
RELEASE_TAG=$(echo "$EVENT_JSON" | jq -r '.release.tag_name')
RELEASE_BRANCH=$(echo "$EVENT_JSON" | jq -r '.release.target_commitish')
RELEASE_ID=$(echo "$EVENT_JSON" | jq -r '.release.id')
SCRIPTS_DIR="./.github/scripts"
OUTPUT_DIR="$GITHUB_WORKSPACE/build"
PACKAGE_NAME="esp32-$RELEASE_TAG"
PACKAGE_JSON_MERGE="$GITHUB_WORKSPACE/.github/scripts/merge_packages.py"
@ -36,17 +41,23 @@ echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID"
echo "Tag: $RELEASE_TAG, Draft: $draft, Pre-Release: $RELEASE_PRE"
# Try extracting something like a JSON with a "boards" array/element and "vendor" fields
BOARDS=`echo $RELEASE_BODY | grep -Pzo '(?s){.*}' | jq -r '.boards[]? // .boards? // empty' | xargs echo -n 2>/dev/null`
VENDOR=`echo $RELEASE_BODY | grep -Pzo '(?s){.*}' | jq -r '.vendor? // empty' | xargs echo -n 2>/dev/null`
if ! [ -z "${BOARDS}" ]; then echo "Releasing board(s): $BOARDS" ; fi
if ! [ -z "${VENDOR}" ]; then echo "Setting packager: $VENDOR" ; fi
BOARDS=$(echo "$RELEASE_BODY" | grep -Pzo '(?s){.*}' | jq -r '.boards[]? // .boards? // empty' | xargs echo -n 2>/dev/null)
VENDOR=$(echo "$RELEASE_BODY" | grep -Pzo '(?s){.*}' | jq -r '.vendor? // empty' | xargs echo -n 2>/dev/null)
function get_file_size(){
if [ -n "${BOARDS}" ]; then
echo "Releasing board(s): $BOARDS"
fi
if [ -n "${VENDOR}" ]; then
echo "Setting packager: $VENDOR"
fi
function get_file_size {
local file="$1"
if [[ "$OSTYPE" == "darwin"* ]]; then
eval `stat -s "$file"`
eval "$(stat -s "$file")"
local res="$?"
echo "$st_size"
echo "${st_size:?}"
return $res
else
stat --printf="%s" "$file"
@ -54,23 +65,29 @@ function get_file_size(){
fi
}
function git_upload_asset(){
local name=$(basename "$1")
function git_upload_asset {
local name
name=$(basename "$1")
# local mime=$(file -b --mime-type "$1")
curl -k -X POST -sH "Authorization: token $GITHUB_TOKEN" -H "Content-Type: application/octet-stream" --data-binary @"$1" "https://uploads.github.com/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets?name=$name"
}
function git_safe_upload_asset(){
function git_safe_upload_asset {
local file="$1"
local name=$(basename "$file")
local size=`get_file_size "$file"`
local upload_res=`git_upload_asset "$file"`
if [ $? -ne 0 ]; then
local name
local size
local upload_res
name=$(basename "$file")
size=$(get_file_size "$file")
if ! upload_res=$(git_upload_asset "$file"); then
>&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1
fi
up_size=`echo "$upload_res" | jq -r '.size'`
if [ $up_size -ne $size ]; then
up_size=$(echo "$upload_res" | jq -r '.size')
if [ "$up_size" -ne "$size" ]; then
>&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset
return 1
@ -79,7 +96,7 @@ function git_safe_upload_asset(){
return $?
}
function git_upload_to_pages(){
function git_upload_to_pages {
local path=$1
local src=$2
@ -88,41 +105,50 @@ function git_upload_to_pages(){
return 1
fi
local info=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages"`
local type=`echo "$info" | jq -r '.type'`
local message=$(basename $path)
local info
local type
local message
local sha=""
local content=""
if [ $type == "file" ]; then
sha=`echo "$info" | jq -r '.sha'`
info=$(curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages")
type=$(echo "$info" | jq -r '.type')
message=$(basename "$path")
if [ "$type" == "file" ]; then
sha=$(echo "$info" | jq -r '.sha')
sha=",\"sha\":\"$sha\""
message="Updating $message"
elif [ ! $type == "null" ]; then
elif [ ! "$type" == "null" ]; then
>&2 echo "Wrong type '$type'"
return 1
else
message="Creating $message"
fi
content=`base64 -i "$src"`
content=$(base64 -i "$src")
data="{\"branch\":\"gh-pages\",\"message\":\"$message\",\"content\":\"$content\"$sha}"
echo "$data" | curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" -X PUT --data @- "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path"
}
function git_safe_upload_to_pages(){
function git_safe_upload_to_pages {
local path=$1
local file="$2"
local name=$(basename "$file")
local size=`get_file_size "$file"`
local upload_res=`git_upload_to_pages "$path" "$file"`
if [ $? -ne 0 ]; then
local name
local size
local upload_res
name=$(basename "$file")
size=$(get_file_size "$file")
if ! upload_res=$(git_upload_to_pages "$path" "$file"); then
>&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1
fi
up_size=`echo "$upload_res" | jq -r '.content.size'`
if [ $up_size -ne $size ]; then
up_size=$(echo "$upload_res" | jq -r '.content.size')
if [ "$up_size" -ne "$size" ]; then
>&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset
return 1
@ -131,15 +157,20 @@ function git_safe_upload_to_pages(){
return $?
}
function merge_package_json(){
function merge_package_json {
local jsonLink=$1
local jsonOut=$2
local old_json=$OUTPUT_DIR/oldJson.json
local merged_json=$OUTPUT_DIR/mergedJson.json
local error_code=0
echo "Downloading previous JSON $jsonLink ..."
curl -L -o "$old_json" "https://github.com/$GITHUB_REPOSITORY/releases/download/$jsonLink?access_token=$GITHUB_TOKEN" 2>/dev/null
if [ $? -ne 0 ]; then echo "ERROR: Download Failed! $?"; exit 1; fi
error_code=$?
if [ $error_code -ne 0 ]; then
echo "ERROR: Download Failed! $error_code"
exit 1
fi
echo "Creating new JSON ..."
set +e
@ -147,7 +178,7 @@ function merge_package_json(){
set -e
set -v
if [ ! -s $merged_json ]; then
if [ ! -s "$merged_json" ]; then
rm -f "$merged_json"
echo "Nothing to merge"
else
@ -188,9 +219,10 @@ else
done
# Copy only relevant variant files
mkdir "$PKG_DIR/variants/"
for variant in `cat ${PKG_DIR}/boards.txt | grep "\.variant=" | cut -d= -f2` ; do
board_list=$(cat "${PKG_DIR}"/boards.txt | grep "\.variant=" | cut -d= -f2)
while IFS= read -r variant; do
cp -Rf "$GITHUB_WORKSPACE/variants/${variant}" "$PKG_DIR/variants/"
done
done <<< "$board_list"
fi
cp -f "$GITHUB_WORKSPACE/CMakeLists.txt" "$PKG_DIR/"
cp -f "$GITHUB_WORKSPACE/idf_component.yml" "$PKG_DIR/"
@ -207,7 +239,7 @@ cp -f "$GITHUB_WORKSPACE/tools/gen_insights_package.py" "$PKG_DIR/tools/"
cp -f "$GITHUB_WORKSPACE/tools/gen_insights_package.exe" "$PKG_DIR/tools/"
cp -Rf "$GITHUB_WORKSPACE/tools/partitions" "$PKG_DIR/tools/"
cp -Rf "$GITHUB_WORKSPACE/tools/ide-debug" "$PKG_DIR/tools/"
cp -f "$GITHUB_WORKSPACE/tools/platformio-build.py" "$PKG_DIR/tools/"
cp -f "$GITHUB_WORKSPACE/tools/pioarduino-build.py" "$PKG_DIR/tools/"
# Remove unnecessary files in the package folder
echo "Cleaning up folders ..."
@ -219,12 +251,8 @@ find "$PKG_DIR" -name '*.git*' -type f -delete
##
RVTC_NAME="riscv32-esp-elf-gcc"
RVTC_NEW_NAME="esp-rv32"
X32TC_NAME="xtensa-esp32-elf-gcc"
X32TC_NAME="xtensa-esp-elf-gcc"
X32TC_NEW_NAME="esp-x32"
XS2TC_NAME="xtensa-esp32s2-elf-gcc"
XS2TC_NEW_NAME="esp-xs2"
XS3TC_NAME="xtensa-esp32s3-elf-gcc"
XS3TC_NEW_NAME="esp-xs3"
# Replace tools locations in platform.txt
echo "Generating platform.txt..."
@ -233,40 +261,40 @@ sed "s/version=.*/version=$RELEASE_TAG/g" | \
sed 's/tools\.esp32-arduino-libs\.path\.windows=.*//g' | \
sed 's/{runtime\.platform\.path}.tools.esp32-arduino-libs/\{runtime.tools.esp32-arduino-libs.path\}/g' | \
sed 's/{runtime\.platform\.path}.tools.xtensa-esp-elf-gdb/\{runtime.tools.xtensa-esp-elf-gdb.path\}/g' | \
sed "s/{runtime\.platform\.path}.tools.xtensa-esp32-elf/\\{runtime.tools.$X32TC_NEW_NAME.path\\}/g" | \
sed "s/{runtime\.platform\.path}.tools.xtensa-esp32s2-elf/\\{runtime.tools.$XS2TC_NEW_NAME.path\\}/g" | \
sed "s/{runtime\.platform\.path}.tools.xtensa-esp32s3-elf/\\{runtime.tools.$XS3TC_NEW_NAME.path\\}/g" | \
sed "s/{runtime\.platform\.path}.tools.xtensa-esp-elf/\\{runtime.tools.$X32TC_NEW_NAME.path\\}/g" | \
sed 's/{runtime\.platform\.path}.tools.riscv32-esp-elf-gdb/\{runtime.tools.riscv32-esp-elf-gdb.path\}/g' | \
sed "s/{runtime\.platform\.path}.tools.riscv32-esp-elf/\\{runtime.tools.$RVTC_NEW_NAME.path\\}/g" | \
sed 's/{runtime\.platform\.path}.tools.esptool/\{runtime.tools.esptool_py.path\}/g' | \
sed 's/{runtime\.platform\.path}.tools.openocd-esp32/\{runtime.tools.openocd-esp32.path\}/g' \
> "$PKG_DIR/platform.txt"
sed 's/{runtime\.platform\.path}.tools.openocd-esp32/\{runtime.tools.openocd-esp32.path\}/g' > "$PKG_DIR/platform.txt"
if ! [ -z ${VENDOR} ]; then
if [ -n "${VENDOR}" ]; then
# Append vendor name to platform.txt to create a separate section
sed -i "/^name=.*/s/$/ ($VENDOR)/" "$PKG_DIR/platform.txt"
fi
# Add header with version information
echo "Generating core_version.h ..."
ver_define=`echo $RELEASE_TAG | tr "[:lower:].\055" "[:upper:]_"`
ver_hex=`git -C "$GITHUB_WORKSPACE" rev-parse --short=8 HEAD 2>/dev/null`
echo \#define ARDUINO_ESP32_GIT_VER 0x$ver_hex > "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_GIT_DESC `git -C "$GITHUB_WORKSPACE" describe --tags 2>/dev/null` >> "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_RELEASE_$ver_define >> "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_RELEASE \"$ver_define\" >> "$PKG_DIR/cores/esp32/core_version.h"
ver_define=$(echo "$RELEASE_TAG" | tr "[:lower:].\055" "[:upper:]_")
ver_hex=$(git -C "$GITHUB_WORKSPACE" rev-parse --short=8 HEAD 2>/dev/null)
echo \#define ARDUINO_ESP32_GIT_VER 0x"$ver_hex" > "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_GIT_DESC "$(git -C "$GITHUB_WORKSPACE" describe --tags 2>/dev/null)" >> "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_RELEASE_"$ver_define" >> "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_RELEASE \""$ver_define"\" >> "$PKG_DIR/cores/esp32/core_version.h"
# Compress package folder
echo "Creating ZIP ..."
pushd "$OUTPUT_DIR" >/dev/null
zip -qr "$PACKAGE_ZIP" "$PACKAGE_NAME"
if [ $? -ne 0 ]; then echo "ERROR: Failed to create $PACKAGE_ZIP ($?)"; exit 1; fi
if [ $? -ne 0 ]; then
echo "ERROR: Failed to create $PACKAGE_ZIP ($?)"
exit 1
fi
# Calculate SHA-256
echo "Calculating SHA sum ..."
PACKAGE_PATH="$OUTPUT_DIR/$PACKAGE_ZIP"
PACKAGE_SHA=`shasum -a 256 "$PACKAGE_ZIP" | cut -f 1 -d ' '`
PACKAGE_SIZE=`get_file_size "$PACKAGE_ZIP"`
PACKAGE_SHA=$(shasum -a 256 "$PACKAGE_ZIP" | cut -f 1 -d ' ')
PACKAGE_SIZE=$(get_file_size "$PACKAGE_ZIP")
popd >/dev/null
rm -rf "$PKG_DIR"
echo "'$PACKAGE_ZIP' Created! Size: $PACKAGE_SIZE, SHA-256: $PACKAGE_SHA"
@ -274,7 +302,7 @@ echo
# Upload package to release page
echo "Uploading package to release page ..."
PACKAGE_URL=`git_safe_upload_asset "$PACKAGE_PATH"`
PACKAGE_URL=$(git_safe_upload_asset "$PACKAGE_PATH")
echo "Package Uploaded"
echo "Download URL: $PACKAGE_URL"
echo
@ -282,9 +310,9 @@ echo
##
## TEMP WORKAROUND FOR RV32 LONG PATH ON WINDOWS
##
RVTC_VERSION=`cat $PACKAGE_JSON_TEMPLATE | jq -r ".packages[0].platforms[0].toolsDependencies[] | select(.name == \"$RVTC_NAME\") | .version" | cut -d '_' -f 2`
RVTC_VERSION=$(cat "$PACKAGE_JSON_TEMPLATE" | jq -r ".packages[0].platforms[0].toolsDependencies[] | select(.name == \"$RVTC_NAME\") | .version" | cut -d '_' -f 2)
# RVTC_VERSION=`date -j -f '%Y%m%d' "$RVTC_VERSION" '+%y%m'` # MacOS
RVTC_VERSION=`date -d "$RVTC_VERSION" '+%y%m'`
RVTC_VERSION=$(date -d "$RVTC_VERSION" '+%y%m')
rvtc_jq_arg="\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$RVTC_NAME\")).version = \"$RVTC_VERSION\" |\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$RVTC_NAME\")).name = \"$RVTC_NEW_NAME\" |\
@ -293,15 +321,7 @@ rvtc_jq_arg="\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$X32TC_NAME\")).version = \"$RVTC_VERSION\" |\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$X32TC_NAME\")).name = \"$X32TC_NEW_NAME\" |\
(.packages[0].tools[] | select(.name==\"$X32TC_NAME\")).version = \"$RVTC_VERSION\" |\
(.packages[0].tools[] | select(.name==\"$X32TC_NAME\")).name = \"$X32TC_NEW_NAME\" |\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$XS2TC_NAME\")).version = \"$RVTC_VERSION\" |\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$XS2TC_NAME\")).name = \"$XS2TC_NEW_NAME\" |\
(.packages[0].tools[] | select(.name==\"$XS2TC_NAME\")).version = \"$RVTC_VERSION\" |\
(.packages[0].tools[] | select(.name==\"$XS2TC_NAME\")).name = \"$XS2TC_NEW_NAME\" |\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$XS3TC_NAME\")).version = \"$RVTC_VERSION\" |\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$XS3TC_NAME\")).name = \"$XS3TC_NEW_NAME\" |\
(.packages[0].tools[] | select(.name==\"$XS3TC_NAME\")).version = \"$RVTC_VERSION\" |\
(.packages[0].tools[] | select(.name==\"$XS3TC_NAME\")).name = \"$XS3TC_NEW_NAME\""
(.packages[0].tools[] | select(.name==\"$X32TC_NAME\")).name = \"$X32TC_NEW_NAME\""
cat "$PACKAGE_JSON_TEMPLATE" | jq "$rvtc_jq_arg" > "$OUTPUT_DIR/package-rvfix.json"
PACKAGE_JSON_TEMPLATE="$OUTPUT_DIR/package-rvfix.json"
@ -317,17 +337,20 @@ jq_arg=".packages[0].platforms[0].version = \"$RELEASE_TAG\" | \
.packages[0].platforms[0].checksum = \"SHA-256:$PACKAGE_SHA\""
# Generate package JSONs
echo "Genarating $PACKAGE_JSON_DEV ..."
echo "Generating $PACKAGE_JSON_DEV ..."
cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_DEV"
if [ "$RELEASE_PRE" == "false" ]; then
echo "Genarating $PACKAGE_JSON_REL ..."
echo "Generating $PACKAGE_JSON_REL ..."
cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_REL"
fi
# Figure out the last release or pre-release
echo "Getting previous releases ..."
releasesJson=`curl -sH "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$GITHUB_REPOSITORY/releases" 2>/dev/null`
if [ $? -ne 0 ]; then echo "ERROR: Get Releases Failed! ($?)"; exit 1; fi
releasesJson=$(curl -sH "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$GITHUB_REPOSITORY/releases" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "ERROR: Get Releases Failed! ($?)"
exit 1
fi
set +e
prev_release=$(echo "$releasesJson" | jq -e -r ". | map(select(.draft == false and .prerelease == false)) | sort_by(.published_at | - fromdateiso8601) | .[0].tag_name")
@ -347,13 +370,13 @@ echo "Previous (any)release: $prev_any_release"
echo
# Merge package JSONs with previous releases
if [ ! -z "$prev_any_release" ] && [ "$prev_any_release" != "null" ]; then
if [ -n "$prev_any_release" ] && [ "$prev_any_release" != "null" ]; then
echo "Merging with JSON from $prev_any_release ..."
merge_package_json "$prev_any_release/$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV"
fi
if [ "$RELEASE_PRE" == "false" ]; then
if [ ! -z "$prev_release" ] && [ "$prev_release" != "null" ]; then
if [ -n "$prev_release" ] && [ "$prev_release" != "null" ]; then
echo "Merging with JSON from $prev_release ..."
merge_package_json "$prev_release/$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL"
fi
@ -363,21 +386,30 @@ fi
echo "Installing arduino-cli ..."
export PATH="/home/runner/bin:$PATH"
source ./.github/scripts/install-arduino-cli.sh
source "${SCRIPTS_DIR}/install-arduino-cli.sh"
echo "Testing $PACKAGE_JSON_DEV install ..."
echo "Installing esp32 ..."
arduino-cli core install esp32:esp32 --additional-urls "file://$OUTPUT_DIR/$PACKAGE_JSON_DEV"
if [ $? -ne 0 ]; then echo "ERROR: Failed to install esp32 ($?)"; exit 1; fi
if [ $? -ne 0 ]; then
echo "ERROR: Failed to install esp32 ($?)"
exit 1
fi
echo "Compiling example ..."
arduino-cli compile --fqbn esp32:esp32:esp32 $GITHUB_WORKSPACE/libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino
if [ $? -ne 0 ]; then echo "ERROR: Failed to compile example ($?)"; exit 1; fi
arduino-cli compile --fqbn esp32:esp32:esp32 "$GITHUB_WORKSPACE"/libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino
if [ $? -ne 0 ]; then
echo "ERROR: Failed to compile example ($?)"
exit 1
fi
echo "Uninstalling esp32 ..."
arduino-cli core uninstall esp32:esp32
if [ $? -ne 0 ]; then echo "ERROR: Failed to uninstall esp32 ($?)"; exit 1; fi
if [ $? -ne 0 ]; then
echo "ERROR: Failed to uninstall esp32 ($?)"
exit 1
fi
echo "Test successful!"
@ -386,15 +418,24 @@ if [ "$RELEASE_PRE" == "false" ]; then
echo "Installing esp32 ..."
arduino-cli core install esp32:esp32 --additional-urls "file://$OUTPUT_DIR/$PACKAGE_JSON_REL"
if [ $? -ne 0 ]; then echo "ERROR: Failed to install esp32 ($?)"; exit 1; fi
if [ $? -ne 0 ]; then
echo "ERROR: Failed to install esp32 ($?)"
exit 1
fi
echo "Compiling example ..."
arduino-cli compile --fqbn esp32:esp32:esp32 $GITHUB_WORKSPACE/libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino
if [ $? -ne 0 ]; then echo "ERROR: Failed to compile example ($?)"; exit 1; fi
arduino-cli compile --fqbn esp32:esp32:esp32 "$GITHUB_WORKSPACE"/libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino
if [ $? -ne 0 ]; then
echo "ERROR: Failed to compile example ($?)"
exit 1
fi
echo "Uninstalling esp32 ..."
arduino-cli core uninstall esp32:esp32
if [ $? -ne 0 ]; then echo "ERROR: Failed to uninstall esp32 ($?)"; exit 1; fi
if [ $? -ne 0 ]; then
echo "ERROR: Failed to uninstall esp32 ($?)"
exit 1
fi
echo "Test successful!"
fi
@ -402,13 +443,13 @@ fi
# Upload package JSONs
echo "Uploading $PACKAGE_JSON_DEV ..."
echo "Download URL: "`git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_DEV"`
echo "Pages URL: "`git_safe_upload_to_pages "$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV"`
echo "Download URL: $(git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_DEV")"
echo "Pages URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV")"
echo
if [ "$RELEASE_PRE" == "false" ]; then
echo "Uploading $PACKAGE_JSON_REL ..."
echo "Download URL: "`git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_REL"`
echo "Pages URL: "`git_safe_upload_to_pages "$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL"`
echo "Download URL: $(git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_REL")"
echo "Pages URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL")"
echo
fi

View file

@ -11,23 +11,23 @@ elif [[ $LIB_CHANGED == 'true' ]]; then
echo "Libraries changed. Building only affected sketches."
if [[ $NETWORKING_CHANGED == 'true' ]]; then
echo "Networking libraries changed. Building networking related sketches."
networking_sketches="$(find libraries/WiFi -name *.ino) "
networking_sketches+="$(find libraries/Ethernet -name *.ino) "
networking_sketches+="$(find libraries/PPP -name *.ino) "
networking_sketches+="$(find libraries/NetworkClientSecure -name *.ino) "
networking_sketches+="$(find libraries/WebServer -name *.ino) "
networking_sketches="$(find libraries/WiFi -name '*.ino') "
networking_sketches+="$(find libraries/Ethernet -name '*.ino') "
networking_sketches+="$(find libraries/PPP -name '*.ino') "
networking_sketches+="$(find libraries/NetworkClientSecure -name '*.ino') "
networking_sketches+="$(find libraries/WebServer -name '*.ino') "
fi
if [[ $FS_CHANGED == 'true' ]]; then
echo "FS libraries changed. Building FS related sketches."
fs_sketches="$(find libraries/SD -name *.ino) "
fs_sketches+="$(find libraries/SD_MMC -name *.ino) "
fs_sketches+="$(find libraries/SPIFFS -name *.ino) "
fs_sketches+="$(find libraries/LittleFS -name *.ino) "
fs_sketches+="$(find libraries/FFat -name *.ino) "
fs_sketches="$(find libraries/SD -name '*.ino') "
fs_sketches+="$(find libraries/SD_MMC -name '*.ino') "
fs_sketches+="$(find libraries/SPIFFS -name '*.ino') "
fs_sketches+="$(find libraries/LittleFS -name '*.ino') "
fs_sketches+="$(find libraries/FFat -name '*.ino') "
fi
sketches="$networking_sketches $fs_sketches"
for file in $LIB_FILES; do
lib=$(echo $file | awk -F "/" '{print $1"/"$2}')
lib=$(echo "$file" | awk -F "/" '{print $1"/"$2}')
if [[ "$file" == *.ino ]]; then
# If file ends with .ino, add it to the list of sketches
echo "Sketch found: $file"
@ -36,14 +36,14 @@ elif [[ $LIB_CHANGED == 'true' ]]; then
# If file is inside the src directory, find all sketches in the lib/examples directory
echo "Library src file found: $file"
if [[ -d $lib/examples ]]; then
lib_sketches=$(find $lib/examples -name *.ino)
lib_sketches=$(find "$lib"/examples -name '*.ino')
sketches+="$lib_sketches "
echo "Library sketches: $lib_sketches"
fi
else
# If file is in a example folder but it is not a sketch, find all sketches in the current directory
echo "File in example folder found: $file"
sketch=$(find $(dirname $file) -name *.ino)
sketch=$(find "$(dirname "$file")" -name '*.ino')
sketches+="$sketch "
echo "Sketch in example folder: $sketch"
fi
@ -53,9 +53,9 @@ fi
if [[ -n $sketches ]]; then
# Remove duplicates
sketches=$(echo $sketches | tr ' ' '\n' | sort | uniq)
sketches=$(echo "$sketches" | tr ' ' '\n' | sort | uniq)
for sketch in $sketches; do
echo $sketch >> sketches_found.txt
echo "$sketch" >> sketches_found.txt
chunks_count=$((chunks_count+1))
done
echo "Number of sketches found: $chunks_count"
@ -69,15 +69,16 @@ if [[ -n $sketches ]]; then
fi
chunks='["0"'
for i in $(seq 1 $(( $chunks_count - 1 )) ); do
for i in $(seq 1 $(( chunks_count - 1 )) ); do
chunks+=",\"$i\""
done
chunks+="]"
echo "build_all=$build_all" >> $GITHUB_OUTPUT
echo "build_libraries=$BUILD_LIBRARIES" >> $GITHUB_OUTPUT
echo "build_static_sketches=$BUILD_STATIC_SKETCHES" >> $GITHUB_OUTPUT
echo "build_idf=$BUILD_IDF" >> $GITHUB_OUTPUT
echo "build_platformio=$BUILD_PLATFORMIO" >> $GITHUB_OUTPUT
echo "chunk_count=$chunks_count" >> $GITHUB_OUTPUT
echo "chunks=$chunks" >> $GITHUB_OUTPUT
{
echo "build_all=$build_all"
echo "build_libraries=$BUILD_LIBRARIES"
echo "build_static_sketches=$BUILD_STATIC_SKETCHES"
echo "build_idf=$BUILD_IDF"
echo "chunk_count=$chunks_count"
echo "chunks=$chunks"
} >> "$GITHUB_OUTPUT"

View file

@ -8,10 +8,12 @@ else
SDKCONFIG_DIR="tools/esp32-arduino-libs"
fi
function check_requirements(){ # check_requirements <sketchdir> <sdkconfig_path>
function check_requirements { # check_requirements <sketchdir> <sdkconfig_path>
local sketchdir=$1
local sdkconfig_path=$2
local has_requirements=1
local requirements
local requirements_or
if [ ! -f "$sdkconfig_path" ] || [ ! -f "$sketchdir/ci.json" ]; then
echo "ERROR: sdkconfig or ci.json not found" 1>&2
@ -19,10 +21,10 @@ function check_requirements(){ # check_requirements <sketchdir> <sdkconfig_path>
# CI will fail and the user will know that the sketch has a problem.
else
# Check if the sketch requires any configuration options (AND)
local requirements=$(jq -r '.requires[]? // empty' "$sketchdir/ci.json")
requirements=$(jq -r '.requires[]? // empty' "$sketchdir/ci.json")
if [[ "$requirements" != "null" && "$requirements" != "" ]]; then
for requirement in $requirements; do
requirement=$(echo $requirement | xargs)
requirement=$(echo "$requirement" | xargs)
found_line=$(grep -E "^$requirement" "$sdkconfig_path")
if [[ "$found_line" == "" ]]; then
has_requirements=0
@ -31,11 +33,11 @@ function check_requirements(){ # check_requirements <sketchdir> <sdkconfig_path>
fi
# Check if the sketch requires any configuration options (OR)
local requirements_or=$(jq -r '.requires_any[]? // empty' "$sketchdir/ci.json")
requirements_or=$(jq -r '.requires_any[]? // empty' "$sketchdir/ci.json")
if [[ "$requirements_or" != "null" && "$requirements_or" != "" ]]; then
local found=false
for requirement in $requirements_or; do
requirement=$(echo $requirement | xargs)
requirement=$(echo "$requirement" | xargs)
found_line=$(grep -E "^$requirement" "$sdkconfig_path")
if [[ "$found_line" != "" ]]; then
found=true
@ -51,8 +53,8 @@ function check_requirements(){ # check_requirements <sketchdir> <sdkconfig_path>
echo $has_requirements
}
function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [extra-options]
while [ ! -z "$1" ]; do
function build_sketch { # build_sketch <ide_path> <user_path> <path-to-ino> [extra-options]
while [ -n "$1" ]; do
case "$1" in
-ai )
shift
@ -97,10 +99,10 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
shift
done
xtra_opts=$*
xtra_opts=("$@")
len=0
if [ -z $sketchdir ]; then
if [ -z "$sketchdir" ]; then
echo "ERROR: Sketch directory not provided"
echo "$USAGE"
exit 1
@ -108,8 +110,8 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
# No FQBN was passed, try to get it from other options
if [ -z $fqbn ]; then
if [ -z $target ]; then
if [ -z "$fqbn" ]; then
if [ -z "$target" ]; then
echo "ERROR: Unspecified chip"
echo "$USAGE"
exit 1
@ -120,25 +122,25 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
# precedence. Note that the following logic also falls to the default
# parameters if no arguments were passed and no file was found.
if [ -z $options ] && [ -f $sketchdir/ci.json ]; then
if [ -z "$options" ] && [ -f "$sketchdir"/ci.json ]; then
# The config file could contain multiple FQBNs for one chip. If
# that's the case we build one time for every FQBN.
len=`jq -r --arg target $target '.fqbn[$target] | length' $sketchdir/ci.json`
if [ $len -gt 0 ]; then
fqbn=`jq -r --arg target $target '.fqbn[$target] | sort' $sketchdir/ci.json`
len=$(jq -r --arg target "$target" '.fqbn[$target] | length' "$sketchdir"/ci.json)
if [ "$len" -gt 0 ]; then
fqbn=$(jq -r --arg target "$target" '.fqbn[$target] | sort' "$sketchdir"/ci.json)
fi
fi
if [ ! -z $options ] || [ $len -eq 0 ]; then
if [ -n "$options" ] || [ "$len" -eq 0 ]; then
# Since we are passing options, we will end up with only one FQBN to
# build.
len=1
if [ -f $sketchdir/ci.json ]; then
fqbn_append=`jq -r '.fqbn_append' $sketchdir/ci.json`
if [ $fqbn_append == "null" ]; then
if [ -f "$sketchdir"/ci.json ]; then
fqbn_append=$(jq -r '.fqbn_append' "$sketchdir"/ci.json)
if [ "$fqbn_append" == "null" ]; then
fqbn_append=""
fi
fi
@ -153,6 +155,7 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
esp32c3_opts=$(echo "$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g')
esp32c6_opts=$(echo "$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g')
esp32h2_opts=$(echo "$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g')
esp32p4_opts=$(echo "PSRAM=enabled,USBMode=default,$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g')
# Select the common part of the FQBN based on the target. The rest will be
# appended depending on the passed options.
@ -184,6 +187,14 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
[ -n "${options:-$esp32h2_opts}" ] && opt=":${options:-$esp32h2_opts}"
fqbn="espressif:esp32:esp32h2$opt"
;;
"esp32p4")
[ -n "${options:-$esp32p4_opts}" ] && opt=":${options:-$esp32p4_opts}"
fqbn="espressif:esp32:esp32p4$opt"
;;
*)
echo "ERROR: Invalid chip: $target"
exit 1
;;
esac
# Make it look like a JSON array.
@ -202,7 +213,7 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
exit 1
fi
# The directory that will hold all the artifcats (the build directory) is
# The directory that will hold all the artifacts (the build directory) is
# provided through:
# 1. An env variable called ARDUINO_BUILD_DIR.
# 2. Created at the sketch level as "build" in the case of a single
@ -210,17 +221,18 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
# 3. Created at the sketch level as "buildX" where X is the number
# of configuration built in case of a multiconfiguration test.
sketchname=$(basename $sketchdir)
sketchname=$(basename "$sketchdir")
local has_requirements
if [ -f $sketchdir/ci.json ]; then
if [ -f "$sketchdir"/ci.json ]; then
# If the target is listed as false, skip the sketch. Otherwise, include it.
is_target=$(jq -r --arg target $target '.targets[$target]' $sketchdir/ci.json)
is_target=$(jq -r --arg target "$target" '.targets[$target]' "$sketchdir"/ci.json)
if [[ "$is_target" == "false" ]]; then
echo "Skipping $sketchname for target $target"
exit 0
fi
local has_requirements=$(check_requirements "$sketchdir" "$SDKCONFIG_DIR/$target/sdkconfig")
has_requirements=$(check_requirements "$sketchdir" "$SDKCONFIG_DIR/$target/sdkconfig")
if [ "$has_requirements" == "0" ]; then
echo "Target $target does not meet the requirements for $sketchname. Skipping."
exit 0
@ -230,7 +242,7 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
if [ -n "$ARDUINO_BUILD_DIR" ]; then
build_dir="$ARDUINO_BUILD_DIR"
elif [ $len -eq 1 ]; then
elif [ "$len" -eq 1 ]; then
# build_dir="$sketchdir/build"
build_dir="$HOME/.arduino/tests/$sketchname/build.tmp"
fi
@ -239,51 +251,49 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
sizes_file="$GITHUB_WORKSPACE/cli_compile_$chunk_index.json"
mkdir -p "$ARDUINO_CACHE_DIR"
for i in `seq 0 $(($len - 1))`
do
if [ $len -ne 1 ]; then
for i in $(seq 0 $((len - 1))); do
if [ "$len" -ne 1 ]; then
# build_dir="$sketchdir/build$i"
build_dir="$HOME/.arduino/tests/$sketchname/build$i.tmp"
fi
rm -rf $build_dir
mkdir -p $build_dir
rm -rf "$build_dir"
mkdir -p "$build_dir"
currfqbn=`echo $fqbn | jq -r --argjson i $i '.[$i]'`
currfqbn=$(echo "$fqbn" | jq -r --argjson i "$i" '.[$i]')
if [ -f "$ide_path/arduino-cli" ]; then
echo "Building $sketchname with arduino-cli and FQBN=$currfqbn"
curroptions=`echo "$currfqbn" | cut -d':' -f4`
currfqbn=`echo "$currfqbn" | cut -d':' -f1-3`
$ide_path/arduino-cli compile \
curroptions=$(echo "$currfqbn" | cut -d':' -f4)
currfqbn=$(echo "$currfqbn" | cut -d':' -f1-3)
"$ide_path"/arduino-cli compile \
--fqbn "$currfqbn" \
--board-options "$curroptions" \
--warnings "all" \
--build-property "compiler.warning_flags.all=-Wall -Werror=all -Wextra" \
--build-cache-path "$ARDUINO_CACHE_DIR" \
--build-path "$build_dir" \
$xtra_opts "${sketchdir}" \
2>&1 | tee $output_file
"${xtra_opts[@]}" "${sketchdir}" \
2>&1 | tee "$output_file"
exit_status=${PIPESTATUS[0]}
if [ $exit_status -ne 0 ]; then
if [ "$exit_status" -ne 0 ]; then
echo "ERROR: Compilation failed with error code $exit_status"
exit $exit_status
exit "$exit_status"
fi
if [ $log_compilation ]; then
if [ -n "$log_compilation" ]; then
#Extract the program storage space and dynamic memory usage in bytes and percentage in separate variables from the output, just the value without the string
flash_bytes=$(grep -oE 'Sketch uses ([0-9]+) bytes' $output_file | awk '{print $3}')
flash_percentage=$(grep -oE 'Sketch uses ([0-9]+) bytes \(([0-9]+)%\)' $output_file | awk '{print $5}' | tr -d '(%)')
ram_bytes=$(grep -oE 'Global variables use ([0-9]+) bytes' $output_file | awk '{print $4}')
ram_percentage=$(grep -oE 'Global variables use ([0-9]+) bytes \(([0-9]+)%\)' $output_file | awk '{print $6}' | tr -d '(%)')
flash_bytes=$(grep -oE 'Sketch uses ([0-9]+) bytes' "$output_file" | awk '{print $3}')
flash_percentage=$(grep -oE 'Sketch uses ([0-9]+) bytes \(([0-9]+)%\)' "$output_file" | awk '{print $5}' | tr -d '(%)')
ram_bytes=$(grep -oE 'Global variables use ([0-9]+) bytes' "$output_file" | awk '{print $4}')
ram_percentage=$(grep -oE 'Global variables use ([0-9]+) bytes \(([0-9]+)%\)' "$output_file" | awk '{print $6}' | tr -d '(%)')
# Extract the directory path excluding the filename
directory_path=$(dirname "$sketch")
# Define the constant part
constant_part="/home/runner/Arduino/hardware/espressif/esp32/libraries/"
# Extract the desired substring using sed
lib_sketch_name=$(echo "$directory_path" | sed "s|$constant_part||")
# Extract the desired substring
lib_sketch_name="${directory_path#"$constant_part"}"
#append json file where key is fqbn, sketch name, sizes -> extracted values
echo "{\"name\": \"$lib_sketch_name\",
\"sizes\": [{
@ -299,15 +309,15 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
echo "Building $sketchname with arduino-builder and FQBN=$currfqbn"
echo "Build path = $build_dir"
$ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \
-fqbn=\"$currfqbn\" \
"$ide_path"/arduino-builder -compile -logger=human -core-api-version=10810 \
-fqbn=\""$currfqbn"\" \
-warnings="all" \
-tools "$ide_path/tools-builder" \
-hardware "$user_path/hardware" \
-libraries "$user_path/libraries" \
-build-cache "$ARDUINO_CACHE_DIR" \
-build-path "$build_dir" \
$xtra_opts "${sketchdir}/${sketchname}.ino"
"${xtra_opts[@]}" "${sketchdir}/${sketchname}.ino"
exit_status=$?
if [ $exit_status -ne 0 ]; then
@ -334,11 +344,12 @@ function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [ex
unset options
}
function count_sketches(){ # count_sketches <path> [target] [file] [ignore-requirements]
function count_sketches { # count_sketches <path> [target] [file] [ignore-requirements]
local path=$1
local target=$2
local ignore_requirements=$3
local file=$4
local sketches
if [ $# -lt 1 ]; then
echo "ERROR: Illegal number of parameters"
@ -352,42 +363,47 @@ function count_sketches(){ # count_sketches <path> [target] [file] [ignore-requi
fi
if [ -f "$file" ]; then
local sketches=$(cat $file)
sketches=$(cat "$file")
else
local sketches=$(find $path -name *.ino | sort)
sketches=$(find "$path" -name '*.ino' | sort)
fi
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
local sketchdir
local sketchdirname
local sketchname
local has_requirements
sketchdir=$(dirname "$sketch")
sketchdirname=$(basename "$sketchdir")
sketchname=$(basename "$sketch")
if [[ "$sketchdirname.ino" != "$sketchname" ]]; then
continue
elif [[ -n $target ]] && [[ -f $sketchdir/ci.json ]]; then
# If the target is listed as false, skip the sketch. Otherwise, include it.
is_target=$(jq -r --arg target $target '.targets[$target]' $sketchdir/ci.json)
is_target=$(jq -r --arg target "$target" '.targets[$target]' "$sketchdir"/ci.json)
if [[ "$is_target" == "false" ]]; then
continue
fi
if [ "$ignore_requirements" != "1" ]; then
local has_requirements=$(check_requirements "$sketchdir" "$SDKCONFIG_DIR/$target/sdkconfig")
has_requirements=$(check_requirements "$sketchdir" "$SDKCONFIG_DIR/$target/sdkconfig")
if [ "$has_requirements" == "0" ]; then
continue
fi
fi
fi
echo $sketch >> sketches.txt
sketchnum=$(($sketchnum + 1))
echo "$sketch" >> sketches.txt
sketchnum=$((sketchnum + 1))
done
return $sketchnum
}
function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <path> <chunk> <total-chunks> [extra-options]
local args=""
while [ ! -z "$1" ]; do
function build_sketches { # build_sketches <ide_path> <user_path> <target> <path> <chunk> <total-chunks> [extra-options]
local args=()
while [ -n "$1" ]; do
case $1 in
-ai )
shift
@ -400,12 +416,12 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <pat
-t )
shift
target=$1
args+=" -t $target"
args+=("-t" "$target")
;;
-fqbn )
shift
fqbn=$1
args+=" -fqbn $fqbn"
args+=("-fqbn" "$fqbn")
;;
-p )
shift
@ -427,6 +443,11 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <pat
shift
sketches_file=$1
;;
-d )
shift
debug_level="$1"
args+=("-d" "$debug_level")
;;
* )
break
;;
@ -434,10 +455,10 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <pat
shift
done
local xtra_opts=$*
local xtra_opts=("$@")
if [ -z "$chunk_index" ] || [ -z "$chunk_max" ]; then
echo "ERROR: Invalid chunk paramters"
echo "ERROR: Invalid chunk parameters"
echo "$USAGE"
exit 1
fi
@ -460,13 +481,16 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <pat
local sketchcount=$?
fi
set -e
local sketches=$(cat sketches.txt)
local sketches
sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunk_max ))
local all_chunks=$(( $chunk_max * $chunk_size ))
local chunk_size
local all_chunks
chunk_size=$(( sketchcount / chunk_max ))
all_chunks=$(( chunk_max * chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
chunk_size=$(( chunk_size + 1 ))
fi
local start_index=0
@ -475,19 +499,20 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <pat
start_index=$chunk_index
end_index=$sketchcount
else
start_index=$(( $chunk_index * $chunk_size ))
start_index=$(( chunk_index * chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "No sketches to build for $target in this chunk"
return 0
fi
end_index=$(( $(( $chunk_index + 1 )) * $chunk_size ))
end_index=$(( $(( chunk_index + 1 )) * chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
fi
local start_num=$(( $start_index + 1 ))
local start_num
start_num=$(( start_index + 1 ))
echo "Found $sketchcount Sketches for target '$target'";
echo "Chunk Index : $chunk_index"
echo "Chunk Count : $chunk_max"
@ -496,14 +521,14 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <pat
echo "End Sketch : $end_index"
#if fqbn is not passed then set it to default for compilation log
if [ -z $fqbn ]; then
if [ -z "$fqbn" ]; then
log_fqbn="espressif:esp32:$target"
else
log_fqbn=$fqbn
fi
sizes_file="$GITHUB_WORKSPACE/cli_compile_$chunk_index.json"
if [ $log_compilation ]; then
if [ -n "$log_compilation" ]; then
#echo board,target and start of sketches to sizes_file json
echo "{ \"board\": \"$log_fqbn\",
\"target\": \"$target\",
@ -511,30 +536,34 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <pat
fi
local sketchnum=0
args+=" -ai $ide_path -au $user_path -i $chunk_index"
if [ $log_compilation ]; then
args+=" -l $log_compilation"
args+=("-ai" "$ide_path" "-au" "$user_path" "-i" "$chunk_index")
if [ -n "$log_compilation" ]; then
args+=("-l" "$log_compilation")
fi
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
sketchnum=$(($sketchnum + 1))
local sketchdir
local sketchdirname
sketchdir=$(dirname "$sketch")
sketchdirname=$(basename "$sketchdir")
sketchnum=$((sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
echo ""
echo "Building Sketch Index $sketchnum - $sketchdirname"
build_sketch $args -s $sketchdir $xtra_opts
build_sketch "${args[@]}" -s "$sketchdir" "${xtra_opts[@]}"
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
done
if [ $log_compilation ]; then
if [ -n "$log_compilation" ]; then
#remove last comma from json
if [ $i -eq $(($len - 1)) ]; then
if [ "$i" -eq $((len - 1)) ]; then
sed -i '$ s/.$//' "$sizes_file"
fi
#echo end of sketches sizes_file json
@ -557,20 +586,20 @@ Available commands:
cmd=$1
shift
if [ -z $cmd ]; then
if [ -z "$cmd" ]; then
echo "ERROR: No command supplied"
echo "$USAGE"
exit 2
fi
case "$cmd" in
"count") count_sketches $*
"count") count_sketches "$@"
;;
"build") build_sketch $*
"build") build_sketch "$@"
;;
"chunk_build") build_sketches $*
"chunk_build") build_sketches "$@"
;;
"check_requirements") check_requirements $*
"check_requirements") check_requirements "$@"
;;
*)
echo "ERROR: Unrecognized command"

View file

@ -10,7 +10,7 @@ USAGE:
Remove build and test generated files
"
function clean(){
function clean {
rm -rf tests/.pytest_cache
find tests/ -type d -name 'build*' -exec rm -rf "{}" \+
find tests/ -type d -name '__pycache__' -exec rm -rf "{}" \+
@ -23,7 +23,7 @@ BUILD_CMD=""
chunk_build=0
while [ ! -z "$1" ]; do
while [ -n "$1" ]; do
case $1 in
-c )
chunk_build=1
@ -51,15 +51,15 @@ while [ ! -z "$1" ]; do
shift
done
source ${SCRIPTS_DIR}/install-arduino-cli.sh
source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
source "${SCRIPTS_DIR}/install-arduino-cli.sh"
source "${SCRIPTS_DIR}/install-arduino-core-esp32.sh"
args="-ai $ARDUINO_IDE_PATH -au $ARDUINO_USR_PATH"
args=("-ai" "$ARDUINO_IDE_PATH" "-au" "$ARDUINO_USR_PATH")
if [[ $test_type == "all" ]] || [[ -z $test_type ]]; then
if [ -n "$sketch" ]; then
tmp_sketch_path=$(find tests -name $sketch.ino)
test_type=$(basename $(dirname $(dirname "$tmp_sketch_path")))
tmp_sketch_path=$(find tests -name "$sketch".ino)
test_type=$(basename "$(dirname "$(dirname "$tmp_sketch_path")")")
echo "Sketch $sketch test type: $test_type"
test_folder="$PWD/tests/$test_type"
else
@ -71,11 +71,10 @@ fi
if [ $chunk_build -eq 1 ]; then
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
args+=" -p $test_folder -i 0 -m 1"
args+=("-p" "$test_folder" "-i" "0" "-m" "1")
else
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh build"
args+=" -s $test_folder/$sketch"
args+=("-s" "$test_folder/$sketch")
fi
${BUILD_CMD} ${args} $*
${BUILD_CMD} "${args[@]}" "$@"

View file

@ -12,15 +12,17 @@ if [[ $IS_PR != 'true' ]] || [[ $PERFORMANCE_ENABLED == 'true' ]]; then
#qemu_types+=",'performance'"
fi
targets="'esp32','esp32s2','esp32s3','esp32c3','esp32c6','esp32h2'"
targets="'esp32','esp32s2','esp32s3','esp32c3','esp32c6','esp32h2','esp32p4'"
mkdir -p info
echo "[$wokwi_types]" > info/wokwi_types.txt
echo "[$targets]" > info/targets.txt
echo "build-types=[$build_types]" >> $GITHUB_OUTPUT
echo "hw-types=[$hw_types]" >> $GITHUB_OUTPUT
echo "wokwi-types=[$wokwi_types]" >> $GITHUB_OUTPUT
echo "qemu-types=[$qemu_types]" >> $GITHUB_OUTPUT
echo "targets=[$targets]" >> $GITHUB_OUTPUT
{
echo "build-types=[$build_types]"
echo "hw-types=[$hw_types]"
echo "wokwi-types=[$wokwi_types]"
echo "qemu-types=[$qemu_types]"
echo "targets=[$targets]"
} >> "$GITHUB_OUTPUT"

View file

@ -1,125 +1,129 @@
#!/bin/bash
function run_test() {
function run_test {
local target=$1
local sketch=$2
local options=$3
local erase_flash=$4
local sketchdir=$(dirname $sketch)
local sketchname=$(basename $sketchdir)
local sketchdir
local sketchname
local result=0
local error=0
local sdkconfig_path
local extra_args
if [ $options -eq 0 ] && [ -f $sketchdir/ci.json ]; then
len=`jq -r --arg target $target '.fqbn[$target] | length' $sketchdir/ci.json`
if [ $len -eq 0 ]; then
sketchdir=$(dirname "$sketch")
sketchname=$(basename "$sketchdir")
if [ "$options" -eq 0 ] && [ -f "$sketchdir"/ci.json ]; then
len=$(jq -r --arg target "$target" '.fqbn[$target] | length' "$sketchdir"/ci.json)
if [ "$len" -eq 0 ]; then
len=1
fi
else
len=1
fi
if [ $len -eq 1 ]; then
if [ "$len" -eq 1 ]; then
sdkconfig_path="$HOME/.arduino/tests/$sketchname/build.tmp/sdkconfig"
else
sdkconfig_path="$HOME/.arduino/tests/$sketchname/build0.tmp/sdkconfig"
fi
if [ -f $sketchdir/ci.json ]; then
if [ -f "$sketchdir"/ci.json ]; then
# If the target or platform is listed as false, skip the sketch. Otherwise, include it.
is_target=$(jq -r --arg target $target '.targets[$target]' $sketchdir/ci.json)
selected_platform=$(jq -r --arg platform $platform '.platforms[$platform]' $sketchdir/ci.json)
is_target=$(jq -r --arg target "$target" '.targets[$target]' "$sketchdir"/ci.json)
selected_platform=$(jq -r --arg platform "$platform" '.platforms[$platform]' "$sketchdir"/ci.json)
if [[ $is_target == "false" ]] || [[ $selected_platform == "false" ]]; then
printf "\033[93mSkipping $sketchname test for $target, platform: $platform\033[0m\n"
printf "\033[93mSkipping %s test for %s, platform: %s\033[0m\n" "$sketchname" "$target" "$platform"
printf "\n\n\n"
return 0
fi
fi
if [ ! -f $sdkconfig_path ]; then
printf "\033[93mSketch $sketchname not built\nMight be due to missing target requirements or build failure\033[0m\n"
if [ ! -f "$sdkconfig_path" ]; then
printf "\033[93mSketch %s not built\nMight be due to missing target requirements or build failure\033[0m\n" "$sketchname"
printf "\n\n\n"
return 0
fi
local right_target=$(grep -E "^CONFIG_IDF_TARGET=\"$target\"$" "$sdkconfig_path")
local right_target
right_target=$(grep -E "^CONFIG_IDF_TARGET=\"$target\"$" "$sdkconfig_path")
if [ -z "$right_target" ]; then
printf "\033[91mError: Sketch $sketchname compiled for different target\n\033[0m\n"
printf "\033[91mError: Sketch %s compiled for different target\n\033[0m\n" "$sketchname"
printf "\n\n\n"
return 1
fi
if [ $len -eq 1 ]; then
if [ "$len" -eq 1 ]; then
# build_dir="$sketchdir/build"
build_dir="$HOME/.arduino/tests/$sketchname/build.tmp"
report_file="$sketchdir/$target/$sketchname.xml"
fi
for i in `seq 0 $(($len - 1))`
do
for i in $(seq 0 $((len - 1))); do
fqbn="Default"
if [ $len -ne 1 ]; then
fqbn=`jq -r --arg target $target --argjson i $i '.fqbn[$target] | sort | .[$i]' $sketchdir/ci.json`
elif [ -f $sketchdir/ci.json ]; then
has_fqbn=`jq -r --arg target $target '.fqbn[$target]' $sketchdir/ci.json`
if [ "$len" -ne 1 ]; then
fqbn=$(jq -r --arg target "$target" --argjson i "$i" '.fqbn[$target] | sort | .[$i]' "$sketchdir"/ci.json)
elif [ -f "$sketchdir"/ci.json ]; then
has_fqbn=$(jq -r --arg target "$target" '.fqbn[$target]' "$sketchdir"/ci.json)
if [ "$has_fqbn" != "null" ]; then
fqbn=`jq -r --arg target $target '.fqbn[$target] | .[0]' $sketchdir/ci.json`
fqbn=$(jq -r --arg target "$target" '.fqbn[$target] | .[0]' "$sketchdir"/ci.json)
fi
fi
printf "\033[95mRunning test: $sketchname -- Config: $fqbn\033[0m\n"
if [ $erase_flash -eq 1 ]; then
esptool.py -c $target erase_flash
printf "\033[95mRunning test: %s -- Config: %s\033[0m\n" "$sketchname" "$fqbn"
if [ "$erase_flash" -eq 1 ]; then
esptool.py -c "$target" erase_flash
fi
if [ $len -ne 1 ]; then
if [ "$len" -ne 1 ]; then
# build_dir="$sketchdir/build$i"
build_dir="$HOME/.arduino/tests/$sketchname/build$i.tmp"
report_file="$sketchdir/$target/$sketchname$i.xml"
fi
if [ $platform == "wokwi" ]; then
extra_args="--target $target --embedded-services arduino,wokwi --wokwi-timeout=$wokwi_timeout"
extra_args=("--target" "$target" "--embedded-services" "arduino,wokwi" "--wokwi-timeout=$wokwi_timeout")
if [[ -f "$sketchdir/scenario.yaml" ]]; then
extra_args+=" --wokwi-scenario $sketchdir/scenario.yaml"
extra_args+=("--wokwi-scenario" "$sketchdir/scenario.yaml")
fi
if [[ -f "$sketchdir/diagram.$target.json" ]]; then
extra_args+=" --wokwi-diagram $sketchdir/diagram.$target.json"
extra_args+=("--wokwi-diagram" "$sketchdir/diagram.$target.json")
fi
elif [ $platform == "qemu" ]; then
PATH=$HOME/qemu/bin:$PATH
extra_args="--embedded-services qemu --qemu-image-path $build_dir/$sketchname.ino.merged.bin"
extra_args=("--embedded-services" "qemu" "--qemu-image-path" "$build_dir/$sketchname.ino.merged.bin")
if [ $target == "esp32" ] || [ $target == "esp32s3" ]; then
extra_args+=" --qemu-prog-path qemu-system-xtensa --qemu-cli-args=\"-machine $target -m 4M -nographic\""
elif [ $target == "esp32c3" ]; then
extra_args+=" --qemu-prog-path qemu-system-riscv32 --qemu-cli-args=\"-machine $target -icount 3 -nographic\""
if [ "$target" == "esp32" ] || [ "$target" == "esp32s3" ]; then
extra_args+=("--qemu-prog-path" "qemu-system-xtensa" "--qemu-cli-args=\"-machine $target -m 4M -nographic\"")
elif [ "$target" == "esp32c3" ]; then
extra_args+=("--qemu-prog-path" "qemu-system-riscv32" "--qemu-cli-args=\"-machine $target -icount 3 -nographic\"")
else
printf "\033[91mUnsupported QEMU target: $target\033[0m\n"
printf "\033[91mUnsupported QEMU target: %s\033[0m\n" "$target"
exit 1
fi
else
extra_args="--embedded-services esp,arduino"
extra_args=("--embedded-services" "esp,arduino")
fi
rm $sketchdir/diagram.json 2>/dev/null || true
rm "$sketchdir"/diagram.json 2>/dev/null || true
result=0
printf "\033[95mpytest $sketchdir/test_$sketchname.py --build-dir $build_dir --junit-xml=$report_file $extra_args\033[0m\n"
bash -c "set +e; pytest $sketchdir/test_$sketchname.py --build-dir $build_dir --junit-xml=$report_file $extra_args; exit \$?" || result=$?
printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "${extra_args[*]@Q}"
bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" ${extra_args[*]@Q}; exit \$?" || result=$?
printf "\n"
if [ $result -ne 0 ]; then
result=0
printf "\033[95mRetrying test: $sketchname -- Config: $i\033[0m\n"
printf "\033[95mpytest $sketchdir/test_$sketchname.py --build-dir $build_dir --junit-xml=$report_file $extra_args\033[0m\n"
bash -c "set +e; pytest $sketchdir/test_$sketchname.py --build-dir $build_dir --junit-xml=$report_file $extra_args; exit \$?" || result=$?
printf "\033[95mRetrying test: %s -- Config: %s\033[0m\n" "$sketchname" "$i"
printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "${extra_args[*]@Q}"
bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" ${extra_args[*]@Q}; exit \$?" || result=$?
printf "\n"
if [ $result -ne 0 ]; then
printf "\033[91mFailed test: $sketchname -- Config: $i\033[0m\n\n"
printf "\033[91mFailed test: %s -- Config: %s\033[0m\n\n" "$sketchname" "$i"
error=$result
fi
fi
@ -136,13 +140,13 @@ chunk_run=0
options=0
erase=0
while [ ! -z "$1" ]; do
while [ -n "$1" ]; do
case $1 in
-c )
chunk_run=1
;;
-Q )
if [ ! -d $QEMU_PATH ]; then
if [ ! -d "$QEMU_PATH" ]; then
echo "QEMU path $QEMU_PATH does not exist"
exit 1
fi
@ -195,14 +199,14 @@ while [ ! -z "$1" ]; do
done
if [ ! $platform == "qemu" ]; then
source ${SCRIPTS_DIR}/install-arduino-ide.sh
source "${SCRIPTS_DIR}/install-arduino-ide.sh"
fi
# If sketch is provided and test type is not, test type is inferred from the sketch path
if [[ $test_type == "all" ]] || [[ -z $test_type ]]; then
if [ -n "$sketch" ]; then
tmp_sketch_path=$(find tests -name $sketch.ino)
test_type=$(basename $(dirname $(dirname "$tmp_sketch_path")))
tmp_sketch_path=$(find tests -name "$sketch".ino)
test_type=$(basename "$(dirname "$(dirname "$tmp_sketch_path")")")
echo "Sketch $sketch test type: $test_type"
test_folder="$PWD/tests/$test_type"
else
@ -213,11 +217,11 @@ else
fi
if [ $chunk_run -eq 0 ]; then
if [ -z $sketch ]; then
if [ -z "$sketch" ]; then
echo "ERROR: Sketch name is required for single test run"
exit 1
fi
run_test $target $test_folder/$sketch/$sketch.ino $options $erase
run_test "$target" "$test_folder"/"$sketch"/"$sketch".ino $options $erase
exit $?
else
if [ "$chunk_max" -le 0 ]; then
@ -238,10 +242,10 @@ else
sketches=$(cat sketches.txt)
rm -rf sketches.txt
chunk_size=$(( $sketchcount / $chunk_max ))
all_chunks=$(( $chunk_max * $chunk_size ))
chunk_size=$(( sketchcount / chunk_max ))
all_chunks=$(( chunk_max * chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
chunk_size=$(( chunk_size + 1 ))
fi
start_index=0
@ -250,33 +254,32 @@ else
start_index=$chunk_index
end_index=$sketchcount
else
start_index=$(( $chunk_index * $chunk_size ))
start_index=$(( chunk_index * chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
exit 0
fi
end_index=$(( $(( $chunk_index + 1 )) * $chunk_size ))
end_index=$(( $(( chunk_index + 1 )) * chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
fi
start_num=$(( $start_index + 1 ))
sketchnum=0
error=0
for sketch in $sketches; do
sketchnum=$(($sketchnum + 1))
sketchnum=$((sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
printf "\033[95mSketch Index $(($sketchnum - 1))\033[0m\n"
printf "\033[95mSketch Index %s\033[0m\n" "$((sketchnum - 1))"
exit_code=0
run_test $target $sketch $options $erase || exit_code=$?
run_test "$target" "$sketch" $options $erase || exit_code=$?
if [ $exit_code -ne 0 ]; then
error=$exit_code
fi

View file

@ -1,4 +1,5 @@
#!/bin/bash
# shellcheck disable=SC2002
# For reference: add tools for all boards by replacing one line in each board
# "[board].upload.tool=esptool_py" to "[board].upload.tool=esptool_py\n[board].upload.tool.default=esptool_py\n[board].upload.tool.network=esp_ota"
@ -36,7 +37,8 @@ sed "s/#define ESP_ARDUINO_VERSION_MAJOR.*/#define ESP_ARDUINO_VERSION_MAJOR $ES
sed "s/#define ESP_ARDUINO_VERSION_MINOR.*/#define ESP_ARDUINO_VERSION_MINOR $ESP_ARDUINO_VERSION_MINOR/g" | \
sed "s/#define ESP_ARDUINO_VERSION_PATCH.*/#define ESP_ARDUINO_VERSION_PATCH $ESP_ARDUINO_VERSION_PATCH/g" > __esp_arduino_version.h && mv __esp_arduino_version.h cores/esp32/esp_arduino_version.h
for lib in `ls libraries`; do
libraries=$(find libraries -maxdepth 1 -mindepth 1 -type d -exec basename {} \;)
for lib in $libraries; do
if [ -f "libraries/$lib/library.properties" ]; then
echo "Updating Library $lib..."
cat "libraries/$lib/library.properties" | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > "libraries/$lib/__library.properties" && mv "libraries/$lib/__library.properties" "libraries/$lib/library.properties"

View file

@ -1,11 +1,12 @@
#!/bin/bash
CHANGED_FILES=$1
echo "Pushing '$CHANGED_FILES' as github-actions[bot]"
git config --global github.user "github-actions[bot]"
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
for tool in $CHANGED_FILES; do
git add tools/$tool.exe
git add tools/"$tool".exe
done
git commit -m "change(tools): Push generated binaries to PR"
git push

View file

@ -1,6 +1,6 @@
name: Boards Test - Remote trigger
# The workflow will run on remote dispath with event-type set to "test-boards"
# The workflow will run on remote dispatch with event-type set to "test-boards"
on:
repository_dispatch:
types: [test-boards]
@ -20,8 +20,7 @@ jobs:
ref: ${{ github.event.client_payload.branch }}
- name: Get boards fqbns
run:
bash .github/scripts/find_all_boards.sh
run: bash .github/scripts/find_all_boards.sh
setup-chunks:
needs: find-boards
@ -43,8 +42,7 @@ jobs:
- id: set-test-chunks
name: Set Chunks
run:
echo "test-chunks<<EOF" >> $GITHUB_OUTPUT
run: echo "test-chunks<<EOF" >> $GITHUB_OUTPUT
echo "$( jq -nc '${{ needs.find-boards.outputs.fqbns }} | [_nwise( ${{ needs.find-boards.outputs.board-count }}/15 | ceil)]')" >> $GITHUB_OUTPUT
@ -71,8 +69,7 @@ jobs:
ref: ${{ github.event.client_payload.branch }}
- name: Echo FQBNS to file
run:
echo "$FQBN" > fqbns.json
run: echo "$FQBN" > fqbns.json
env:
FQBN: ${{ toJSON(matrix.chunk) }}
@ -88,5 +85,4 @@ jobs:
enable-warnings-report: false
cli-compile-flags: |
- --warnings="all"
sketch-paths:
"- ./libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino"
sketch-paths: "- ./libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino"

View file

@ -4,9 +4,9 @@ name: Boards Test
on:
pull_request:
paths:
- 'boards.txt'
- 'libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino'
- '.github/workflows/boards.yml'
- "boards.txt"
- "libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino"
- ".github/workflows/boards.yml"
env:
# It's convenient to set variables for values used multiple times in the workflow
@ -28,8 +28,7 @@ jobs:
uses: dcarbone/install-jq-action@v1.0.1
- name: Get board name
run:
bash .github/scripts/find_new_boards.sh ${{ github.repository }} ${{github.base_ref}}
run: bash .github/scripts/find_new_boards.sh ${{ github.repository }} ${{github.base_ref}}
test-boards:
needs: find-boards
@ -85,6 +84,5 @@ jobs:
cli-compile-flags: |
- --warnings="all"
exit-on-fail: true
sketch-paths:
"- ./libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino"
sketch-paths: "- ./libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino"
verbose: true

View file

@ -3,11 +3,11 @@ name: Build Python Tools
on:
pull_request:
paths:
- '.github/workflows/build_py_tools.yml'
- 'tools/get.py'
- 'tools/espota.py'
- 'tools/gen_esp32part.py'
- 'tools/gen_insights_package.py'
- ".github/workflows/build_py_tools.yml"
- "tools/get.py"
- "tools/espota.py"
- "tools/gen_esp32part.py"
- "tools/gen_insights_package.py"
jobs:
find-changed-tools:
@ -33,8 +33,8 @@ jobs:
uses: tj-actions/changed-files@v41
id: verify-changed-files
with:
fetch_depth: '2'
since_last_remote_commit: 'true'
fetch_depth: "2"
since_last_remote_commit: "true"
files: |
tools/get.py
tools/espota.py
@ -60,17 +60,17 @@ jobs:
- os: windows-latest
TARGET: win64
EXTEN: .exe
SEPARATOR: ';'
SEPARATOR: ";"
- os: macos-latest
TARGET: macos
SEPARATOR: ':'
SEPARATOR: ":"
- os: ubuntu-20.04
TARGET: linux-amd64
SEPARATOR: ':'
SEPARATOR: ":"
- os: ARM
CONTAINER: python:3.8-bullseye
TARGET: arm
SEPARATOR: ':'
SEPARATOR: ":"
container: ${{ matrix.CONTAINER }} # use python container on ARM
env:
DISTPATH: pytools-${{ matrix.TARGET }}

View file

@ -20,5 +20,5 @@ jobs:
uses: espressif/shared-github-dangerjs@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
rule-max-commits: 'false'
commit-messages-min-summary-length: '10'
rule-max-commits: "false"
commit-messages-min-summary-length: "10"

View file

@ -6,15 +6,14 @@ on:
- master
- release/v2.x
paths:
- 'docs/**'
- '.github/workflows/docs_build.yml'
- "docs/**"
- ".github/workflows/docs_build.yml"
pull_request:
paths:
- 'docs/**'
- '.github/workflows/docs_build.yml'
- "docs/**"
- ".github/workflows/docs_build.yml"
jobs:
build-docs:
name: Build ESP-Docs
runs-on: ubuntu-22.04
@ -28,8 +27,8 @@ jobs:
- uses: actions/setup-python@v5
with:
cache-dependency-path: docs/requirements.txt
cache: 'pip'
python-version: '3.10'
cache: "pip"
python-version: "3.10"
- name: Build
run: |
sudo apt update

View file

@ -10,8 +10,8 @@ on:
- release/v2.x
- master
paths:
- 'docs/**'
- '.github/workflows/docs_deploy.yml'
- "docs/**"
- ".github/workflows/docs_deploy.yml"
jobs:
deploy-prod-docs:
@ -32,8 +32,8 @@ jobs:
- uses: actions/setup-python@v5
with:
cache-dependency-path: docs/requirements.txt
cache: 'pip'
python-version: '3.10'
cache: "pip"
python-version: "3.10"
- name: Deploy Documentation
env:
# Deploy to production server

View file

@ -6,12 +6,11 @@ on:
- master
- pages
paths:
- 'README.md'
- '.github/scripts/on-pages.sh'
- '.github/workflows/gh-pages.yml'
- "README.md"
- ".github/scripts/on-pages.sh"
- ".github/workflows/gh-pages.yml"
jobs:
build-pages:
name: Build GitHub Pages
runs-on: ubuntu-latest

View file

@ -7,7 +7,7 @@ on:
# Schedule weekly builds on every Sunday at 4 am
schedule:
- cron: '0 4 * * SUN'
- cron: "0 4 * * SUN"
concurrency:
group: libs-${{ github.event.pull_request.number || github.ref }}
@ -27,7 +27,6 @@ jobs:
contains(github.event.pull_request.labels.*.name, 'lib_test') ||
(github.event_name == 'schedule' && github.repository == 'espressif/arduino-esp32')
runs-on: ubuntu-latest
env:
REPOSITORY: |
- source-path: '.'
@ -42,6 +41,7 @@ jobs:
- esp32s3
- esp32c6
- esp32h2
- esp32p4
include:
- target: esp32
@ -56,7 +56,8 @@ jobs:
fqbn: espressif:esp32:esp32c6
- target: esp32h2
fqbn: espressif:esp32:esp32h2
- target: esp32p4
fqbn: espressif:esp32:esp32p4
steps:
# This step makes the contents of the repository available to the workflow
@ -94,11 +95,10 @@ jobs:
uses: actions/checkout@v4
with:
token: ${{ env.GITHUB_TOKEN }}
fetch-depth: '0'
fetch-depth: "0"
- name: Switch branch
run:
git checkout remotes/origin/gh-pages
run: git checkout remotes/origin/gh-pages
# This step is needed to get the size data produced by the compile jobs
- name: Download sketches reports artifact
@ -115,8 +115,7 @@ jobs:
destination-file: ${{ env.RESULT_LIBRARY_TEST_FILE }}
- name: Append file with action URL
run:
echo "/ [GitHub Action Link](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})" >> ${{ env.RESULT_LIBRARY_TEST_FILE }}
run: echo "/ [GitHub Action Link](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})" >> ${{ env.RESULT_LIBRARY_TEST_FILE }}
- name: Push to github repo
run: |

View file

@ -37,7 +37,7 @@ jobs:
uses: actions/setup-python@v5
with:
cache-dependency-path: tools/pre-commit/requirements.txt
cache: 'pip'
cache: "pip"
python-version: "3.x"
- name: Get Python version hash

View file

@ -11,7 +11,7 @@ env:
jobs:
sizes-test-results:
name: Sizes Comparsion Results
name: Sizes Comparison Results
runs-on: ubuntu-latest
steps:
- name: Checkout code
@ -41,8 +41,7 @@ jobs:
destination-file: ${{ env.RESULT_SIZES_TEST_FILE }}
- name: Append file with action URL
run:
echo "/ [GitHub Action Link](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})" >> ${{ env.RESULT_SIZES_TEST_FILE }}
run: echo "/ [GitHub Action Link](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})" >> ${{ env.RESULT_SIZES_TEST_FILE }}
- name: Push to github repo
run: |

View file

@ -14,7 +14,7 @@ env:
jobs:
sizes-test-results:
name: Sizes Comparsion Results
name: Sizes Comparison Results
runs-on: ubuntu-latest
if: |
github.event.workflow_run.event == 'pull_request' &&

View file

@ -2,32 +2,48 @@ name: Compilation Tests
on:
workflow_dispatch:
inputs:
log_level:
description: "Log level"
default: "none"
type: "choice"
required: true
options:
- "none"
- "error"
- "warn"
- "info"
- "debug"
- "verbose"
schedule:
# Every Sunday at 2:00 UTC run a build with verbose log level
- cron: "0 2 * * SUN"
push:
branches:
- master
- release/*
pull_request:
paths:
- 'cores/**'
- 'libraries/**'
- '!libraries/**.md'
- '!libraries/**.txt'
- '!libraries/**.properties'
- '!libraries/**.py'
- 'package/**'
- 'tools/**.py'
- 'platform.txt'
- 'programmers.txt'
- 'idf_component.yml'
- 'Kconfig.projbuild'
- 'package.json'
- 'CMakeLists.txt'
- '.github/workflows/push.yml'
- '.github/scripts/**'
- '!.github/scripts/find_*'
- '!.github/scripts/on-release.sh'
- '!.github/scripts/tests_*'
- '!.github/scripts/upload_*'
- "cores/**"
- "libraries/**"
- "!libraries/**.md"
- "!libraries/**.txt"
- "!libraries/**.properties"
- "!libraries/**.py"
- "package/**"
- "tools/**.py"
- "platform.txt"
- "programmers.txt"
- "idf_component.yml"
- "Kconfig.projbuild"
- "package.json"
- "CMakeLists.txt"
- ".github/workflows/push.yml"
- ".github/scripts/**"
- "!.github/scripts/find_*"
- "!.github/scripts/on-release.sh"
- "!.github/scripts/tests_*"
- "!.github/scripts/upload_*"
- "variants/esp32/**/*"
- "variants/esp32s2/**/*"
- "variants/esp32s3/**/*"
@ -61,7 +77,6 @@ jobs:
build_libraries: ${{ steps.set-chunks.outputs.build_libraries }}
build_static_sketches: ${{ steps.set-chunks.outputs.build_static_sketches }}
build_idf: ${{ steps.set-chunks.outputs.build_idf }}
build_platformio: ${{ steps.set-chunks.outputs.build_platformio }}
chunk_count: ${{ steps.set-chunks.outputs.chunk_count }}
chunks: ${{ steps.set-chunks.outputs.chunks }}
steps:
@ -77,11 +92,9 @@ jobs:
files_yaml: |
core:
- '.github/**'
- '!.github/scripts/install-platformio-esp32.sh'
- 'cores/**'
- 'package/**'
- 'tools/**'
- '!tools/platformio-build.py'
- 'platform.txt'
- 'programmers.txt'
- "variants/esp32/**/*"
@ -110,10 +123,6 @@ jobs:
- 'Kconfig.projbuild'
- 'CMakeLists.txt'
- "variants/esp32c2/**/*"
platformio:
- 'package.json'
- '.github/scripts/install-platformio-esp32.sh'
- 'tools/platformio-build.py'
- name: Set chunks
id: set-chunks
@ -121,7 +130,6 @@ jobs:
LIB_FILES: ${{ steps.changed-files.outputs.libraries_all_changed_files }}
IS_PR: ${{ github.event_name == 'pull_request' }}
MAX_CHUNKS: ${{ env.MAX_CHUNKS }}
BUILD_PLATFORMIO: ${{ steps.changed-files.outputs.platformio_any_changed == 'true' }}
BUILD_IDF: ${{ steps.changed-files.outputs.idf_any_changed == 'true' }}
BUILD_LIBRARIES: ${{ steps.changed-files.outputs.libraries_any_changed == 'true' }}
BUILD_STATIC_SKETCHES: ${{ steps.changed-files.outputs.static_sketeches_any_changed == 'true' }}
@ -156,7 +164,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
python-version: "3.x"
- name: Get libs cache
uses: actions/cache@v4
@ -171,9 +179,19 @@ jobs:
./tools/riscv32-*
./tools/xtensa-*
- name: Set Log Level
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "LOG_LEVEL=${{ github.event.inputs.log_level }}" >> $GITHUB_ENV
elif [ "${{ github.event_name }}" == "schedule" ]; then
echo "LOG_LEVEL=verbose" >> $GITHUB_ENV
else
echo "LOG_LEVEL=none" >> $GITHUB_ENV
fi
- name: Build all sketches
if: ${{ needs.gen-chunks.outputs.build_all == 'true' }}
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} ${{ env.MAX_CHUNKS }} 1
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} ${{ env.MAX_CHUNKS }} 1 ${{ env.LOG_LEVEL }}
- name: Download sketches found
if: ${{ needs.gen-chunks.outputs.build_all == 'false' && needs.gen-chunks.outputs.build_libraries == 'true' }}
@ -183,7 +201,7 @@ jobs:
- name: Build selected sketches
if: ${{ needs.gen-chunks.outputs.build_all == 'false' && needs.gen-chunks.outputs.build_libraries == 'true' }}
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} ${{ needs.gen-chunks.outputs.chunk_count }} 1 sketches_found.txt
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} ${{ needs.gen-chunks.outputs.chunk_count }} 1 ${{ env.LOG_LEVEL }} sketches_found.txt
#Upload cli compile json as artifact
- name: Upload cli compile json
@ -208,32 +226,10 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
python-version: "3.x"
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh
# PlatformIO on Windows, Ubuntu and Mac
build-platformio:
name: PlatformIO on ${{ matrix.os }}
needs: gen-chunks
if: |
needs.gen-chunks.outputs.build_all == 'true' ||
needs.gen-chunks.outputs.build_static_sketches == 'true' ||
needs.gen-chunks.outputs.build_platformio == 'true'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO
build-esp-idf-component:
name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
needs: gen-chunks
@ -249,8 +245,18 @@ jobs:
# See https://hub.docker.com/r/espressif/idf/tags and
# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html
# for details.
idf_ver: ["release-v5.1"]
idf_target: ["esp32", "esp32s2", "esp32s3", "esp32c2", "esp32c3", "esp32c6", "esp32h2"]
idf_ver: ["release-v5.3"]
idf_target:
[
"esp32",
"esp32s2",
"esp32s3",
"esp32c2",
"esp32c3",
"esp32c6",
"esp32h2",
"esp32p4"
]
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Check out arduino-esp32 as a component
@ -280,11 +286,10 @@ jobs:
uses: actions/checkout@v4
with:
token: ${{secrets.GITHUB_TOKEN}}
fetch-depth: '0'
fetch-depth: "0"
- name: Switch branch
run:
git checkout remotes/origin/gh-pages
run: git checkout remotes/origin/gh-pages
- name: Download sketches reports artifact
uses: actions/download-artifact@v4

View file

@ -15,7 +15,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.x'
python-version: "3.x"
- run: pip install packaging
- run: pip install pyserial
- name: Build Release

View file

@ -16,22 +16,22 @@ on:
pull_request:
types: [opened, reopened, closed, synchronize, labeled, unlabeled]
paths:
- '.github/workflows/tests*'
- '.github/scripts/*.sh'
- '!.github/scripts/check-cmakelists.sh'
- '!.github/scripts/find_*'
- '!.github/scripts/on-*.sh'
- '!.github/scripts/set_push_chunks.sh'
- '!.github/scripts/update-version.sh'
- '!.github/scripts/upload_py_tools.sh'
- 'tests/**'
- 'cores/**'
- 'libraries/*/src/**.cpp'
- 'libraries/*/src/**.h'
- 'libraries/*/src/**.c'
- 'package/**'
- ".github/workflows/tests*"
- ".github/scripts/*.sh"
- "!.github/scripts/check-cmakelists.sh"
- "!.github/scripts/find_*"
- "!.github/scripts/on-*.sh"
- "!.github/scripts/set_push_chunks.sh"
- "!.github/scripts/update-version.sh"
- "!.github/scripts/upload_py_tools.sh"
- "tests/**"
- "cores/**"
- "libraries/*/src/**.cpp"
- "libraries/*/src/**.h"
- "libraries/*/src/**.c"
- "package/**"
schedule:
- cron: '0 2 * * *'
- cron: "0 2 * * *"
concurrency:
group: tests-${{ github.event.pull_request.number || github.ref }}
@ -115,7 +115,7 @@ jobs:
fail-fast: false
matrix:
type: ${{ fromJson(needs.gen-matrix.outputs.qemu-types) }}
chip: ['esp32', 'esp32c3']
chip: ["esp32", "esp32c3"]
with:
type: ${{ matrix.type }}
chip: ${{ matrix.chip }}

View file

@ -5,11 +5,11 @@ on:
inputs:
type:
type: string
description: 'Type of tests to build'
description: "Type of tests to build"
required: true
chip:
type: string
description: 'Chip to build tests for'
description: "Chip to build tests for"
required: true
jobs:

View file

@ -5,11 +5,11 @@ on:
inputs:
type:
type: string
description: 'Type of tests to run'
description: "Type of tests to run"
required: true
chip:
type: string
description: 'Chip to run tests for'
description: "Chip to run tests for"
required: true
env:

View file

@ -64,8 +64,8 @@ jobs:
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
with:
cache-dependency-path: tests/requirements.txt
cache: 'pip'
python-version: '3.x'
cache: "pip"
python-version: "3.x"
- name: Install Python dependencies
if: ${{ steps.check-tests.outputs.enabled == 'true' }}

View file

@ -139,22 +139,23 @@ jobs:
core.info(`${name} is ${state}`);
- name: Create output folder
if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }}
if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled
run: |
rm -rf artifacts
mkdir -p runtime-tests-results
- name: Generate badge
if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }}
if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled
uses: jaywcjlove/generated-badges@v1.0.13
with:
label: Runtime Tests
status: ${{ job.status }}
status: ${{ job.status == 'success' && 'passing' || 'failing' }}
output: runtime-tests-results/badge.svg
color: ${{ job.status == 'success' && 'green' || 'red' }}
style: flat
- name: Push badge
if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }}
if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

View file

@ -247,8 +247,8 @@ jobs:
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
with:
cache-dependency-path: tests/requirements.txt
cache: 'pip'
python-version: '3.x'
cache: "pip"
python-version: "3.x"
- name: Install dependencies
if: ${{ steps.check-tests.outputs.enabled == 'true' }}

View file

@ -1,6 +1,11 @@
name: Push components to https://components.espressif.com
on:
workflow_dispatch:
inputs:
tag:
description: 'Tag to push to the component registry'
required: true
workflow_run:
workflows: ["ESP32 Arduino Release"]
types:
@ -15,9 +20,9 @@ jobs:
steps:
- name: Get the release tag
env:
head_branch: ${{ github.event.workflow_run.head_branch }}
head_branch: ${{ inputs.tag || github.event.workflow_run.head_branch }}
run: |
if [ "${{ github.event.workflow_run.conclusion }}" != "success" ]; then
if [ "${{ github.event.workflow_run.conclusion }}" != "success" ] && [ "${{ github.event_name }}" == "workflow_run" ]; then
echo "Release workflow failed. Exiting..."
exit 1
fi
@ -39,6 +44,7 @@ jobs:
- uses: actions/checkout@v4
with:
ref: ${{ env.RELEASE_TAG }}
submodules: "recursive"
- name: Upload components to the component registry

View file

@ -12,8 +12,9 @@ default_language_version:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v4.5.0"
rev: "v5.0.0"
hooks:
# Generic checks
- id: check-case-conflict
- id: check-symlinks
- id: debug-statements
@ -25,6 +26,8 @@ repos:
args: [--fix=lf]
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
# JSON formatting
- id: pretty-format-json
stages: [manual]
args: [--autofix]
@ -35,40 +38,67 @@ repos:
package\.json$|
^package\/.*$
)
- repo: https://github.com/codespell-project/codespell
rev: "v2.3.0"
hooks:
# Spell checking
- id: codespell
exclude: ^.*\.(svd|SVD)$
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: "v18.1.3"
hooks:
# C/C++ formatting
- id: clang-format
types_or: [c, c++]
exclude: ^.*\/build_opt\.h$
- repo: https://github.com/psf/black-pre-commit-mirror
rev: "22.10.0"
rev: "24.10.0"
hooks:
# Python formatting
- id: black
types_or: [python]
args: [--line-length=120] #From the arduino code style. Add as argument rather than creating a new config file.
- repo: https://github.com/PyCQA/flake8
rev: "7.0.0"
rev: "7.1.1"
hooks:
# Python linting
- id: flake8
types_or: [python]
additional_dependencies:
- flake8-bugbear
- flake8-comprehensions
- flake8-simplify
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v3.1.0"
hooks:
# YAML formatting
- id: prettier
types_or: [yaml]
- repo: https://github.com/errata-ai/vale
rev: "v3.0.7"
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: "v0.10.0.1"
hooks:
# Bash linting
- id: shellcheck
types: [shell]
- repo: https://github.com/openstack/bashate
rev: "2.1.1"
hooks:
# Bash formatting
- id: bashate
types: [shell]
args: ["-i", "E006"] # Ignore E006: Line too long
- repo: https://github.com/errata-ai/vale
rev: "v3.9.1"
hooks:
# Sync vale styles and lint markdown and reStructuredText
- id: vale
name: vale-sync
language_version: "1.21.6"

11
.shellcheckrc Normal file
View file

@ -0,0 +1,11 @@
# Shellcheck configuration file for ESP32 Arduino core
# Optional checks. https://github.com/koalaman/shellcheck/wiki/optional
enable=add-default-case,deprecate-which,avoid-nullary-conditions
# Enable search for external sources
external-sources=true
# Search folder for sourced files.
# Set to the folder where the original script is located.
source-path=SCRIPTDIR

View file

@ -5,8 +5,8 @@
# export ARDUINO_SKIP_IDF_VERSION_CHECK=1
# idf.py build
set(min_supported_idf_version "5.1.0")
set(max_supported_idf_version "5.1.99")
set(min_supported_idf_version "5.3.0")
set(max_supported_idf_version "5.3.99")
set(idf_version "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}")
if ("${idf_version}" AND NOT "$ENV{ARDUINO_SKIP_IDF_VERSION_CHECK}")
@ -25,6 +25,7 @@ endif()
set(CORE_SRCS
cores/esp32/base64.cpp
cores/esp32/cbuf.cpp
cores/esp32/ColorFormat.c
cores/esp32/chip-debug-report.cpp
cores/esp32/esp32-hal-adc.c
cores/esp32/esp32-hal-bt.c
@ -45,9 +46,11 @@ set(CORE_SRCS
cores/esp32/esp32-hal-timer.c
cores/esp32/esp32-hal-tinyusb.c
cores/esp32/esp32-hal-touch.c
cores/esp32/esp32-hal-touch-ng.c
cores/esp32/esp32-hal-uart.c
cores/esp32/esp32-hal-rmt.c
cores/esp32/Esp.cpp
cores/esp32/freertos_stats.cpp
cores/esp32/FunctionalInterrupt.cpp
cores/esp32/HardwareSerial.cpp
cores/esp32/HEXBuilder.cpp
@ -93,6 +96,7 @@ set(ARDUINO_ALL_LIBRARIES
HTTPUpdate
Insights
LittleFS
Matter
NetBIOS
Network
OpenThread
@ -116,7 +120,6 @@ set(ARDUINO_ALL_LIBRARIES
)
set(ARDUINO_LIBRARY_ArduinoOTA_SRCS libraries/ArduinoOTA/src/ArduinoOTA.cpp)
set(ARDUINO_LIBRARY_ArduinoOTA_REQUIRES esp_https_ota)
set(ARDUINO_LIBRARY_AsyncUDP_SRCS libraries/AsyncUDP/src/AsyncUDP.cpp)
@ -157,7 +160,6 @@ set(ARDUINO_LIBRARY_HTTPUpdate_SRCS libraries/HTTPUpdate/src/HTTPUpdate.cpp)
set(ARDUINO_LIBRARY_Insights_SRCS libraries/Insights/src/Insights.cpp)
set(ARDUINO_LIBRARY_LittleFS_SRCS libraries/LittleFS/src/LittleFS.cpp)
set(ARDUINO_LIBRARY_LittleFS_REQUIRES joltwallet__littlefs)
set(ARDUINO_LIBRARY_NetBIOS_SRCS libraries/NetBIOS/src/NetBIOS.cpp)
@ -165,6 +167,22 @@ set(ARDUINO_LIBRARY_OpenThread_SRCS
libraries/OpenThread/src/OThreadCLI.cpp
libraries/OpenThread/src/OThreadCLI_Util.cpp)
set(ARDUINO_LIBRARY_Matter_SRCS
libraries/Matter/src/MatterEndpoints/MatterGenericSwitch.cpp
libraries/Matter/src/MatterEndpoints/MatterOnOffLight.cpp
libraries/Matter/src/MatterEndpoints/MatterDimmableLight.cpp
libraries/Matter/src/MatterEndpoints/MatterColorTemperatureLight.cpp
libraries/Matter/src/MatterEndpoints/MatterColorLight.cpp
libraries/Matter/src/MatterEndpoints/MatterEnhancedColorLight.cpp
libraries/Matter/src/MatterEndpoints/MatterFan.cpp
libraries/Matter/src/MatterEndpoints/MatterTemperatureSensor.cpp
libraries/Matter/src/MatterEndpoints/MatterHumiditySensor.cpp
libraries/Matter/src/MatterEndpoints/MatterContactSensor.cpp
libraries/Matter/src/MatterEndpoints/MatterPressureSensor.cpp
libraries/Matter/src/MatterEndpoints/MatterOccupancySensor.cpp
libraries/Matter/src/MatterEndpoints/MatterOnOffPlugin.cpp
libraries/Matter/src/Matter.cpp)
set(ARDUINO_LIBRARY_PPP_SRCS
libraries/PPP/src/PPP.cpp
libraries/PPP/src/ppp.c)
@ -258,10 +276,15 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS
libraries/Zigbee/src/ZigbeeHandlers.cpp
libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp
libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp
libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp
libraries/Zigbee/src/ep/ZigbeeLight.cpp
libraries/Zigbee/src/ep/ZigbeeSwitch.cpp
libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp
libraries/Zigbee/src/ep/ZigbeeThermostat.cpp
libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp
libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp
libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp
libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp
)
set(ARDUINO_LIBRARY_BLE_SRCS
@ -317,7 +340,7 @@ endforeach()
set(includedirs variants/${CONFIG_ARDUINO_VARIANT}/ cores/esp32/ ${ARDUINO_LIBRARIES_INCLUDEDIRS})
set(srcs ${CORE_SRCS} ${ARDUINO_LIBRARIES_SRCS})
set(priv_includes cores/esp32/libb64)
set(requires spi_flash esp_partition mbedtls wpa_supplicant esp_adc esp_eth http_parser espressif__network_provisioning)
set(requires spi_flash esp_partition mbedtls wpa_supplicant esp_adc esp_eth http_parser esp_ringbuf esp_driver_gptimer esp_driver_usb_serial_jtag driver)
set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support bt esp_hid usb esp_psram ${ARDUINO_LIBRARIES_REQUIRES})
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_OpenThread)
@ -328,6 +351,10 @@ if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_OpenThre
endif()
endif()
if(IDF_TARGET STREQUAL "esp32p4")
list(APPEND requires esp_driver_touch_sens)
endif()
idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires})
if(NOT CONFIG_FREERTOS_HZ EQUAL 1000 AND NOT "$ENV{ARDUINO_SKIP_TICK_CHECK}")
@ -367,9 +394,21 @@ function(maybe_add_component component_name)
endif()
endfunction()
if(IDF_TARGET MATCHES "esp32s2|esp32s3" AND CONFIG_TINYUSB_ENABLED)
if(IDF_TARGET MATCHES "esp32s2|esp32s3|esp32p4" AND CONFIG_TINYUSB_ENABLED)
maybe_add_component(arduino_tinyusb)
endif()
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_ArduinoOTA)
maybe_add_component(esp_https_ota)
endif()
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_ESP_SR)
maybe_add_component(espressif__esp_sr)
endif()
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_Matter)
maybe_add_component(espressif__esp_matter)
endif()
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_LittleFS)
maybe_add_component(joltwallet__littlefs)
endif()
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_WiFiProv)
maybe_add_component(espressif__network_provisioning)
endif()

View file

@ -266,6 +266,11 @@ config ARDUINO_SELECTIVE_Wire
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_ESP_SR
bool "Enable ESP-SR"
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_EEPROM
bool "Enable EEPROM"
depends on ARDUINO_SELECTIVE_COMPILATION
@ -286,6 +291,11 @@ config ARDUINO_SELECTIVE_Update
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_Zigbee
bool "Enable Zigbee"
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_FS
bool "Enable FS"
depends on ARDUINO_SELECTIVE_COMPILATION
@ -358,6 +368,11 @@ config ARDUINO_SELECTIVE_HTTPClient
select ARDUINO_SELECTIVE_NetworkClientSecure
default y
config ARDUINO_SELECTIVE_Matter
bool "Enable Matter"
depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Network
default y
config ARDUINO_SELECTIVE_NetBIOS
bool "Enable NetBIOS"
depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Network
@ -399,4 +414,19 @@ config ARDUINO_SELECTIVE_SimpleBLE
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_RainMaker
bool "Enable RainMaker"
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_OpenThread
bool "Enable OpenThread"
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_Insights
bool "Enable Insights"
depends on ARDUINO_SELECTIVE_COMPILATION
default y
endmenu

View file

@ -1,6 +1,9 @@
# Arduino core for the ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6 and ESP32-H2
# Arduino core for the ESP32, ESP32-P4, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6 and ESP32-H2
[![Build Status](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml/badge.svg?branch=master&event=push)](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml) [![External Libraries Test](https://github.com/espressif/arduino-esp32/actions/workflows/lib.yml/badge.svg?branch=master&event=schedule)](https://github.com/espressif/arduino-esp32/blob/gh-pages/LIBRARIES_TEST.md) [![Hardware Tests](https://github.com/espressif/arduino-esp32/blob/gh-pages/runtime-tests-results/badge.svg)](https://github.com/espressif/arduino-esp32/actions/workflows/tests_results.yml)
[![Build Status](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/push.yml?branch=master&event=push&label=Compilation%20Tests)](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml?query=branch%3Amaster+event%3Apush)
[![Verbose Build Status](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/push.yml?branch=master&event=schedule&label=Compilation%20Tests%20(Verbose))](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml?query=branch%3Amaster+event%3Aschedule)
[![External Libraries Test](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/lib.yml?branch=master&event=schedule&label=External%20Libraries%20Test)](https://github.com/espressif/arduino-esp32/blob/gh-pages/LIBRARIES_TEST.md)
[![Runtime Tests](https://github.com/espressif/arduino-esp32/blob/gh-pages/runtime-tests-results/badge.svg)](https://github.com/espressif/arduino-esp32/actions/workflows/tests_results.yml)
### Need help or have a question? Join the chat at [Gitter](https://gitter.im/espressif/arduino-esp32) or [open a new Discussion](https://github.com/espressif/arduino-esp32/discussions)
@ -16,9 +19,17 @@
### Development Status
Latest Stable Release [![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) [![Release Date](https://img.shields.io/github/release-date/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) [![Downloads](https://img.shields.io/github/downloads/espressif/arduino-esp32/latest/total.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/)
#### Latest Stable Release
Latest Development Release [![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/) [![Release Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/) [![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/)
[![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/)
[![Release Date](https://img.shields.io/github/release-date/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/)
[![Downloads](https://img.shields.io/github/downloads/espressif/arduino-esp32/latest/total.svg)](https://github.com/espressif/arduino-esp32/releases/latest/)
#### Latest Development Release
[![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg)](https://github.com/espressif/arduino-esp32/releases/)
[![Release Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/)
[![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg)](https://github.com/espressif/arduino-esp32/releases/)
### Development Planning
@ -59,6 +70,7 @@ Here are the ESP32 series supported by the Arduino-ESP32 project:
| ESP32-S3 | Yes | Yes | [ESP32-S3](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) |
| ESP32-C6 | Yes | Yes | [ESP32-C6](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) |
| ESP32-H2 | Yes | Yes | [ESP32-H2](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) |
| ESP32-P4 | Yes | Yes | [ESP32-P4](https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf) |
> [!NOTE]
> ESP32-C2 is also supported by Arduino-ESP32 but requires rebuilding the static libraries. This is not trivial and requires a good understanding of the ESP-IDF

View file

@ -161,6 +161,195 @@ esp32c2.menu.EraseFlash.all.upload.erase_cmd=-e
##############################################################
esp32p4.name=ESP32P4 Dev Module
esp32p4.bootloader.tool=esptool_py
esp32p4.bootloader.tool.default=esptool_py
esp32p4.upload.tool=esptool_py
esp32p4.upload.tool.default=esptool_py
esp32p4.upload.tool.network=esp_ota
esp32p4.upload.maximum_size=1310720
esp32p4.upload.maximum_data_size=327680
esp32p4.upload.flags=
esp32p4.upload.extra_flags=
esp32p4.upload.use_1200bps_touch=false
esp32p4.upload.wait_for_upload_port=false
esp32p4.serial.disableDTR=false
esp32p4.serial.disableRTS=false
esp32p4.build.tarch=riscv32
esp32p4.build.target=esp
esp32p4.build.mcu=esp32p4
esp32p4.build.core=esp32
esp32p4.build.variant=esp32p4
esp32p4.build.board=ESP32P4_DEV
esp32p4.build.bootloader_addr=0x2000
esp32p4.build.usb_mode=0
esp32p4.build.cdc_on_boot=0
esp32p4.build.msc_on_boot=0
esp32p4.build.dfu_on_boot=0
esp32p4.build.f_cpu=360000000L
esp32p4.build.flash_size=4MB
esp32p4.build.flash_freq=80m
esp32p4.build.img_freq=80m
esp32p4.build.flash_mode=qio
esp32p4.build.boot=qio
esp32p4.build.partitions=default
esp32p4.build.defines=
## IDE 2.0 Seems to not update the value
esp32p4.menu.JTAGAdapter.default=Disabled
esp32p4.menu.JTAGAdapter.default.build.copy_jtag_files=0
esp32p4.menu.JTAGAdapter.builtin=Integrated USB JTAG
esp32p4.menu.JTAGAdapter.builtin.build.openocdscript=esp32p4-builtin.cfg
esp32p4.menu.JTAGAdapter.builtin.build.copy_jtag_files=1
esp32p4.menu.JTAGAdapter.external=FTDI Adapter
esp32p4.menu.JTAGAdapter.external.build.openocdscript=esp32p4-ftdi.cfg
esp32p4.menu.JTAGAdapter.external.build.copy_jtag_files=1
esp32p4.menu.JTAGAdapter.bridge=ESP USB Bridge
esp32p4.menu.JTAGAdapter.bridge.build.openocdscript=esp32p4-bridge.cfg
esp32p4.menu.JTAGAdapter.bridge.build.copy_jtag_files=1
esp32p4.menu.PSRAM.disabled=Disabled
esp32p4.menu.PSRAM.disabled.build.defines=
esp32p4.menu.PSRAM.enabled=Enabled
esp32p4.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM
esp32p4.menu.USBMode.default=USB-OTG (TinyUSB)
esp32p4.menu.USBMode.default.build.usb_mode=0
esp32p4.menu.USBMode.hwcdc=Hardware CDC and JTAG
esp32p4.menu.USBMode.hwcdc.build.usb_mode=1
esp32p4.menu.CDCOnBoot.default=Disabled
esp32p4.menu.CDCOnBoot.default.build.cdc_on_boot=0
esp32p4.menu.CDCOnBoot.cdc=Enabled
esp32p4.menu.CDCOnBoot.cdc.build.cdc_on_boot=1
esp32p4.menu.MSCOnBoot.default=Disabled
esp32p4.menu.MSCOnBoot.default.build.msc_on_boot=0
esp32p4.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode)
esp32p4.menu.MSCOnBoot.msc.build.msc_on_boot=1
esp32p4.menu.DFUOnBoot.default=Disabled
esp32p4.menu.DFUOnBoot.default.build.dfu_on_boot=0
esp32p4.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode)
esp32p4.menu.DFUOnBoot.dfu.build.dfu_on_boot=1
esp32p4.menu.UploadMode.default=UART0 / Hardware CDC
esp32p4.menu.UploadMode.default.upload.use_1200bps_touch=false
esp32p4.menu.UploadMode.default.upload.wait_for_upload_port=false
esp32p4.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB)
esp32p4.menu.UploadMode.cdc.upload.use_1200bps_touch=true
esp32p4.menu.UploadMode.cdc.upload.wait_for_upload_port=true
esp32p4.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
esp32p4.menu.PartitionScheme.default.build.partitions=default
esp32p4.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
esp32p4.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
esp32p4.menu.PartitionScheme.default_8MB=8M with spiffs (3MB APP/1.5MB SPIFFS)
esp32p4.menu.PartitionScheme.default_8MB.build.partitions=default_8MB
esp32p4.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336
esp32p4.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
esp32p4.menu.PartitionScheme.minimal.build.partitions=minimal
esp32p4.menu.PartitionScheme.no_fs=No FS 4MB (2MB APP x2)
esp32p4.menu.PartitionScheme.no_fs.build.partitions=no_fs
esp32p4.menu.PartitionScheme.no_fs.upload.maximum_size=2031616
esp32p4.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
esp32p4.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32p4.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
esp32p4.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
esp32p4.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
esp32p4.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
esp32p4.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
esp32p4.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
esp32p4.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
esp32p4.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
esp32p4.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
esp32p4.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
esp32p4.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
esp32p4.menu.PartitionScheme.huge_app.build.partitions=huge_app
esp32p4.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
esp32p4.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
esp32p4.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32p4.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
esp32p4.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FATFS)
esp32p4.menu.PartitionScheme.fatflash.build.partitions=ffat
esp32p4.menu.PartitionScheme.fatflash.upload.maximum_size=2097152
esp32p4.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9.9MB FATFS)
esp32p4.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB
esp32p4.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728
esp32p4.menu.PartitionScheme.custom=Custom
esp32p4.menu.PartitionScheme.custom.build.partitions=
esp32p4.menu.PartitionScheme.custom.upload.maximum_size=16777216
## From https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/kconfig.html#config-esp-default-cpu-freq-mhz
esp32p4.menu.CPUFreq.360=360MHz
esp32p4.menu.CPUFreq.360.build.f_cpu=360000000L
esp32p4.menu.CPUFreq.40=40MHz
esp32p4.menu.CPUFreq.40.build.f_cpu=40000000L
esp32p4.menu.FlashMode.qio=QIO
esp32p4.menu.FlashMode.qio.build.flash_mode=dio
esp32p4.menu.FlashMode.qio.build.boot=qio
esp32p4.menu.FlashMode.dio=DIO
esp32p4.menu.FlashMode.dio.build.flash_mode=dio
esp32p4.menu.FlashMode.dio.build.boot=dio
esp32p4.menu.FlashFreq.80=80MHz
esp32p4.menu.FlashFreq.80.build.flash_freq=80m
esp32p4.menu.FlashFreq.40=40MHz
esp32p4.menu.FlashFreq.40.build.flash_freq=40m
esp32p4.menu.FlashSize.4M=4MB (32Mb)
esp32p4.menu.FlashSize.4M.build.flash_size=4MB
esp32p4.menu.FlashSize.8M=8MB (64Mb)
esp32p4.menu.FlashSize.8M.build.flash_size=8MB
esp32p4.menu.FlashSize.8M.build.partitions=default_8MB
esp32p4.menu.FlashSize.2M=2MB (16Mb)
esp32p4.menu.FlashSize.2M.build.flash_size=2MB
esp32p4.menu.FlashSize.2M.build.partitions=minimal
esp32p4.menu.FlashSize.16M=16MB (128Mb)
esp32p4.menu.FlashSize.16M.build.flash_size=16MB
esp32p4.menu.UploadSpeed.921600=921600
esp32p4.menu.UploadSpeed.921600.upload.speed=921600
esp32p4.menu.UploadSpeed.115200=115200
esp32p4.menu.UploadSpeed.115200.upload.speed=115200
esp32p4.menu.UploadSpeed.256000.windows=256000
esp32p4.menu.UploadSpeed.256000.upload.speed=256000
esp32p4.menu.UploadSpeed.230400.windows.upload.speed=256000
esp32p4.menu.UploadSpeed.230400=230400
esp32p4.menu.UploadSpeed.230400.upload.speed=230400
esp32p4.menu.UploadSpeed.460800.linux=460800
esp32p4.menu.UploadSpeed.460800.macosx=460800
esp32p4.menu.UploadSpeed.460800.upload.speed=460800
esp32p4.menu.UploadSpeed.512000.windows=512000
esp32p4.menu.UploadSpeed.512000.upload.speed=512000
esp32p4.menu.DebugLevel.none=None
esp32p4.menu.DebugLevel.none.build.code_debug=0
esp32p4.menu.DebugLevel.error=Error
esp32p4.menu.DebugLevel.error.build.code_debug=1
esp32p4.menu.DebugLevel.warn=Warn
esp32p4.menu.DebugLevel.warn.build.code_debug=2
esp32p4.menu.DebugLevel.info=Info
esp32p4.menu.DebugLevel.info.build.code_debug=3
esp32p4.menu.DebugLevel.debug=Debug
esp32p4.menu.DebugLevel.debug.build.code_debug=4
esp32p4.menu.DebugLevel.verbose=Verbose
esp32p4.menu.DebugLevel.verbose.build.code_debug=5
esp32p4.menu.EraseFlash.none=Disabled
esp32p4.menu.EraseFlash.none.upload.erase_cmd=
esp32p4.menu.EraseFlash.all=Enabled
esp32p4.menu.EraseFlash.all.upload.erase_cmd=-e
##############################################################
esp32h2.name=ESP32H2 Dev Module
esp32h2.bootloader.tool=esptool_py
@ -342,7 +531,15 @@ esp32h2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_co
esp32h2.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor)
esp32h2.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP
esp32h2.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port
esp32h2.menu.ZigbeeMode.ed_debug=Zigbee ED (end device) - Debug
esp32h2.menu.ZigbeeMode.ed_debug.build.zigbee_mode=-DZIGBEE_MODE_ED
esp32h2.menu.ZigbeeMode.ed_debug.build.zigbee_libs=-lesp_zb_api_ed.debug -lesp_zb_cli_command -lzboss_stack.ed.debug -lzboss_port.debug
esp32h2.menu.ZigbeeMode.zczr_debug=Zigbee ZCZR (coordinator/router) - Debug
esp32h2.menu.ZigbeeMode.zczr_debug.build.zigbee_mode=-DZIGBEE_MODE_ZCZR
esp32h2.menu.ZigbeeMode.zczr_debug.build.zigbee_libs=-lesp_zb_api_zczr.debug -lesp_zb_cli_command -lzboss_stack.zczr.debug -lzboss_port.debug
esp32h2.menu.ZigbeeMode.rcp_debug=Zigbee RCP (radio co-processor) - Debug
esp32h2.menu.ZigbeeMode.rcp_debug.build.zigbee_mode=-DZIGBEE_MODE_RCP
esp32h2.menu.ZigbeeMode.rcp_debug.build.zigbee_libs=-lesp_zb_api_rcp.debug -lesp_zb_cli_command -lzboss_stack.rcp.debug -lzboss_port.debug
##############################################################
@ -534,6 +731,15 @@ esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_co
esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor)
esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP
esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port
esp32c6.menu.ZigbeeMode.ed_debug=Zigbee ED (end device) - Debug
esp32c6.menu.ZigbeeMode.ed_debug.build.zigbee_mode=-DZIGBEE_MODE_ED
esp32c6.menu.ZigbeeMode.ed_debug.build.zigbee_libs=-lesp_zb_api_ed.debug -lesp_zb_cli_command -lzboss_stack.ed.debug -lzboss_port.debug
esp32c6.menu.ZigbeeMode.zczr_debug=Zigbee ZCZR (coordinator/router) - Debug
esp32c6.menu.ZigbeeMode.zczr_debug.build.zigbee_mode=-DZIGBEE_MODE_ZCZR
esp32c6.menu.ZigbeeMode.zczr_debug.build.zigbee_libs=-lesp_zb_api_zczr.debug -lesp_zb_cli_command -lzboss_stack.zczr.debug -lzboss_port.debug
esp32c6.menu.ZigbeeMode.rcp_debug=Zigbee RCP (radio co-processor) - Debug
esp32c6.menu.ZigbeeMode.rcp_debug.build.zigbee_mode=-DZIGBEE_MODE_RCP
esp32c6.menu.ZigbeeMode.rcp_debug.build.zigbee_libs=-lesp_zb_api_rcp.debug -lesp_zb_cli_command -lzboss_stack.rcp.debug -lzboss_port.debug
##############################################################
@ -48239,3 +48445,222 @@ yb_esp32s3_amp_v3.menu.EraseFlash.all=Enabled
yb_esp32s3_amp_v3.menu.EraseFlash.all.upload.erase_cmd=-e
##############################################################
yb_esp32s3_eth.name=YelloByte YB-ESP32-S3-ETH
yb_esp32s3_eth.bootloader.tool=esptool_py
yb_esp32s3_eth.bootloader.tool.default=esptool_py
yb_esp32s3_eth.upload.tool=esptool_py
yb_esp32s3_eth.upload.tool.default=esptool_py
yb_esp32s3_eth.upload.tool.network=esp_ota
yb_esp32s3_eth.upload.maximum_size=1310720
yb_esp32s3_eth.upload.maximum_data_size=327680
yb_esp32s3_eth.upload.flags=
yb_esp32s3_eth.upload.extra_flags=
yb_esp32s3_eth.upload.use_1200bps_touch=false
yb_esp32s3_eth.upload.wait_for_upload_port=false
yb_esp32s3_eth.serial.disableDTR=false
yb_esp32s3_eth.serial.disableRTS=false
yb_esp32s3_eth.build.tarch=xtensa
yb_esp32s3_eth.build.bootloader_addr=0x0
yb_esp32s3_eth.build.target=esp32s3
yb_esp32s3_eth.build.mcu=esp32s3
yb_esp32s3_eth.build.core=esp32
yb_esp32s3_eth.build.variant=yb_esp32s3_eth
yb_esp32s3_eth.build.board=YB_ESP32S3_ETH
yb_esp32s3_eth.build.usb_mode=1
yb_esp32s3_eth.build.cdc_on_boot=0
yb_esp32s3_eth.build.msc_on_boot=0
yb_esp32s3_eth.build.dfu_on_boot=0
yb_esp32s3_eth.build.f_cpu=240000000L
yb_esp32s3_eth.build.flash_size=4MB
yb_esp32s3_eth.build.flash_freq=80m
yb_esp32s3_eth.build.flash_mode=dio
yb_esp32s3_eth.build.boot=qio
yb_esp32s3_eth.build.boot_freq=80m
yb_esp32s3_eth.build.partitions=default
yb_esp32s3_eth.build.defines=
yb_esp32s3_eth.build.loop_core=
yb_esp32s3_eth.build.event_core=
yb_esp32s3_eth.build.psram_type=qspi
yb_esp32s3_eth.build.memory_type={build.boot}_{build.psram_type}
yb_esp32s3_eth.menu.JTAGAdapter.default=Disabled
yb_esp32s3_eth.menu.JTAGAdapter.default.build.copy_jtag_files=0
yb_esp32s3_eth.menu.JTAGAdapter.builtin=Integrated USB JTAG
yb_esp32s3_eth.menu.JTAGAdapter.builtin.build.openocdscript=esp32s3-builtin.cfg
yb_esp32s3_eth.menu.JTAGAdapter.builtin.build.copy_jtag_files=1
yb_esp32s3_eth.menu.JTAGAdapter.external=FTDI Adapter
yb_esp32s3_eth.menu.JTAGAdapter.external.build.openocdscript=esp32s3-ftdi.cfg
yb_esp32s3_eth.menu.JTAGAdapter.external.build.copy_jtag_files=1
yb_esp32s3_eth.menu.JTAGAdapter.bridge=ESP USB Bridge
yb_esp32s3_eth.menu.JTAGAdapter.bridge.build.openocdscript=esp32s3-bridge.cfg
yb_esp32s3_eth.menu.JTAGAdapter.bridge.build.copy_jtag_files=1
yb_esp32s3_eth.menu.LoopCore.1=Core 1
yb_esp32s3_eth.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1
yb_esp32s3_eth.menu.LoopCore.0=Core 0
yb_esp32s3_eth.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0
yb_esp32s3_eth.menu.EventsCore.1=Core 1
yb_esp32s3_eth.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1
yb_esp32s3_eth.menu.EventsCore.0=Core 0
yb_esp32s3_eth.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0
yb_esp32s3_eth.menu.USBMode.hwcdc=Hardware CDC and JTAG
yb_esp32s3_eth.menu.USBMode.hwcdc.build.usb_mode=1
yb_esp32s3_eth.menu.USBMode.default=USB-OTG (TinyUSB)
yb_esp32s3_eth.menu.USBMode.default.build.usb_mode=0
yb_esp32s3_eth.menu.CDCOnBoot.default=Disabled
yb_esp32s3_eth.menu.CDCOnBoot.default.build.cdc_on_boot=0
yb_esp32s3_eth.menu.CDCOnBoot.cdc=Enabled
yb_esp32s3_eth.menu.CDCOnBoot.cdc.build.cdc_on_boot=1
yb_esp32s3_eth.menu.MSCOnBoot.default=Disabled
yb_esp32s3_eth.menu.MSCOnBoot.default.build.msc_on_boot=0
yb_esp32s3_eth.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode)
yb_esp32s3_eth.menu.MSCOnBoot.msc.build.msc_on_boot=1
yb_esp32s3_eth.menu.DFUOnBoot.default=Disabled
yb_esp32s3_eth.menu.DFUOnBoot.default.build.dfu_on_boot=0
yb_esp32s3_eth.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode)
yb_esp32s3_eth.menu.DFUOnBoot.dfu.build.dfu_on_boot=1
yb_esp32s3_eth.menu.UploadMode.default=UART0 / Hardware CDC
yb_esp32s3_eth.menu.UploadMode.default.upload.use_1200bps_touch=false
yb_esp32s3_eth.menu.UploadMode.default.upload.wait_for_upload_port=false
yb_esp32s3_eth.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB)
yb_esp32s3_eth.menu.UploadMode.cdc.upload.use_1200bps_touch=true
yb_esp32s3_eth.menu.UploadMode.cdc.upload.wait_for_upload_port=true
yb_esp32s3_eth.menu.PSRAM.disabled=Disabled
yb_esp32s3_eth.menu.PSRAM.disabled.build.defines=
yb_esp32s3_eth.menu.PSRAM.disabled.build.psram_type=qspi
yb_esp32s3_eth.menu.PSRAM.enabled=QSPI PSRAM
yb_esp32s3_eth.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM
yb_esp32s3_eth.menu.PSRAM.enabled.build.psram_type=qspi
yb_esp32s3_eth.menu.PSRAM.opi=OPI PSRAM
yb_esp32s3_eth.menu.PSRAM.opi.build.defines=-DBOARD_HAS_PSRAM
yb_esp32s3_eth.menu.PSRAM.opi.build.psram_type=opi
yb_esp32s3_eth.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
yb_esp32s3_eth.menu.PartitionScheme.default.build.partitions=default
yb_esp32s3_eth.menu.PartitionScheme.default_8MB=8M with spiffs (3MB APP/1.5MB SPIFFS)
yb_esp32s3_eth.menu.PartitionScheme.default_8MB.build.partitions=default_8MB
yb_esp32s3_eth.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336
yb_esp32s3_eth.menu.PartitionScheme.default_16MB=16M with spiffs (6.25MB APP/3.43MB SPIFFS)
yb_esp32s3_eth.menu.PartitionScheme.default_16MB.build.partitions=default_16MB
yb_esp32s3_eth.menu.PartitionScheme.default_16MB.upload.maximum_size=6553600
yb_esp32s3_eth.menu.PartitionScheme.max_app_8MB=Maximum APP (7.9MB APP No OTA/No FS)
yb_esp32s3_eth.menu.PartitionScheme.max_app_8MB.build.partitions=max_app_8MB
yb_esp32s3_eth.menu.PartitionScheme.max_app_8MB.upload.maximum_size=8257536
yb_esp32s3_eth.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FATFS)
yb_esp32s3_eth.menu.PartitionScheme.fatflash.build.partitions=ffat
yb_esp32s3_eth.menu.PartitionScheme.fatflash.upload.maximum_size=2097152
yb_esp32s3_eth.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
yb_esp32s3_eth.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
yb_esp32s3_eth.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
yb_esp32s3_eth.menu.PartitionScheme.minimal.build.partitions=minimal
yb_esp32s3_eth.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
yb_esp32s3_eth.menu.PartitionScheme.no_ota.build.partitions=no_ota
yb_esp32s3_eth.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
yb_esp32s3_eth.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
yb_esp32s3_eth.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
yb_esp32s3_eth.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
yb_esp32s3_eth.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
yb_esp32s3_eth.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
yb_esp32s3_eth.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
yb_esp32s3_eth.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
yb_esp32s3_eth.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
yb_esp32s3_eth.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
yb_esp32s3_eth.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
yb_esp32s3_eth.menu.PartitionScheme.huge_app.build.partitions=huge_app
yb_esp32s3_eth.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
yb_esp32s3_eth.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
yb_esp32s3_eth.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
yb_esp32s3_eth.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
yb_esp32s3_eth.menu.PartitionScheme.custom=Custom
yb_esp32s3_eth.menu.PartitionScheme.custom.build.partitions=
yb_esp32s3_eth.menu.PartitionScheme.custom.upload.maximum_size=16777216
yb_esp32s3_eth.menu.CPUFreq.240=240MHz (WiFi)
yb_esp32s3_eth.menu.CPUFreq.240.build.f_cpu=240000000L
yb_esp32s3_eth.menu.CPUFreq.160=160MHz (WiFi)
yb_esp32s3_eth.menu.CPUFreq.160.build.f_cpu=160000000L
yb_esp32s3_eth.menu.CPUFreq.80=80MHz (WiFi)
yb_esp32s3_eth.menu.CPUFreq.80.build.f_cpu=80000000L
yb_esp32s3_eth.menu.CPUFreq.40=40MHz
yb_esp32s3_eth.menu.CPUFreq.40.build.f_cpu=40000000L
yb_esp32s3_eth.menu.CPUFreq.20=20MHz
yb_esp32s3_eth.menu.CPUFreq.20.build.f_cpu=20000000L
yb_esp32s3_eth.menu.CPUFreq.10=10MHz
yb_esp32s3_eth.menu.CPUFreq.10.build.f_cpu=10000000L
yb_esp32s3_eth.menu.FlashMode.qio=QIO 80MHz
yb_esp32s3_eth.menu.FlashMode.qio.build.flash_mode=dio
yb_esp32s3_eth.menu.FlashMode.qio.build.boot=qio
yb_esp32s3_eth.menu.FlashMode.qio.build.boot_freq=80m
yb_esp32s3_eth.menu.FlashMode.qio.build.flash_freq=80m
yb_esp32s3_eth.menu.FlashMode.qio120=QIO 120MHz
yb_esp32s3_eth.menu.FlashMode.qio120.build.flash_mode=dio
yb_esp32s3_eth.menu.FlashMode.qio120.build.boot=qio
yb_esp32s3_eth.menu.FlashMode.qio120.build.boot_freq=120m
yb_esp32s3_eth.menu.FlashMode.qio120.build.flash_freq=80m
yb_esp32s3_eth.menu.FlashMode.dio=DIO 80MHz
yb_esp32s3_eth.menu.FlashMode.dio.build.flash_mode=dio
yb_esp32s3_eth.menu.FlashMode.dio.build.boot=dio
yb_esp32s3_eth.menu.FlashMode.dio.build.boot_freq=80m
yb_esp32s3_eth.menu.FlashMode.dio.build.flash_freq=80m
yb_esp32s3_eth.menu.FlashMode.opi=OPI 80MHz
yb_esp32s3_eth.menu.FlashMode.opi.build.flash_mode=dout
yb_esp32s3_eth.menu.FlashMode.opi.build.boot=opi
yb_esp32s3_eth.menu.FlashMode.opi.build.boot_freq=80m
yb_esp32s3_eth.menu.FlashMode.opi.build.flash_freq=80m
yb_esp32s3_eth.menu.FlashSize.4M=4MB (32Mb)
yb_esp32s3_eth.menu.FlashSize.4M.build.flash_size=4MB
yb_esp32s3_eth.menu.FlashSize.8M=8MB (64Mb)
yb_esp32s3_eth.menu.FlashSize.8M.build.flash_size=8MB
yb_esp32s3_eth.menu.FlashSize.16M=16MB (128Mb)
yb_esp32s3_eth.menu.FlashSize.16M.build.flash_size=16MB
yb_esp32s3_eth.menu.UploadSpeed.921600=921600
yb_esp32s3_eth.menu.UploadSpeed.921600.upload.speed=921600
yb_esp32s3_eth.menu.UploadSpeed.115200=115200
yb_esp32s3_eth.menu.UploadSpeed.115200.upload.speed=115200
yb_esp32s3_eth.menu.UploadSpeed.256000.windows=256000
yb_esp32s3_eth.menu.UploadSpeed.256000.upload.speed=256000
yb_esp32s3_eth.menu.UploadSpeed.230400.windows.upload.speed=256000
yb_esp32s3_eth.menu.UploadSpeed.230400=230400
yb_esp32s3_eth.menu.UploadSpeed.230400.upload.speed=230400
yb_esp32s3_eth.menu.UploadSpeed.460800.linux=460800
yb_esp32s3_eth.menu.UploadSpeed.460800.macosx=460800
yb_esp32s3_eth.menu.UploadSpeed.460800.upload.speed=460800
yb_esp32s3_eth.menu.UploadSpeed.512000.windows=512000
yb_esp32s3_eth.menu.UploadSpeed.512000.upload.speed=512000
yb_esp32s3_eth.menu.DebugLevel.none=None
yb_esp32s3_eth.menu.DebugLevel.none.build.code_debug=0
yb_esp32s3_eth.menu.DebugLevel.error=Error
yb_esp32s3_eth.menu.DebugLevel.error.build.code_debug=1
yb_esp32s3_eth.menu.DebugLevel.warn=Warn
yb_esp32s3_eth.menu.DebugLevel.warn.build.code_debug=2
yb_esp32s3_eth.menu.DebugLevel.info=Info
yb_esp32s3_eth.menu.DebugLevel.info.build.code_debug=3
yb_esp32s3_eth.menu.DebugLevel.debug=Debug
yb_esp32s3_eth.menu.DebugLevel.debug.build.code_debug=4
yb_esp32s3_eth.menu.DebugLevel.verbose=Verbose
yb_esp32s3_eth.menu.DebugLevel.verbose.build.code_debug=5
yb_esp32s3_eth.menu.EraseFlash.none=Disabled
yb_esp32s3_eth.menu.EraseFlash.none.upload.erase_cmd=
yb_esp32s3_eth.menu.EraseFlash.all=Enabled
yb_esp32s3_eth.menu.EraseFlash.all.upload.erase_cmd=-e
##############################################################

View file

@ -199,6 +199,7 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
#include "Udp.h"
#include "HardwareSerial.h"
#include "Esp.h"
#include "freertos_stats.h"
// Use float-compatible stl abs() and round(), we don't use Arduino macros to avoid issues with the C++ libraries
using std::abs;

View file

@ -26,7 +26,9 @@
class Client : public Stream {
public:
virtual int connect(IPAddress ip, uint16_t port) = 0;
virtual int connect(IPAddress ip, uint16_t port, int32_t timeout) = 0;
virtual int connect(const char *host, uint16_t port) = 0;
virtual int connect(const char *host, uint16_t port, int32_t timeout) = 0;
virtual size_t write(uint8_t) = 0;
virtual size_t write(const uint8_t *buf, size_t size) = 0;
virtual int available() = 0;

279
cores/esp32/ColorFormat.c Normal file
View file

@ -0,0 +1,279 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ColorFormat.h"
#include <math.h>
// define a clamp macro to substitute the std::clamp macro which is available from C++17 onwards
#define clamp(a, min, max) ((a) < (min) ? (min) : ((a) > (max) ? (max) : (a)))
const espHsvColor_t HSV_BLACK = {0, 0, 0};
const espHsvColor_t HSV_WHITE = {0, 0, 254};
const espHsvColor_t HSV_RED = {0, 254, 254};
const espHsvColor_t HSV_YELLOW = {42, 254, 254};
const espHsvColor_t HSV_GREEN = {84, 254, 254};
const espHsvColor_t HSV_CYAN = {127, 254, 254};
const espHsvColor_t HSV_BLUE = {169, 254, 254};
const espHsvColor_t HSV_MAGENTA = {211, 254, 254};
const espRgbColor_t RGB_BLACK = {0, 0, 0};
const espRgbColor_t RGB_WHITE = {255, 255, 255};
const espRgbColor_t RGB_RED = {255, 0, 0};
const espRgbColor_t RGB_YELLOW = {255, 255, 0};
const espRgbColor_t RGB_GREEN = {0, 255, 0};
const espRgbColor_t RGB_CYAN = {0, 255, 255};
const espRgbColor_t RGB_BLUE = {0, 0, 255};
const espRgbColor_t RGB_MAGENTA = {255, 0, 255};
// main color temperature values
const espCtColor_t COOL_WHITE_COLOR_TEMPERATURE = {142};
const espCtColor_t DAYLIGHT_WHITE_COLOR_TEMPERATURE = {181};
const espCtColor_t WHITE_COLOR_TEMPERATURE = {250};
const espCtColor_t SOFT_WHITE_COLOR_TEMPERATURE = {370};
const espCtColor_t WARM_WHITE_COLOR_TEMPERATURE = {454};
espRgbColor_t espHsvToRgbColor(uint16_t h, uint8_t s, uint8_t v) {
espHsvColor_t hsv = {h, s, v};
return espHsvColorToRgbColor(hsv);
}
espRgbColor_t espHsvColorToRgbColor(espHsvColor_t hsv) {
espRgbColor_t rgb;
uint8_t region, p, q, t;
uint32_t h, s, v, remainder;
if (hsv.s == 0) {
rgb.r = rgb.g = rgb.b = hsv.v;
} else {
h = hsv.h;
s = hsv.s;
v = hsv.v;
region = h / 43;
remainder = (h - (region * 43)) * 6;
p = (v * (255 - s)) >> 8;
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch (region) {
case 0: rgb.r = v, rgb.g = t, rgb.b = p; break;
case 1: rgb.r = q, rgb.g = v, rgb.b = p; break;
case 2: rgb.r = p, rgb.g = v, rgb.b = t; break;
case 3: rgb.r = p, rgb.g = q, rgb.b = v; break;
case 4: rgb.r = t, rgb.g = p, rgb.b = v; break;
case 5:
default: rgb.r = v, rgb.g = p, rgb.b = q; break;
}
}
return rgb;
}
espHsvColor_t espRgbToHsvColor(uint8_t r, uint8_t g, uint8_t b) {
espRgbColor_t rgb = {r, g, b};
return espRgbColorToHsvColor(rgb);
}
espHsvColor_t espRgbColorToHsvColor(espRgbColor_t rgb) {
espHsvColor_t hsv;
uint8_t rgbMin, rgbMax;
rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
hsv.v = rgbMax;
if (hsv.v == 0) {
hsv.h = 0;
hsv.s = 0;
return hsv;
}
hsv.s = 255 * (rgbMax - rgbMin) / hsv.v;
if (hsv.s == 0) {
hsv.h = 0;
return hsv;
}
if (rgbMax == rgb.r) {
hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
} else if (rgbMax == rgb.g) {
hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
} else {
hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
}
return hsv;
}
espRgbColor_t espXYColorToRgbColor(uint8_t Level, espXyColor_t xy) {
return espXYToRgbColor(Level, xy.x, xy.y);
}
espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y) {
// convert xyY color space to RGB
// https://www.easyrgb.com/en/math.php
// https://en.wikipedia.org/wiki/SRGB
// refer https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space
// The current_X/current_Y attribute contains the current value of the normalized chromaticity value of x/y.
// The value of x/y shall be related to the current_X/current_Y attribute by the relationship
// x = current_X/65536
// y = current_Y/65536
// z = 1-x-y
espRgbColor_t rgb;
float x, y, z;
float X, Y, Z;
float r, g, b;
x = ((float)current_X) / 65535.0f;
y = ((float)current_Y) / 65535.0f;
z = 1.0f - x - y;
// Calculate XYZ values
// Y - given brightness in 0 - 1 range
Y = ((float)Level) / 254.0f;
X = (Y / y) * x;
Z = (Y / y) * z;
// X, Y and Z input refer to a D65/2° standard illuminant.
// sR, sG and sB (standard RGB) output range = 0 ÷ 255
// convert XYZ to RGB - CIE XYZ to sRGB
X = X / 100.0f;
Y = Y / 100.0f;
Z = Z / 100.0f;
r = (X * 3.2406f) - (Y * 1.5372f) - (Z * 0.4986f);
g = -(X * 0.9689f) + (Y * 1.8758f) + (Z * 0.0415f);
b = (X * 0.0557f) - (Y * 0.2040f) + (Z * 1.0570f);
// apply gamma 2.2 correction
r = (r <= 0.0031308f ? 12.92f * r : (1.055f) * pow(r, (1.0f / 2.4f)) - 0.055f);
g = (g <= 0.0031308f ? 12.92f * g : (1.055f) * pow(g, (1.0f / 2.4f)) - 0.055f);
b = (b <= 0.0031308f ? 12.92f * b : (1.055f) * pow(b, (1.0f / 2.4f)) - 0.055f);
// Round off
r = clamp(r, 0, 1);
g = clamp(g, 0, 1);
b = clamp(b, 0, 1);
// these rgb values are in the range of 0 to 1, convert to limit of HW specific LED
rgb.r = (uint8_t)(r * 255);
rgb.g = (uint8_t)(g * 255);
rgb.b = (uint8_t)(b * 255);
return rgb;
}
espXyColor_t espRgbToXYColor(uint8_t r, uint8_t g, uint8_t b) {
espRgbColor_t rgb = {r, g, b};
return espRgbColorToXYColor(rgb);
}
espXyColor_t espRgbColorToXYColor(espRgbColor_t rgb) {
// convert RGB to xy color space
// https://www.easyrgb.com/en/math.php
// https://en.wikipedia.org/wiki/SRGB
// refer https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space
espXyColor_t xy;
float r, g, b;
float X, Y, Z;
float x, y;
r = ((float)rgb.r) / 255.0f;
g = ((float)rgb.g) / 255.0f;
b = ((float)rgb.b) / 255.0f;
// convert RGB to XYZ - sRGB to CIE XYZ
r = (r <= 0.04045f ? r / 12.92f : pow((r + 0.055f) / 1.055f, 2.4f));
g = (g <= 0.04045f ? g / 12.92f : pow((g + 0.055f) / 1.055f, 2.4f));
b = (b <= 0.04045f ? b / 12.92f : pow((b + 0.055f) / 1.055f, 2.4f));
// https://gist.github.com/popcorn245/30afa0f98eea1c2fd34d
X = r * 0.649926f + g * 0.103455f + b * 0.197109f;
Y = r * 0.234327f + g * 0.743075f + b * 0.022598f;
Z = r * 0.0000000f + g * 0.053077f + b * 1.035763f;
// sR, sG and sB (standard RGB) input range = 0 ÷ 255
// X, Y and Z output refer to a D65/2° standard illuminant.
X = r * 0.4124564f + g * 0.3575761f + b * 0.1804375f;
Y = r * 0.2126729f + g * 0.7151522f + b * 0.0721750f;
Z = r * 0.0193339f + g * 0.1191920f + b * 0.9503041f;
// Calculate xy values
x = X / (X + Y + Z);
y = Y / (X + Y + Z);
// convert to 0-65535 range
xy.x = (uint16_t)(x * 65535);
xy.y = (uint16_t)(y * 65535);
return xy;
}
espRgbColor_t espCTToRgbColor(uint16_t ct) {
espCtColor_t ctColor = {ct};
return espCTColorToRgbColor(ctColor);
}
espRgbColor_t espCTColorToRgbColor(espCtColor_t ct) {
espRgbColor_t rgb = {0, 0, 0};
float r, g, b;
if (ct.ctMireds == 0) {
return rgb;
}
// Algorithm credits to Tanner Helland: https://tannerhelland.com/2012/09/18/convert-temperature-rgb-algorithm-code.html
// Convert Mireds to centiKelvins. k = 1,000,000/mired
float ctCentiKelvin = 10000 / ct.ctMireds;
// Red
if (ctCentiKelvin <= 66) {
r = 255;
} else {
r = 329.698727446f * pow(ctCentiKelvin - 60, -0.1332047592f);
}
// Green
if (ctCentiKelvin <= 66) {
g = 99.4708025861f * log(ctCentiKelvin) - 161.1195681661f;
} else {
g = 288.1221695283f * pow(ctCentiKelvin - 60, -0.0755148492f);
}
// Blue
if (ctCentiKelvin >= 66) {
b = 255;
} else {
if (ctCentiKelvin <= 19) {
b = 0;
} else {
b = 138.5177312231 * log(ctCentiKelvin - 10) - 305.0447927307;
}
}
rgb.r = (uint8_t)clamp(r, 0, 255);
rgb.g = (uint8_t)clamp(g, 0, 255);
rgb.b = (uint8_t)clamp(b, 0, 255);
return rgb;
}

70
cores/esp32/ColorFormat.h Normal file
View file

@ -0,0 +1,70 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* 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.
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct RgbColor_t {
uint8_t r;
uint8_t g;
uint8_t b;
};
struct HsvColor_t {
uint16_t h;
uint8_t s;
uint8_t v;
};
struct XyColor_t {
uint16_t x;
uint16_t y;
};
struct CtColor_t {
uint16_t ctMireds;
};
typedef struct RgbColor_t espRgbColor_t;
typedef struct HsvColor_t espHsvColor_t;
typedef struct XyColor_t espXyColor_t;
typedef struct CtColor_t espCtColor_t;
espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y);
espRgbColor_t espXYColorToRgb(uint8_t Level, espXyColor_t xy);
espXyColor_t espRgbColorToXYColor(espRgbColor_t rgb);
espXyColor_t espRgbToXYColor(uint8_t r, uint8_t g, uint8_t b);
espRgbColor_t espHsvColorToRgbColor(espHsvColor_t hsv);
espRgbColor_t espHsvToRgbColor(uint16_t h, uint8_t s, uint8_t v);
espRgbColor_t espCTColorToRgbColor(espCtColor_t ct);
espRgbColor_t espCTToRgbColor(uint16_t ct);
espHsvColor_t espRgbColorToHsvColor(espRgbColor_t rgb);
espHsvColor_t espRgbToHsvColor(uint8_t r, uint8_t g, uint8_t b);
extern const espHsvColor_t HSV_BLACK, HSV_WHITE, HSV_RED, HSV_YELLOW, HSV_GREEN, HSV_CYAN, HSV_BLUE, HSV_MAGENTA;
extern const espCtColor_t COOL_WHITE_COLOR_TEMPERATURE, DAYLIGHT_WHITE_COLOR_TEMPERATURE, WHITE_COLOR_TEMPERATURE, SOFT_WHITE_COLOR_TEMPERATURE,
WARM_WHITE_COLOR_TEMPERATURE;
extern const espRgbColor_t RGB_BLACK, RGB_WHITE, RGB_RED, RGB_YELLOW, RGB_GREEN, RGB_CYAN, RGB_BLUE, RGB_MAGENTA;
#ifdef __cplusplus
}
#endif

View file

@ -60,6 +60,9 @@ extern "C" {
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/spi_flash.h"
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32h2 is located at 0x0000
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/spi_flash.h"
#define ESP_FLASH_IMAGE_BASE 0x2000 // Esp32p4 is located at 0x2000
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
@ -297,6 +300,7 @@ const char *EspClass::getChipModel(void) {
case CHIP_ESP32C2: return "ESP32-C2";
case CHIP_ESP32C6: return "ESP32-C6";
case CHIP_ESP32H2: return "ESP32-H2";
case CHIP_ESP32P4: return "ESP32-P4";
default: return "UNKNOWN";
}
#endif
@ -335,6 +339,8 @@ uint32_t EspClass::getFlashChipSpeed(void) {
return magicFlashChipSpeed(fhdr.spi_speed);
}
// FIXME for P4
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
FlashMode_t EspClass::getFlashChipMode(void) {
#if CONFIG_IDF_TARGET_ESP32S2
uint32_t spi_ctrl = REG_READ(PERIPHS_SPI_FLASH_CTRL);
@ -361,6 +367,7 @@ FlashMode_t EspClass::getFlashChipMode(void) {
}
return (FM_DOUT);
}
#endif // if !defined(CONFIG_IDF_TARGET_ESP32P4)
uint32_t EspClass::magicFlashChipSize(uint8_t byte) {
/*

View file

@ -286,14 +286,14 @@ bool HWCDC::deinit(void *busptr) {
running = true;
// Setting USB D+ D- pins
bool retCode = true;
retCode &= perimanClearPinBus(USB_DM_GPIO_NUM);
retCode &= perimanClearPinBus(USB_DP_GPIO_NUM);
retCode &= perimanClearPinBus(USB_INT_PHY0_DM_GPIO_NUM);
retCode &= perimanClearPinBus(USB_INT_PHY0_DP_GPIO_NUM);
if (retCode) {
// Force the host to re-enumerate (BUS_RESET)
pinMode(USB_DM_GPIO_NUM, OUTPUT_OPEN_DRAIN);
pinMode(USB_DP_GPIO_NUM, OUTPUT_OPEN_DRAIN);
digitalWrite(USB_DM_GPIO_NUM, LOW);
digitalWrite(USB_DP_GPIO_NUM, LOW);
pinMode(USB_INT_PHY0_DM_GPIO_NUM, OUTPUT_OPEN_DRAIN);
pinMode(USB_INT_PHY0_DP_GPIO_NUM, OUTPUT_OPEN_DRAIN);
digitalWrite(USB_INT_PHY0_DM_GPIO_NUM, LOW);
digitalWrite(USB_INT_PHY0_DP_GPIO_NUM, LOW);
}
// release the flag
running = false;
@ -323,11 +323,11 @@ void HWCDC::begin(unsigned long baud) {
// delay(10); // USB Host has to enumerate it again
// Peripheral Manager setting for USB D+ D- pins
uint8_t pin = USB_DM_GPIO_NUM;
uint8_t pin = USB_INT_PHY0_DM_GPIO_NUM;
if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_USB_DM, (void *)this, -1, -1)) {
goto err;
}
pin = USB_DP_GPIO_NUM;
pin = USB_INT_PHY0_DP_GPIO_NUM;
if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_USB_DP, (void *)this, -1, -1)) {
goto err;
}

View file

@ -25,23 +25,37 @@
void serialEvent(void) __attribute__((weak));
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
void serialEvent1(void) __attribute__((weak));
#endif /* SOC_UART_NUM > 1 */
#endif /* SOC_UART_HP_NUM > 1 */
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
void serialEvent2(void) __attribute__((weak));
#endif /* SOC_UART_NUM > 2 */
#endif /* SOC_UART_HP_NUM > 2 */
#if SOC_UART_HP_NUM > 3
void serialEvent3(void) __attribute__((weak));
#endif /* SOC_UART_HP_NUM > 3 */
#if SOC_UART_HP_NUM > 4
void serialEvent4(void) __attribute__((weak));
#endif /* SOC_UART_HP_NUM > 4 */
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
// There is always Seria0 for UART0
HardwareSerial Serial0(0);
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
HardwareSerial Serial1(1);
#endif
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
HardwareSerial Serial2(2);
#endif
#if SOC_UART_HP_NUM > 3
HardwareSerial Serial3(3);
#endif
#if SOC_UART_HP_NUM > 4
HardwareSerial Serial4(4);
#endif
#if HWCDC_SERIAL_IS_DEFINED == 1 // Hardware JTAG CDC Event
extern void HWCDCSerialEvent(void) __attribute__((weak));
@ -67,16 +81,26 @@ void serialEventRun(void) {
if (serialEvent && Serial0.available()) {
serialEvent();
}
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
if (serialEvent1 && Serial1.available()) {
serialEvent1();
}
#endif
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
if (serialEvent2 && Serial2.available()) {
serialEvent2();
}
#endif
#if SOC_UART_HP_NUM > 3
if (serialEvent3 && Serial3.available()) {
serialEvent3();
}
#endif
#if SOC_UART_HP_NUM > 4
if (serialEvent4 && Serial4.available()) {
serialEvent4();
}
#endif
}
#endif
@ -274,8 +298,8 @@ void HardwareSerial::_uartEventTask(void *args) {
}
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd) {
if (_uart_nr >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_NUM - 1);
if (_uart_nr >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_HP_NUM - 1);
return;
}
@ -289,6 +313,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
// map logical pins to GPIO numbers
rxPin = digitalPinToGPIONumber(rxPin);
txPin = digitalPinToGPIONumber(txPin);
int8_t _rxPin = uart_get_RxPin(_uart_nr);
int8_t _txPin = uart_get_TxPin(_uart_nr);
rxPin = rxPin < 0 ? _rxPin : rxPin;
txPin = txPin < 0 ? _txPin : txPin;
HSERIAL_MUTEX_LOCK();
// First Time or after end() --> set default Pins
@ -304,7 +333,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
txPin = _txPin < 0 ? (int8_t)SOC_TX0 : _txPin;
}
break;
#if SOC_UART_NUM > 1 // may save some flash bytes...
#if SOC_UART_HP_NUM > 1 // may save some flash bytes...
case UART_NUM_1:
if (rxPin < 0 && txPin < 0) {
// do not change RX1/TX1 if it has already been set before
@ -313,18 +342,55 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
}
break;
#endif
#if SOC_UART_NUM > 2 // may save some flash bytes...
#if SOC_UART_HP_NUM > 2 // may save some flash bytes...
case UART_NUM_2:
if (rxPin < 0 && txPin < 0) {
// do not change RX2/TX2 if it has already been set before
#ifdef RX2
rxPin = _rxPin < 0 ? (int8_t)RX2 : _rxPin;
#endif
#ifdef TX2
txPin = _txPin < 0 ? (int8_t)TX2 : _txPin;
#endif
}
break;
#endif
#if SOC_UART_HP_NUM > 3 // may save some flash bytes...
case UART_NUM_3:
if (rxPin < 0 && txPin < 0) {
// do not change RX2/TX2 if it has already been set before
#ifdef RX3
rxPin = _rxPin < 0 ? (int8_t)RX3 : _rxPin;
#endif
#ifdef TX3
txPin = _txPin < 0 ? (int8_t)TX3 : _txPin;
#endif
}
break;
#endif
#if SOC_UART_HP_NUM > 4 // may save some flash bytes...
case UART_NUM_4:
if (rxPin < 0 && txPin < 0) {
// do not change RX2/TX2 if it has already been set before
#ifdef RX4
rxPin = _rxPin < 0 ? (int8_t)RX4 : _rxPin;
#endif
#ifdef TX4
txPin = _txPin < 0 ? (int8_t)TX4 : _txPin;
#endif
}
break;
#endif
}
}
// if no RX/TX pins are defined, it will not start the UART driver
if (rxPin < 0 && txPin < 0) {
log_e("No RX/TX pins defined. Please set RX/TX pins.");
HSERIAL_MUTEX_UNLOCK();
return;
}
// IDF UART driver keeps Pin setting on restarting. Negative Pin number will keep it unmodified.
// it will detach previous UART attached pins

View file

@ -125,6 +125,8 @@ typedef enum {
#define SOC_RX0 (gpio_num_t)17
#elif CONFIG_IDF_TARGET_ESP32H2
#define SOC_RX0 (gpio_num_t)23
#elif CONFIG_IDF_TARGET_ESP32P4
#define SOC_RX0 (gpio_num_t)38
#endif
#endif
@ -141,12 +143,14 @@ typedef enum {
#define SOC_TX0 (gpio_num_t)16
#elif CONFIG_IDF_TARGET_ESP32H2
#define SOC_TX0 (gpio_num_t)24
#elif CONFIG_IDF_TARGET_ESP32P4
#define SOC_TX0 (gpio_num_t)37
#endif
#endif
// Default pins for UART1 are arbitrary, and defined here for convenience.
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
#ifndef RX1
#if CONFIG_IDF_TARGET_ESP32
#define RX1 (gpio_num_t)26
@ -162,6 +166,8 @@ typedef enum {
#define RX1 (gpio_num_t)4
#elif CONFIG_IDF_TARGET_ESP32H2
#define RX1 (gpio_num_t)0
#elif CONFIG_IDF_TARGET_ESP32P4
#define RX1 (gpio_num_t)11
#endif
#endif
@ -180,13 +186,15 @@ typedef enum {
#define TX1 (gpio_num_t)5
#elif CONFIG_IDF_TARGET_ESP32H2
#define TX1 (gpio_num_t)1
#elif CONFIG_IDF_TARGET_ESP32P4
#define TX1 (gpio_num_t)10
#endif
#endif
#endif /* SOC_UART_NUM > 1 */
#endif /* SOC_UART_HP_NUM > 1 */
// Default pins for UART2 are arbitrary, and defined here for convenience.
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
#ifndef RX2
#if CONFIG_IDF_TARGET_ESP32
#define RX2 (gpio_num_t)4
@ -202,7 +210,7 @@ typedef enum {
#define TX2 (gpio_num_t)20
#endif
#endif
#endif /* SOC_UART_NUM > 2 */
#endif /* SOC_UART_HP_NUM > 2 */
typedef std::function<void(void)> OnReceiveCb;
typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb;
@ -357,12 +365,18 @@ extern void serialEventRun(void) __attribute__((weak));
#endif // ARDUINO_USB_CDC_ON_BOOT
// There is always Seria0 for UART0
extern HardwareSerial Serial0;
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
extern HardwareSerial Serial1;
#endif
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
extern HardwareSerial Serial2;
#endif
#if SOC_UART_HP_NUM > 3
extern HardwareSerial Serial3;
#endif
#if SOC_UART_HP_NUM > 4
extern HardwareSerial Serial4;
#endif
#endif //!defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
#endif // HardwareSerial_h

View file

@ -22,6 +22,10 @@
#include "lwip/netif.h"
#include "StreamString.h"
#ifndef CONFIG_LWIP_IPV6
#define IP6_NO_ZONE 0
#endif
IPAddress::IPAddress() : IPAddress(IPv4) {}
IPAddress::IPAddress(IPType ip_type) {
@ -201,7 +205,13 @@ bool IPAddress::fromString6(const char *address) {
colons++;
acc = 0;
} else if (c == '%') {
_zone = netif_name_to_index(address);
// netif_index_to_name crashes on latest esp-idf
// _zone = netif_name_to_index(address);
// in the interim, we parse the suffix as a zone number
while ((*address != '\0') && (!isdigit(*address))) { // skip all non-digit after '%'
address++;
}
_zone = atol(address) + 1; // increase by one by convention, so we can have zone '0'
while (*address != '\0') {
address++;
}
@ -344,12 +354,25 @@ size_t IPAddress::printTo(Print &p, bool includeZone) const {
n += p.print(':');
}
}
// add a zone if zone-id is non-zero
// add a zone if zone-id is non-zero (causes exception on recent IDF builds)
// if (_zone > 0 && includeZone) {
// n += p.print('%');
// char if_name[NETIF_NAMESIZE];
// netif_index_to_name(_zone, if_name);
// n += p.print(if_name);
// }
// In the interim, we just output the index number
if (_zone > 0 && includeZone) {
n += p.print('%');
char if_name[NETIF_NAMESIZE];
netif_index_to_name(_zone, if_name);
n += p.print(if_name);
// look for the interface name
for (netif *intf = netif_list; intf != nullptr; intf = intf->next) {
if (_zone - 1 == intf->num) {
n += p.print(intf->name[0]);
n += p.print(intf->name[1]);
break;
}
}
n += p.print(_zone - 1);
}
return n;
}
@ -368,6 +391,7 @@ IPAddress::IPAddress(const ip_addr_t *addr) {
}
void IPAddress::to_ip_addr_t(ip_addr_t *addr) const {
#if CONFIG_LWIP_IPV6
if (_type == IPv6) {
addr->type = IPADDR_TYPE_V6;
addr->u_addr.ip6.addr[0] = _address.dword[0];
@ -381,9 +405,13 @@ void IPAddress::to_ip_addr_t(ip_addr_t *addr) const {
addr->type = IPADDR_TYPE_V4;
addr->u_addr.ip4.addr = _address.dword[IPADDRESS_V4_DWORD_INDEX];
}
#else
addr->addr = _address.dword[IPADDRESS_V4_DWORD_INDEX];
#endif
}
IPAddress &IPAddress::from_ip_addr_t(const ip_addr_t *addr) {
#if CONFIG_LWIP_IPV6
if (addr->type == IPADDR_TYPE_V6) {
_type = IPv6;
_address.dword[0] = addr->u_addr.ip6.addr[0];
@ -394,13 +422,21 @@ IPAddress &IPAddress::from_ip_addr_t(const ip_addr_t *addr) {
_zone = addr->u_addr.ip6.zone;
#endif /* LWIP_IPV6_SCOPES */
} else {
#endif
_type = IPv4;
memset(_address.bytes, 0, sizeof(_address.bytes));
#if CONFIG_LWIP_IPV6
_address.dword[IPADDRESS_V4_DWORD_INDEX] = addr->u_addr.ip4.addr;
#else
_address.dword[IPADDRESS_V4_DWORD_INDEX] = addr->addr;
#endif
#if CONFIG_LWIP_IPV6
}
#endif
return *this;
}
#if CONFIG_LWIP_IPV6
esp_ip6_addr_type_t IPAddress::addr_type() const {
if (_type != IPv6) {
return ESP_IP6_ADDR_IS_UNKNOWN;
@ -409,6 +445,9 @@ esp_ip6_addr_type_t IPAddress::addr_type() const {
to_ip_addr_t(&addr);
return esp_netif_ip6_get_addr_type((esp_ip6_addr_t *)(&(addr.u_addr.ip6)));
}
#endif
#if CONFIG_LWIP_IPV6
const IPAddress IN6ADDR_ANY(IPv6);
#endif
const IPAddress INADDR_NONE(0, 0, 0, 0);

View file

@ -24,6 +24,7 @@
#include "WString.h"
#include "lwip/ip_addr.h"
#include "esp_netif_ip_addr.h"
#include "sdkconfig.h"
#define IPADDRESS_V4_BYTES_INDEX 12
#define IPADDRESS_V4_DWORD_INDEX 3
@ -115,7 +116,9 @@ public:
IPAddress(const ip_addr_t *addr);
void to_ip_addr_t(ip_addr_t *addr) const;
IPAddress &from_ip_addr_t(const ip_addr_t *addr);
#if CONFIG_LWIP_IPV6
esp_ip6_addr_type_t addr_type() const;
#endif
uint8_t zone() const {
return (type() == IPv6) ? _zone : 0;
}

View file

@ -31,7 +31,7 @@ USBCDC *devices[MAX_USB_CDC_DEVICES] = {NULL, NULL};
static uint16_t load_cdc_descriptor(uint8_t *dst, uint8_t *itf) {
uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB CDC");
uint8_t descriptor[TUD_CDC_DESC_LEN] = {// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(*itf, str_index, 0x85, 64, 0x03, 0x84, 64)
TUD_CDC_DESCRIPTOR(*itf, str_index, 0x85, CFG_TUD_ENDOINT_SIZE, 0x03, 0x84, CFG_TUD_ENDOINT_SIZE)
};
*itf += 2;
memcpy(dst, descriptor, TUD_CDC_DESC_LEN);

View file

@ -24,7 +24,7 @@ extern "C" uint16_t tusb_msc_load_descriptor(uint8_t *dst, uint8_t *itf) {
uint8_t ep_num = tinyusb_get_free_duplex_endpoint();
TU_VERIFY(ep_num != 0);
uint8_t descriptor[TUD_MSC_DESC_LEN] = {// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(*itf, str_index, ep_num, (uint8_t)(0x80 | ep_num), 64)
TUD_MSC_DESCRIPTOR(*itf, str_index, ep_num, (uint8_t)(0x80 | ep_num), CFG_TUD_ENDOINT_SIZE)
};
*itf += 1;
memcpy(dst, descriptor, TUD_MSC_DESC_LEN);

View file

@ -64,6 +64,9 @@ static void printPkgVersion(void) {
#elif CONFIG_IDF_TARGET_ESP32H2
uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_MAC_SYS_4_REG, EFUSE_PKG_VERSION);
chip_report_printf("%lu", pkg_ver);
#elif CONFIG_IDF_TARGET_ESP32P4
uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_MAC_SYS_2_REG, EFUSE_PKG_VERSION);
chip_report_printf("%lu", pkg_ver);
#else
chip_report_printf("Unknown");
#endif
@ -84,6 +87,7 @@ static void printChipInfo(void) {
case CHIP_ESP32C3: chip_report_printf("ESP32-C3\n"); break;
case CHIP_ESP32C6: chip_report_printf("ESP32-C6\n"); break;
case CHIP_ESP32H2: chip_report_printf("ESP32-H2\n"); break;
case CHIP_ESP32P4: chip_report_printf("ESP32-P4\n"); break;
default: chip_report_printf("Unknown %d\n", info.model); break;
}
printPkgVersion();
@ -105,6 +109,8 @@ static void printChipInfo(void) {
static void printFlashInfo(void) {
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#define ESP_FLASH_IMAGE_BASE 0x1000
#elif CONFIG_IDF_TARGET_ESP32P4
#define ESP_FLASH_IMAGE_BASE 0x2000
#else
#define ESP_FLASH_IMAGE_BASE 0x0000
#endif

View file

@ -75,7 +75,7 @@ static bool adcDetachBus(void *pin) {
if (err != ESP_OK) {
return false;
}
#elif !defined(CONFIG_IDF_TARGET_ESP32H2)
#elif (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4))
err = adc_cali_delete_scheme_line_fitting(adc_handle[adc_unit].adc_cali_handle);
if (err != ESP_OK) {
return false;
@ -127,7 +127,7 @@ esp_err_t __analogChannelConfig(adc_bitwidth_t width, adc_attenuation_t atten, i
log_e("adc_cali_create_scheme_curve_fitting failed with error: %d", err);
return err;
}
#elif !defined(CONFIG_IDF_TARGET_ESP32H2) //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
#elif (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4)) //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
log_d("Deleting ADC_UNIT_%d line cali handle", adc_unit);
err = adc_cali_delete_scheme_line_fitting(adc_handle[adc_unit].adc_cali_handle);
if (err != ESP_OK) {
@ -310,7 +310,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin) {
.bitwidth = __analogWidth,
};
err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_handle[adc_unit].adc_cali_handle);
#elif !defined(CONFIG_IDF_TARGET_ESP32H2) //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
#elif (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4)) //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
adc_cali_line_fitting_config_t cali_config = {
.unit_id = adc_unit,
.bitwidth = __analogWidth,
@ -379,7 +379,7 @@ static bool adcContinuousDetachBus(void *adc_unit_number) {
if (err != ESP_OK) {
return false;
}
#elif !defined(CONFIG_IDF_TARGET_ESP32H2)
#elif (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4))
err = adc_cali_delete_scheme_line_fitting(adc_handle[adc_unit].adc_cali_handle);
if (err != ESP_OK) {
return false;
@ -552,7 +552,7 @@ bool analogContinuous(const uint8_t pins[], size_t pins_count, uint32_t conversi
.bitwidth = __adcContinuousWidth,
};
err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_handle[adc_unit].adc_cali_handle);
#elif !defined(CONFIG_IDF_TARGET_ESP32H2) //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
#elif (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4)) //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
adc_cali_line_fitting_config_t cali_config = {
.unit_id = adc_unit,
.bitwidth = __adcContinuousWidth,

View file

@ -19,9 +19,9 @@
#include "esp_attr.h"
#include "esp_log.h"
#include "soc/rtc.h"
#if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2)
#if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4)
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
#include "soc/syscon_reg.h"
#endif
#include "soc/efuse_reg.h"
#include "esp32-hal.h"
@ -30,13 +30,13 @@
#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "freertos/xtensa_timer.h"
#include "xtensa_timer.h"
#include "esp32/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "freertos/xtensa_timer.h"
#include "xtensa_timer.h"
#include "esp32s2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "freertos/xtensa_timer.h"
#include "xtensa_timer.h"
#include "esp32s3/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32C2
#include "esp32c2/rom/rtc.h"
@ -46,6 +46,8 @@
#include "esp32c6/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/rtc.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
@ -161,13 +163,13 @@ bool removeApbChangeCallback(void *arg, apb_change_cb_t cb) {
}
static uint32_t calculateApb(rtc_cpu_freq_config_t *conf) {
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2
return APB_CLK_FREQ;
#else
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
if (conf->freq_mhz >= 80) {
return 80 * MHZ;
}
return (conf->source_freq_mhz * MHZ) / conf->div;
#else
return APB_CLK_FREQ;
#endif
}
@ -177,7 +179,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
rtc_cpu_freq_config_t conf, cconf;
uint32_t capb, apb;
//Get XTAL Frequency and calculate min CPU MHz
#ifndef CONFIG_IDF_TARGET_ESP32H2
#if (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4))
rtc_xtal_freq_t xtal = rtc_clk_xtal_freq_get();
#endif
#if CONFIG_IDF_TARGET_ESP32
@ -193,7 +195,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
}
}
#endif
#ifndef CONFIG_IDF_TARGET_ESP32H2
#if (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4))
if (cpu_freq_mhz > xtal && cpu_freq_mhz != 240 && cpu_freq_mhz != 160 && cpu_freq_mhz != 120 && cpu_freq_mhz != 80) {
if (xtal >= RTC_XTAL_FREQ_40M) {
log_e("Bad frequency: %u MHz! Options are: 240, 160, 120, 80, %u, %u and %u MHz", cpu_freq_mhz, xtal, xtal / 2, xtal / 4);
@ -235,7 +237,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
}
//Make the frequency change
rtc_clk_cpu_freq_set_config_fast(&conf);
#if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2)
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)
if (capb != apb) {
//Update REF_TICK (uncomment if REF_TICK is different than 1MHz)
//if(conf.freq_mhz < 80){
@ -248,11 +250,8 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
}
#endif
//Update FreeRTOS Tick Divisor
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#elif CONFIG_IDF_TARGET_ESP32S3
#else
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
uint32_t fcpu = (conf.freq_mhz >= 80) ? (conf.freq_mhz * MHZ) : (apb);
_xt_tick_divisor = fcpu / XT_TICK_PER_SEC;
#endif
@ -260,16 +259,15 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
if (apb_change_callbacks) {
triggerApbChangeCallback(APB_AFTER_CHANGE, capb, apb);
}
#ifdef SOC_CLK_APLL_SUPPORTED
#if defined(SOC_CLK_APLL_SUPPORTED) && !defined(CONFIG_IDF_TARGET_ESP32P4) // APLL not yet supported in ESP32-P4
log_d(
"%s: %u / %u = %u Mhz, APB: %u Hz",
(conf.source == RTC_CPU_FREQ_SRC_PLL) ? "PLL"
: ((conf.source == RTC_CPU_FREQ_SRC_APLL) ? "APLL" : ((conf.source == RTC_CPU_FREQ_SRC_XTAL) ? "XTAL" : "8M")),
(conf.source == SOC_CPU_CLK_SRC_PLL) ? "PLL" : ((conf.source == SOC_CPU_CLK_SRC_APLL) ? "APLL" : ((conf.source == SOC_CPU_CLK_SRC_XTAL) ? "XTAL" : "8M")),
conf.source_freq_mhz, conf.div, conf.freq_mhz, apb
);
#else
log_d(
"%s: %u / %u = %u Mhz, APB: %u Hz", (conf.source == RTC_CPU_FREQ_SRC_PLL) ? "PLL" : ((conf.source == RTC_CPU_FREQ_SRC_XTAL) ? "XTAL" : "17.5M"),
"%s: %u / %u = %u Mhz, APB: %u Hz", (conf.source == SOC_CPU_CLK_SRC_PLL) ? "PLL" : ((conf.source == SOC_CPU_CLK_SRC_XTAL) ? "XTAL" : "17.5M"),
conf.source_freq_mhz, conf.div, conf.freq_mhz, apb
);
#endif

View file

@ -41,21 +41,40 @@
#include "esp_intr_alloc.h"
#include "soc/i2c_reg.h"
#include "soc/i2c_struct.h"
#include "soc/periph_defs.h"
#include "hal/i2c_ll.h"
#include "hal/clk_gate_ll.h"
#include "esp32-hal-log.h"
#include "esp32-hal-i2c-slave.h"
#include "esp32-hal-periman.h"
#include "esp_private/periph_ctrl.h"
#if SOC_PERIPH_CLK_CTRL_SHARED
#define I2C_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define I2C_CLOCK_SRC_ATOMIC()
#endif
#if !SOC_RCC_IS_INDEPENDENT
#define I2C_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define I2C_RCC_ATOMIC()
#endif
#define I2C_SLAVE_USE_RX_QUEUE 0 // 1: Queue, 0: RingBuffer
#if SOC_I2C_NUM > 1
#ifdef CONFIG_IDF_TARGET_ESP32P4
#define I2C_SCL_IDX(p) ((p == 0) ? I2C0_SCL_PAD_OUT_IDX : ((p == 1) ? I2C1_SCL_PAD_OUT_IDX : 0))
#define I2C_SDA_IDX(p) ((p == 0) ? I2C0_SDA_PAD_OUT_IDX : ((p == 1) ? I2C1_SDA_PAD_OUT_IDX : 0))
#else
#if SOC_HP_I2C_NUM > 1
#define I2C_SCL_IDX(p) ((p == 0) ? I2CEXT0_SCL_OUT_IDX : ((p == 1) ? I2CEXT1_SCL_OUT_IDX : 0))
#define I2C_SDA_IDX(p) ((p == 0) ? I2CEXT0_SDA_OUT_IDX : ((p == 1) ? I2CEXT1_SDA_OUT_IDX : 0))
#else
#define I2C_SCL_IDX(p) I2CEXT0_SCL_OUT_IDX
#define I2C_SDA_IDX(p) I2CEXT0_SDA_OUT_IDX
#endif
#endif // ifdef CONFIG_IDF_TARGET_ESP32P4
#if CONFIG_IDF_TARGET_ESP32
#define I2C_TXFIFO_WM_INT_ENA I2C_TXFIFO_EMPTY_INT_ENA
@ -99,14 +118,14 @@ typedef union {
uint32_t val;
} i2c_slave_queue_event_t;
static i2c_slave_struct_t _i2c_bus_array[SOC_I2C_NUM] = {
static i2c_slave_struct_t _i2c_bus_array[SOC_HP_I2C_NUM] = {
{&I2C0, 0, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
#if !CONFIG_DISABLE_HAL_LOCKS
,
NULL
#endif
},
#if SOC_I2C_NUM > 1
#if SOC_HP_I2C_NUM > 1
{&I2C1, 1, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
#if !CONFIG_DISABLE_HAL_LOCKS
,
@ -173,19 +192,19 @@ static inline void i2c_ll_stretch_clr(i2c_dev_t *hw) {
}
static inline bool i2c_ll_slave_addressed(i2c_dev_t *hw) {
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2
return hw->sr.slave_addressed;
#else
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
return hw->status_reg.slave_addressed;
#else
return hw->sr.slave_addressed;
#endif
}
static inline bool i2c_ll_slave_rw(i2c_dev_t *hw) //not exposed by hal_ll
{
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2
return hw->sr.slave_rw;
#else
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
return hw->status_reg.slave_rw;
#else
return hw->sr.slave_rw;
#endif
}
@ -210,7 +229,7 @@ static bool i2cSlaveDetachBus(void *bus_i2c_num);
//=====================================================================================================================
esp_err_t i2cSlaveAttachCallbacks(uint8_t num, i2c_slave_request_cb_t request_callback, i2c_slave_receive_cb_t receive_callback, void *arg) {
if (num >= SOC_I2C_NUM) {
if (num >= SOC_HP_I2C_NUM) {
log_e("Invalid port num: %u", num);
return ESP_ERR_INVALID_ARG;
}
@ -224,7 +243,7 @@ esp_err_t i2cSlaveAttachCallbacks(uint8_t num, i2c_slave_request_cb_t request_ca
}
esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t frequency, size_t rx_len, size_t tx_len) {
if (num >= SOC_I2C_NUM) {
if (num >= SOC_HP_I2C_NUM) {
log_e("Invalid port num: %u", num);
return ESP_ERR_INVALID_ARG;
}
@ -306,17 +325,18 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
frequency = 100000L;
}
frequency = (frequency * 5) / 4;
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
if (i2c->num == 0) {
periph_ll_enable_clk_clear_rst(PERIPH_I2C0_MODULE);
#if SOC_I2C_NUM > 1
#if SOC_HP_I2C_NUM > 1
} else {
periph_ll_enable_clk_clear_rst(PERIPH_I2C1_MODULE);
#endif
}
#endif // !defined(CONFIG_IDF_TARGET_ESP32P4)
i2c_ll_slave_init(i2c->dev);
i2c_ll_set_fifo_mode(i2c->dev, true);
i2c_ll_slave_set_fifo_mode(i2c->dev, true);
i2c_ll_set_slave_addr(i2c->dev, slaveID, false);
i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT);
i2c_slave_set_frequency(i2c, frequency);
@ -337,15 +357,23 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
i2c_ll_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK);
i2c_ll_clear_intr_mask(i2c->dev, I2C_LL_INTR_MASK);
i2c_ll_set_fifo_mode(i2c->dev, true);
i2c_ll_slave_set_fifo_mode(i2c->dev, true);
if (!i2c->intr_handle) {
uint32_t flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED;
if (i2c->num == 0) {
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
ret = esp_intr_alloc(ETS_I2C_EXT0_INTR_SOURCE, flags, &i2c_slave_isr_handler, i2c, &i2c->intr_handle);
#if SOC_I2C_NUM > 1
#else
ret = esp_intr_alloc(ETS_I2C0_INTR_SOURCE, flags, &i2c_slave_isr_handler, i2c, &i2c->intr_handle);
#endif
#if SOC_HP_I2C_NUM > 1
} else {
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
ret = esp_intr_alloc(ETS_I2C_EXT1_INTR_SOURCE, flags, &i2c_slave_isr_handler, i2c, &i2c->intr_handle);
#else
ret = esp_intr_alloc(ETS_I2C1_INTR_SOURCE, flags, &i2c_slave_isr_handler, i2c, &i2c->intr_handle);
#endif
#endif
}
@ -375,7 +403,7 @@ fail:
}
esp_err_t i2cSlaveDeinit(uint8_t num) {
if (num >= SOC_I2C_NUM) {
if (num >= SOC_HP_I2C_NUM) {
log_e("Invalid port num: %u", num);
return ESP_ERR_INVALID_ARG;
}
@ -398,7 +426,7 @@ esp_err_t i2cSlaveDeinit(uint8_t num) {
}
size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t timeout_ms) {
if (num >= SOC_I2C_NUM) {
if (num >= SOC_HP_I2C_NUM) {
log_e("Invalid port num: %u", num);
return 0;
}
@ -515,16 +543,20 @@ static bool i2c_slave_set_frequency(i2c_slave_struct_t *i2c, uint32_t clk_speed)
i2c_hal_clk_config_t clk_cal;
#if SOC_I2C_SUPPORT_APB
i2c_ll_cal_bus_clk(APB_CLK_FREQ, clk_speed, &clk_cal);
i2c_ll_master_cal_bus_clk(APB_CLK_FREQ, clk_speed, &clk_cal);
I2C_CLOCK_SRC_ATOMIC() {
i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_APB); /*!< I2C source clock from APB, 80M*/
}
#elif SOC_I2C_SUPPORT_XTAL
i2c_ll_cal_bus_clk(XTAL_CLK_FREQ, clk_speed, &clk_cal);
i2c_ll_master_cal_bus_clk(XTAL_CLK_FREQ, clk_speed, &clk_cal);
I2C_CLOCK_SRC_ATOMIC() {
i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_XTAL); /*!< I2C source clock from XTAL, 40M */
}
#endif
i2c_ll_set_txfifo_empty_thr(i2c->dev, a);
i2c_ll_set_rxfifo_full_thr(i2c->dev, SOC_I2C_FIFO_LEN - a);
i2c_ll_set_bus_timing(i2c->dev, &clk_cal);
i2c_ll_set_filter(i2c->dev, 3);
i2c_ll_master_set_bus_timing(i2c->dev, &clk_cal);
i2c_ll_master_set_filter(i2c->dev, 3);
return true;
}

View file

@ -29,6 +29,19 @@
#include "hal/i2c_ll.h"
#include "driver/i2c.h"
#include "esp32-hal-periman.h"
#include "esp_private/periph_ctrl.h"
#if SOC_PERIPH_CLK_CTRL_SHARED
#define I2C_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define I2C_CLOCK_SRC_ATOMIC()
#endif
#if !SOC_RCC_IS_INDEPENDENT
#define I2C_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define I2C_RCC_ATOMIC()
#endif
#if SOC_I2C_SUPPORT_APB || SOC_I2C_SUPPORT_XTAL
#include "esp_private/esp_clk.h"
@ -388,7 +401,9 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency) {
periph_rtc_dig_clk8m_enable();
}
#endif
I2C_CLOCK_SRC_ATOMIC() {
i2c_hal_set_bus_timing(&(hal), frequency, i2c_clk_alloc[src_clk].clk, i2c_clk_alloc[src_clk].clk_freq);
}
bus[i2c_num].frequency = frequency;
//Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);

View file

@ -323,11 +323,16 @@ bool ledcOutputInvert(uint8_t pin, bool out_invert) {
ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC);
if (bus != NULL) {
gpio_set_level(pin, out_invert);
#ifdef CONFIG_IDF_TARGET_ESP32P4
esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT_PAD_OUT0_IDX + ((bus->channel) % 8), out_invert, 0);
#else
#ifdef SOC_LEDC_SUPPORT_HS_MODE
esp_rom_gpio_connect_out_signal(pin, ((bus->channel / 8 == 0) ? LEDC_HS_SIG_OUT0_IDX : LEDC_LS_SIG_OUT0_IDX) + ((bus->channel) % 8), out_invert, 0);
#else
esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT0_IDX + ((bus->channel) % 8), out_invert, 0);
#endif
#endif // ifdef CONFIG_IDF_TARGET_ESP32P4
return true;
}
return false;

View file

@ -32,6 +32,8 @@
#include "esp32c6/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/gpio.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif

View file

@ -30,9 +30,9 @@
#endif //CONFIG_BT_ENABLED
#include <sys/time.h>
#include "soc/rtc.h"
#if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2)
#if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4)
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
#include "soc/syscon_reg.h"
#endif
#include "esp_task_wdt.h"
#include "esp32-hal.h"
@ -54,6 +54,8 @@
#include "esp32c6/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/rtc.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
@ -148,14 +150,14 @@ void feedLoopWDT() {
#endif
void enableCore0WDT() {
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCore(0);
if (idle_0 == NULL || esp_task_wdt_add(idle_0) != ESP_OK) {
log_e("Failed to add Core 0 IDLE task to WDT");
}
}
void disableCore0WDT() {
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCore(0);
if (idle_0 == NULL || esp_task_wdt_delete(idle_0) != ESP_OK) {
log_e("Failed to remove Core 0 IDLE task from WDT");
}
@ -163,14 +165,14 @@ void disableCore0WDT() {
#ifndef CONFIG_FREERTOS_UNICORE
void enableCore1WDT() {
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCore(1);
if (idle_1 == NULL || esp_task_wdt_add(idle_1) != ESP_OK) {
log_e("Failed to add Core 1 IDLE task to WDT");
}
}
void disableCore1WDT() {
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCore(1);
if (idle_1 == NULL || esp_task_wdt_delete(idle_1) != ESP_OK) {
log_e("Failed to remove Core 1 IDLE task from WDT");
}
@ -251,7 +253,7 @@ extern bool btInUse();
#endif
#if CONFIG_SPIRAM_SUPPORT || CONFIG_SPIRAM
ESP_SYSTEM_INIT_FN(init_psram_new, BIT(0), 99) {
ESP_SYSTEM_INIT_FN(init_psram_new, CORE, BIT(0), 99) {
psramInit();
return ESP_OK;
}

View file

@ -27,6 +27,8 @@
#include "esp32s2/rom/cache.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/cache.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/cache.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
@ -79,7 +81,7 @@ bool psramInit() {
ESP_EARLY_LOGE(TAG, "PSRAM test failed!");
return false;
}
ESP_EARLY_LOGI(TAG, "PSRAM enabled");
//ESP_EARLY_LOGI(TAG, "PSRAM enabled");
#endif /* CONFIG_SPIRAM_BOOT_INIT */
spiramDetected = true;
return true;

View file

@ -21,7 +21,8 @@ extern "C" {
#include "sdkconfig.h"
#ifndef BOARD_HAS_PSRAM
// Clear flags in Arduino IDE when PSRAM is disabled
#if defined(ESP32_ARDUINO_LIB_BUILDER) && !defined(BOARD_HAS_PSRAM)
#ifdef CONFIG_SPIRAM_SUPPORT
#undef CONFIG_SPIRAM_SUPPORT
#endif

View file

@ -22,11 +22,13 @@
#include "esp_attr.h"
#include "soc/spi_reg.h"
#include "soc/spi_struct.h"
#include "soc/periph_defs.h"
#include "soc/io_mux_reg.h"
#include "soc/gpio_sig_map.h"
#include "soc/rtc.h"
#include "hal/clk_gate_ll.h"
#include "esp32-hal-periman.h"
#include "esp_private/periph_ctrl.h"
#include "esp_system.h"
#include "esp_intr_alloc.h"
@ -55,12 +57,15 @@
#elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/ets_sys.h"
#include "esp32h2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/ets_sys.h"
#include "esp32p4/rom/gpio.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
struct spi_struct_t {
spi_dev_t *dev;
volatile spi_dev_t *dev;
#if !CONFIG_DISABLE_HAL_LOCKS
SemaphoreHandle_t lock;
#endif
@ -96,6 +101,24 @@ struct spi_struct_t {
#define SPI_FSPI_SS_IDX(n) ((n == 0) ? FSPICS0_OUT_IDX : ((n == 1) ? FSPICS1_OUT_IDX : 0))
#define SPI_SS_IDX(p, n) ((p == 0) ? SPI_FSPI_SS_IDX(n) : ((p == 1) ? SPI_HSPI_SS_IDX(n) : 0))
#elif CONFIG_IDF_TARGET_ESP32P4
// ESP32P4
#define SPI_COUNT (2) // SPI2 and SPI3. SPI0 and SPI1 are reserved for flash and PSRAM
#define SPI_CLK_IDX(p) ((p == 0) ? SPI2_CK_PAD_OUT_IDX : ((p == 1) ? SPI3_CK_PAD_OUT_IDX : 0))
#define SPI_MISO_IDX(p) ((p == 0) ? SPI2_Q_PAD_OUT_IDX : ((p == 1) ? SPI3_QO_PAD_OUT_IDX : 0))
#define SPI_MOSI_IDX(p) ((p == 0) ? SPI2_D_PAD_IN_IDX : ((p == 1) ? SPI3_D_PAD_IN_IDX : 0))
#define SPI_HSPI_SS_IDX(n) ((n == 0) ? SPI3_CS_PAD_OUT_IDX : ((n == 1) ? SPI3_CS1_PAD_OUT_IDX : ((n == 2) ? SPI3_CS2_PAD_OUT_IDX : 0)))
#define SPI_FSPI_SS_IDX(n) \
((n == 0) ? SPI2_CS_PAD_OUT_IDX \
: ((n == 1) ? SPI2_CS1_PAD_OUT_IDX \
: ((n == 2) ? SPI2_CS2_PAD_OUT_IDX \
: ((n == 3) ? SPI2_CS3_PAD_OUT_IDX : ((n == 4) ? SPI2_CS4_PAD_OUT_IDX : ((n == 5) ? SPI2_CS5_PAD_OUT_IDX : 0))))))
#define SPI_SS_IDX(p, n) ((p == 0) ? SPI_FSPI_SS_IDX(n) : ((p == 1) ? SPI_HSPI_SS_IDX(n) : 0))
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
// ESP32C3
#define SPI_COUNT (1)
@ -125,14 +148,15 @@ struct spi_struct_t {
#if CONFIG_DISABLE_HAL_LOCKS
#define SPI_MUTEX_LOCK()
#define SPI_MUTEX_UNLOCK()
// clang-format off
static spi_t _spi_bus_array[] = {
#if CONFIG_IDF_TARGET_ESP32S2
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32S3
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32C2
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32C3
@ -146,6 +170,7 @@ static spi_t _spi_bus_array[] = {
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 3, -1, -1, -1, -1}
#endif
};
// clang-format on
#else
#define SPI_MUTEX_LOCK() \
do { \
@ -157,7 +182,7 @@ static spi_t _spi_bus_array[] = {
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32S3
#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 1, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32C2
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1}
@ -369,11 +394,10 @@ void spiEnableSSPins(spi_t *spi, uint8_t ss_mask) {
return;
}
SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.val &= ~(ss_mask & SPI_SS_MASK_ALL);
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.val &= ~(ss_mask & SPI_SS_MASK_ALL);
#else
spi->dev->misc.val &= ~(ss_mask & SPI_SS_MASK_ALL);
#endif
SPI_MUTEX_UNLOCK();
}
@ -383,11 +407,10 @@ void spiDisableSSPins(spi_t *spi, uint8_t ss_mask) {
return;
}
SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.val |= (ss_mask & SPI_SS_MASK_ALL);
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.val |= (ss_mask & SPI_SS_MASK_ALL);
#else
spi->dev->misc.val |= (ss_mask & SPI_SS_MASK_ALL);
#endif
SPI_MUTEX_UNLOCK();
}
@ -417,11 +440,10 @@ void spiSSSet(spi_t *spi) {
return;
}
SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.cs_keep_active = 1;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.cs_keep_active = 1;
#else
spi->dev->misc.cs_keep_active = 1;
#endif
SPI_MUTEX_UNLOCK();
}
@ -431,11 +453,10 @@ void spiSSClear(spi_t *spi) {
return;
}
SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.cs_keep_active = 0;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.cs_keep_active = 0;
#else
spi->dev->misc.cs_keep_active = 0;
#endif
SPI_MUTEX_UNLOCK();
}
@ -460,11 +481,10 @@ uint8_t spiGetDataMode(spi_t *spi) {
if (!spi) {
return 0;
}
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
bool idleEdge = spi->dev->misc.ck_idle_edge;
#else
#if CONFIG_IDF_TARGET_ESP32
bool idleEdge = spi->dev->pin.ck_idle_edge;
#else
bool idleEdge = spi->dev->misc.ck_idle_edge;
#endif
bool outEdge = spi->dev->user.ck_out_edge;
if (idleEdge) {
@ -486,39 +506,35 @@ void spiSetDataMode(spi_t *spi, uint8_t dataMode) {
SPI_MUTEX_LOCK();
switch (dataMode) {
case SPI_MODE1:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 0;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.ck_idle_edge = 0;
#else
spi->dev->misc.ck_idle_edge = 0;
#endif
spi->dev->user.ck_out_edge = 1;
break;
case SPI_MODE2:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 1;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.ck_idle_edge = 1;
#else
spi->dev->misc.ck_idle_edge = 1;
#endif
spi->dev->user.ck_out_edge = 1;
break;
case SPI_MODE3:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 1;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.ck_idle_edge = 1;
#else
spi->dev->misc.ck_idle_edge = 1;
#endif
spi->dev->user.ck_out_edge = 0;
break;
case SPI_MODE0:
default:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 0;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.ck_idle_edge = 0;
#else
spi->dev->misc.ck_idle_edge = 0;
#endif
spi->dev->user.ck_out_edge = 0;
break;
@ -564,11 +580,10 @@ static void spiInitBus(spi_t *spi) {
spi->dev->slave.trans_done = 0;
#endif
spi->dev->slave.val = 0;
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.val = 0;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.val = 0;
#else
spi->dev->misc.val = 0;
#endif
spi->dev->user.val = 0;
spi->dev->user1.val = 0;
@ -648,18 +663,18 @@ spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST);
}
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#elif defined(__PERIPH_CTRL_ALLOW_LEGACY_API)
periph_ll_reset(PERIPH_SPI2_MODULE);
periph_ll_enable_clk_clear_rst(PERIPH_SPI2_MODULE);
#endif
SPI_MUTEX_LOCK();
spiInitBus(spi);
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->clk_gate.clk_en = 1;
spi->dev->clk_gate.mst_clk_sel = 1;
spi->dev->clk_gate.mst_clk_active = 1;
#if !CONFIG_IDF_TARGET_ESP32C6 && !CONFIG_IDF_TARGET_ESP32H2
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3)
spi->dev->dma_conf.tx_seg_trans_clr_en = 1;
spi->dev->dma_conf.rx_seg_trans_clr_en = 1;
spi->dev->dma_conf.dma_seg_trans_en = 0;
@ -670,7 +685,7 @@ spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t
spi->dev->user.doutdin = 1;
int i;
for (i = 0; i < 16; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = 0x00000000;
#else
spi->dev->data_buf[i] = 0x00000000;
@ -697,7 +712,7 @@ void spiWaitReady(spi_t *spi) {
#if CONFIG_IDF_TARGET_ESP32S2
#define usr_mosi_dbitlen usr_mosi_bit_len
#define usr_miso_dbitlen usr_miso_bit_len
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#elif !defined(CONFIG_IDF_TARGET_ESP32)
#define usr_mosi_dbitlen ms_data_bitlen
#define usr_miso_dbitlen ms_data_bitlen
#define mosi_dlen ms_dlen
@ -718,13 +733,13 @@ void spiWrite(spi_t *spi, const uint32_t *data, uint8_t len) {
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
for (i = 0; i < len; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = data[i];
#else
spi->dev->data_buf[i] = data[i];
#endif
}
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -745,20 +760,20 @@ void spiTransfer(spi_t *spi, uint32_t *data, uint8_t len) {
spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1;
for (i = 0; i < len; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = data[i];
#else
spi->dev->data_buf[i] = data[i];
#endif
}
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr);
for (i = 0; i < len; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
data[i] = spi->dev->data_buf[i].val;
#else
data[i] = spi->dev->data_buf[i];
@ -776,13 +791,13 @@ void spiWriteByte(spi_t *spi, uint8_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -798,18 +813,18 @@ uint8_t spiTransferByte(spi_t *spi, uint8_t data) {
SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
data = spi->dev->data_buf[0].val & 0xFF;
#else
data = spi->dev->data_buf[0] & 0xFF;
@ -839,12 +854,12 @@ void spiWriteWord(spi_t *spi, uint16_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -863,18 +878,18 @@ uint16_t spiTransferWord(spi_t *spi, uint16_t data) {
SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
data = spi->dev->data_buf[0].val;
#else
data = spi->dev->data_buf[0];
@ -898,12 +913,12 @@ void spiWriteLong(spi_t *spi, uint32_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -922,18 +937,18 @@ uint32_t spiTransferLong(spi_t *spi, uint32_t data) {
SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
data = spi->dev->data_buf[0].val;
#else
data = spi->dev->data_buf[0];
@ -972,14 +987,14 @@ static void __spiTransferBytes(spi_t *spi, const uint8_t *data, uint8_t *out, ui
spi->dev->miso_dlen.usr_miso_dbitlen = ((bytes * 8) - 1);
for (i = 0; i < words; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = wordsBuf[i]; //copy buffer to spi fifo
#else
spi->dev->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo
#endif
}
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -989,7 +1004,7 @@ static void __spiTransferBytes(spi_t *spi, const uint8_t *data, uint8_t *out, ui
if (out) {
for (i = 0; i < words; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
wordsBuf[i] = spi->dev->data_buf[i].val; //copy spi fifo to buffer
#else
wordsBuf[i] = spi->dev->data_buf[i]; //copy spi fifo to buffer
@ -1061,39 +1076,35 @@ void spiTransaction(spi_t *spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bit
spi->dev->clock.val = clockDiv;
switch (dataMode) {
case SPI_MODE1:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 0;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.ck_idle_edge = 0;
#else
spi->dev->misc.ck_idle_edge = 0;
#endif
spi->dev->user.ck_out_edge = 1;
break;
case SPI_MODE2:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 1;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.ck_idle_edge = 1;
#else
spi->dev->misc.ck_idle_edge = 1;
#endif
spi->dev->user.ck_out_edge = 1;
break;
case SPI_MODE3:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 1;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.ck_idle_edge = 1;
#else
spi->dev->misc.ck_idle_edge = 1;
#endif
spi->dev->user.ck_out_edge = 0;
break;
case SPI_MODE0:
default:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 0;
#else
#if CONFIG_IDF_TARGET_ESP32
spi->dev->pin.ck_idle_edge = 0;
#else
spi->dev->misc.ck_idle_edge = 0;
#endif
spi->dev->user.ck_out_edge = 0;
break;
@ -1105,7 +1116,7 @@ void spiTransaction(spi_t *spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bit
spi->dev->ctrl.wr_bit_order = 1;
spi->dev->ctrl.rd_bit_order = 1;
}
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
// Sync new config with hardware, fixes https://github.com/espressif/arduino-esp32/issues/9221
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
@ -1134,12 +1145,12 @@ void ARDUINO_ISR_ATTR spiWriteByteNL(spi_t *spi, uint8_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -1153,18 +1164,18 @@ uint8_t spiTransferByteNL(spi_t *spi, uint8_t data) {
}
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
data = spi->dev->data_buf[0].val & 0xFF;
#else
data = spi->dev->data_buf[0] & 0xFF;
@ -1183,12 +1194,12 @@ void ARDUINO_ISR_ATTR spiWriteShortNL(spi_t *spi, uint16_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -1205,18 +1216,18 @@ uint16_t spiTransferShortNL(spi_t *spi, uint16_t data) {
}
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
data = spi->dev->data_buf[0].val & 0xFFFF;
#else
data = spi->dev->data_buf[0] & 0xFFFF;
@ -1238,12 +1249,12 @@ void ARDUINO_ISR_ATTR spiWriteLongNL(spi_t *spi, uint32_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -1260,18 +1271,18 @@ uint32_t spiTransferLongNL(spi_t *spi, uint32_t data) {
}
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
data = spi->dev->data_buf[0].val;
#else
data = spi->dev->data_buf[0];
@ -1302,13 +1313,13 @@ void spiWriteNL(spi_t *spi, const void *data_in, uint32_t len) {
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif
for (size_t i = 0; i < c_longs; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = data[i];
#else
spi->dev->data_buf[i] = data[i];
#endif
}
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -1341,7 +1352,7 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
spi->dev->miso_dlen.usr_miso_dbitlen = (c_len * 8) - 1;
if (data) {
for (size_t i = 0; i < c_longs; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = data[i];
#else
spi->dev->data_buf[i] = data[i];
@ -1349,14 +1360,14 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
}
} else {
for (size_t i = 0; i < c_longs; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = 0xFFFFFFFF;
#else
spi->dev->data_buf[i] = 0xFFFFFFFF;
#endif
}
}
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -1365,13 +1376,13 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
if (result) {
if (c_len & 3) {
for (size_t i = 0; i < (c_longs - 1); i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
result[i] = spi->dev->data_buf[i].val;
#else
result[i] = spi->dev->data_buf[i];
#endif
}
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
uint32_t last_data = spi->dev->data_buf[c_longs - 1].val;
#else
uint32_t last_data = spi->dev->data_buf[c_longs - 1];
@ -1383,7 +1394,7 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
}
} else {
for (size_t i = 0; i < c_longs; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
result[i] = spi->dev->data_buf[i].val;
#else
result[i] = spi->dev->data_buf[i];
@ -1425,18 +1436,18 @@ void spiTransferBitsNL(spi_t *spi, uint32_t data, uint32_t *out, uint8_t bits) {
spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1);
spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[0].val = data;
#else
spi->dev->data_buf[0] = data;
#endif
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
data = spi->dev->data_buf[0].val;
#else
data = spi->dev->data_buf[0];
@ -1477,34 +1488,34 @@ void ARDUINO_ISR_ATTR spiWritePixelsNL(spi_t *spi, const void *data_in, uint32_t
if (msb) {
if (l_bytes && i == (c_longs - 1)) {
if (l_bytes == 2) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
MSB_16_SET(spi->dev->data_buf[i].val, data[i]);
#else
MSB_16_SET(spi->dev->data_buf[i], data[i]);
#endif
} else {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = data[i] & 0xFF;
#else
spi->dev->data_buf[i] = data[i] & 0xFF;
#endif
}
} else {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
MSB_PIX_SET(spi->dev->data_buf[i].val, data[i]);
#else
MSB_PIX_SET(spi->dev->data_buf[i], data[i]);
#endif
}
} else {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
spi->dev->data_buf[i].val = data[i];
#else
spi->dev->data_buf[i] = data[i];
#endif
}
}
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
@ -1528,7 +1539,7 @@ typedef union {
uint32_t clkcnt_l : 6; /*it must be equal to spi_clkcnt_N.*/
uint32_t clkcnt_h : 6; /*it must be floor((spi_clkcnt_N+1)/2-1).*/
uint32_t clkcnt_n : 6; /*it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
uint32_t clkdiv_pre : 4; /*it is pre-divider of spi_clk.*/
uint32_t reserved : 9; /*reserved*/
#else
@ -1573,7 +1584,7 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq) {
while (calPreVari++ <= 1) {
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
if (calPre > 0xF) {
reg.clkdiv_pre = 0xF;
#else

View file

@ -28,10 +28,7 @@ extern "C" {
#define SPI_HAS_TRANSACTION
#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32S3
#define FSPI 0
#define HSPI 1
#elif CONFIG_IDF_TARGET_ESP32S2
#ifdef CONFIG_IDF_TARGET_ESP32S2
#define FSPI 1 //SPI 1 bus. ESP32S2: for external memory only (can use the same data lines but different SS)
#define HSPI 2 //SPI 2 bus. ESP32S2: external memory or device - it can be matrixed to any pins
#define SPI2 2 // Another name for ESP32S2 SPI 2
@ -40,6 +37,9 @@ extern "C" {
#define FSPI 1 //SPI 1 bus attached to the flash (can use the same data lines but different SS)
#define HSPI 2 //SPI 2 bus normally mapped to pins 12 - 15, but can be matrixed to any pins
#define VSPI 3 //SPI 3 bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
#else
#define FSPI 0
#define HSPI 1
#endif
// This defines are not representing the real Divider of the ESP32

View file

@ -10,12 +10,15 @@
#include "soc/soc.h"
#include "soc/efuse_reg.h"
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#include "soc/rtc_cntl_reg.h"
#include "soc/usb_struct.h"
#include "soc/usb_reg.h"
#include "soc/usb_wrap_reg.h"
#include "soc/usb_wrap_struct.h"
#include "soc/usb_periph.h"
#endif
#include "soc/periph_defs.h"
#include "soc/timer_group_struct.h"
#include "soc/system_reg.h"
@ -34,8 +37,8 @@
#include "esp32-hal.h"
#include "esp32-hal-periman.h"
#include "esp32-hal-tinyusb.h"
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/usb/usb_persist.h"
#include "esp32s2/rom/usb/usb_dc.h"
@ -50,6 +53,7 @@
#include "esp32s3/rom/usb/usb_persist.h"
#include "esp32s3/rom/usb/usb_dc.h"
#include "esp32s3/rom/usb/chip_usb_dw_wrapper.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#endif
typedef enum {
@ -127,7 +131,11 @@ esp_err_t init_usb_hal(bool external_phy) {
.controller = USB_PHY_CTRL_OTG,
.target = USB_PHY_TARGET_INT,
.otg_mode = USB_OTG_MODE_DEVICE,
#if CONFIG_IDF_TARGET_ESP32P4
.otg_speed = USB_PHY_SPEED_HIGH,
#else
.otg_speed = USB_PHY_SPEED_FULL,
#endif
.ext_io_conf = NULL,
.otg_io_conf = NULL,
};
@ -165,7 +173,16 @@ void deinit_usb_hal() {
esp_err_t tinyusb_driver_install(const tinyusb_config_t *config) {
init_usb_hal(config->external_phy);
if (!tusb_init()) {
tusb_rhport_init_t tinit;
memset(&tinit, 0, sizeof(tusb_rhport_init_t));
tinit.role = TUSB_ROLE_DEVICE;
#if CONFIG_IDF_TARGET_ESP32P4
tinit.speed = TUSB_SPEED_HIGH;
if (!tusb_init(1, &tinit)) {
#else
tinit.speed = TUSB_SPEED_FULL;
if (!tusb_init(0, &tinit)) {
#endif
log_e("Can't initialize the TinyUSB stack.");
return ESP_FAIL;
}
@ -275,8 +292,7 @@ enum {
VENDOR_REQUEST_MICROSOFT = 2
};
static uint8_t const tinyusb_bos_descriptor[] = {
// total length, number of device caps
static uint8_t const tinyusb_bos_descriptor[] = {// total length, number of device caps
TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2),
// Vendor Code, iLandingPage
@ -467,8 +483,10 @@ __attribute__((weak)) void tud_network_init_cb(void) {}
/*
* Private API
* */
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
static bool usb_persist_enabled = false;
static restart_type_t usb_persist_mode = RESTART_NO_PERSIST;
#endif
#if CONFIG_IDF_TARGET_ESP32S3
@ -549,6 +567,7 @@ static void usb_switch_to_cdc_jtag() {
}
#endif
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
static void IRAM_ATTR usb_persist_shutdown_handler(void) {
if (usb_persist_mode != RESTART_NO_PERSIST) {
if (usb_persist_enabled) {
@ -580,8 +599,10 @@ static void IRAM_ATTR usb_persist_shutdown_handler(void) {
}
}
}
#endif
void usb_persist_restart(restart_type_t mode) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
if (mode < RESTART_TYPE_MAX && esp_register_shutdown_handler(usb_persist_shutdown_handler) == ESP_OK) {
usb_persist_mode = mode;
#if CONFIG_IDF_TARGET_ESP32S3
@ -591,6 +612,7 @@ void usb_persist_restart(restart_type_t mode) {
#endif
esp_restart();
}
#endif
}
static bool tinyusb_reserve_in_endpoint(uint8_t endpoint) {
@ -674,8 +696,13 @@ static inline char nibble_to_hex_char(uint8_t b) {
static void set_usb_serial_num(void) {
/* Get the MAC address */
#if CONFIG_IDF_TARGET_ESP32P4
const uint32_t mac0 = REG_GET_FIELD(EFUSE_RD_MAC_SYS_0_REG, EFUSE_MAC_0);
const uint32_t mac1 = REG_GET_FIELD(EFUSE_RD_MAC_SYS_0_REG, EFUSE_MAC_1);
#else
const uint32_t mac0 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_0_REG, EFUSE_MAC_0);
const uint32_t mac1 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_1_REG, EFUSE_MAC_1);
#endif
uint8_t mac_bytes[6];
memcpy(mac_bytes, &mac0, 4);
memcpy(mac_bytes + 4, &mac1, 2);
@ -794,6 +821,7 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
return ESP_FAIL;
}
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
bool usb_did_persist = (USB_WRAP.date.val == USBDC_PERSIST_ENA);
//if(usb_did_persist && usb_persist_enabled){
@ -806,6 +834,7 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
periph_ll_reset(PERIPH_USB_MODULE);
periph_ll_enable_clk_clear_rst(PERIPH_USB_MODULE);
}
#endif
tinyusb_config_t tusb_cfg = {
.external_phy = false // In the most cases you need to use a `false` value

View file

@ -31,6 +31,14 @@ extern "C" {
#define USB_ESPRESSIF_VID 0x303A
#define USB_STRING_DESCRIPTOR_ARRAY_SIZE 10
#ifndef CFG_TUD_ENDOINT_SIZE
#if CONFIG_IDF_TARGET_ESP32P4
#define CFG_TUD_ENDOINT_SIZE 512
#else
#define CFG_TUD_ENDOINT_SIZE 64
#endif
#endif
typedef struct {
uint16_t vid;
uint16_t pid;

View file

@ -0,0 +1,453 @@
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "soc/soc_caps.h"
#if SOC_TOUCH_SENSOR_SUPPORTED
#if SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 for now
#include "driver/touch_sens.h"
#include "esp32-hal-touch-ng.h"
#include "esp32-hal-periman.h"
/*
Internal Private Touch Data Structure and Functions
*/
typedef void (*voidFuncPtr)(void);
typedef void (*voidArgFuncPtr)(void *);
typedef struct {
voidFuncPtr fn;
bool callWithArgs;
void *arg;
bool lastStatusIsPressed;
} TouchInterruptHandle_t;
static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = {
0,
};
static uint8_t _sample_num = 1;
static uint32_t _div_num = 1;
static uint8_t _coarse_freq_tune = 1;
static uint8_t _fine_freq_tune = 1;
static uint8_t used_pads = 0;
static uint32_t __touchSleepTime = 256;
static float __touchMeasureTime = 32.0f;
static touch_sensor_config_t sensor_config;
static bool initialized = false;
static bool enabled = false;
static bool running = false;
static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = {false};
static touch_sensor_handle_t touch_sensor_handle = NULL;
static touch_channel_handle_t touch_channel_handle[SOC_TOUCH_SENSOR_NUM] = {};
// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio))
static float s_thresh2bm_ratio = 0.015f; // 1.5% for all channels
static bool ARDUINO_ISR_ATTR __touchOnActiveISR(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx) {
uint8_t pad_num = (uint8_t)event->chan_id;
__touchInterruptHandlers[pad_num].lastStatusIsPressed = true;
if (__touchInterruptHandlers[pad_num].fn) {
// keeping backward compatibility with "void cb(void)" and with new "void cb(void *)"
if (__touchInterruptHandlers[pad_num].callWithArgs) {
((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg);
} else {
__touchInterruptHandlers[pad_num].fn();
}
}
return false;
}
static bool ARDUINO_ISR_ATTR __touchOnInactiveISR(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx) {
uint8_t pad_num = (uint8_t)event->chan_id;
__touchInterruptHandlers[pad_num].lastStatusIsPressed = false;
if (__touchInterruptHandlers[pad_num].fn) {
// keeping backward compatibility with "void cb(void)" and with new "void cb(void *)"
if (__touchInterruptHandlers[pad_num].callWithArgs) {
((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg);
} else {
__touchInterruptHandlers[pad_num].fn();
}
}
return false;
}
bool touchStop() {
if (!running) { // Already stopped
return true;
}
if (touch_sensor_stop_continuous_scanning(touch_sensor_handle) != ESP_OK) {
log_e("Touch sensor stop scanning failed!");
return false;
}
running = false;
return true;
}
bool touchDisable() {
if (!enabled) { // Already disabled
return true;
}
if (!running && (touch_sensor_disable(touch_sensor_handle) != ESP_OK)) {
log_e("Touch sensor still running or disable failed!");
return false;
}
enabled = false;
return true;
}
bool touchStart() {
if (running) { // Already running
return true;
}
if (enabled && (touch_sensor_start_continuous_scanning(touch_sensor_handle) != ESP_OK)) {
log_e("Touch sensor not enabled or failed to start continuous scanning failed!");
return false;
}
running = true;
return true;
}
bool touchEnable() {
if (enabled) { // Already enabled
return true;
}
if (touch_sensor_enable(touch_sensor_handle) != ESP_OK) {
log_e("Touch sensor enable failed!");
return false;
}
enabled = true;
return true;
}
bool touchBenchmarkThreshold(uint8_t pad) {
if (!touchEnable()) {
return false;
}
/* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */
for (int i = 0; i < 3; i++) {
if (touch_sensor_trigger_oneshot_scanning(touch_sensor_handle, 2000) != ESP_OK) {
log_e("Touch sensor trigger oneshot scanning failed!");
return false;
}
}
/* Disable the touch channel to rollback the state */
if (!touchDisable()) {
return false;
}
// Reconfigure passed pad with new threshold
uint32_t benchmark[_sample_num] = {};
if (touch_channel_read_data(touch_channel_handle[pad], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark) != ESP_OK) {
log_e("Touch channel read data failed!");
return false;
}
/* Calculate the proper active thresholds regarding the initial benchmark */
touch_channel_config_t chan_cfg = {};
for (int i = 0; i < _sample_num; i++) {
chan_cfg.active_thresh[i] = (uint32_t)(benchmark[i] * s_thresh2bm_ratio);
log_v("Configured [CH %d] sample %d: benchmark = %" PRIu32 ", threshold = %" PRIu32 "\t", pad, i, benchmark[i], chan_cfg.active_thresh[i]);
}
/* Update the channel configuration */
if (touch_sensor_reconfig_channel(touch_channel_handle[pad], &chan_cfg) != ESP_OK) {
log_e("Touch sensor threshold reconfig channel failed!");
return false;
}
return true;
}
static bool touchDetachBus(void *pin) {
int8_t pad = digitalPinToTouchChannel((int)(pin - 1));
channels_initialized[pad] = false;
//disable touch pad and delete the channel
touch_sensor_del_channel(touch_channel_handle[pad]);
used_pads--;
if (used_pads == 0) {
touchStop();
touchDisable();
if (touch_sensor_del_controller(touch_sensor_handle) != ESP_OK) //deinit touch module, as no pads are used
{
log_e("Touch module deinit failed!");
return false;
}
initialized = false;
}
return true;
}
static void __touchInit() {
if (initialized) {
return;
}
// Support only one sample configuration for now
touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_div_num, _coarse_freq_tune, _fine_freq_tune);
touch_sensor_sample_config_t sample_cfg[_sample_num] = {};
sample_cfg[0] = single_sample_cfg;
/* Allocate new touch controller handle */
touch_sensor_config_t sens_cfg = {
.power_on_wait_us = __touchSleepTime,
.meas_interval_us = __touchMeasureTime,
.max_meas_time_us = 0,
.output_mode = TOUCH_PAD_OUT_AS_CLOCK,
.sample_cfg_num = _sample_num,
.sample_cfg = sample_cfg,
};
// touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(_sample_num, sample_cfg);
if (touch_sensor_new_controller(&sens_cfg, &touch_sensor_handle) != ESP_OK) {
goto err;
}
sensor_config = sens_cfg;
/* Configure the touch sensor filter */
touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG();
if (touch_sensor_config_filter(touch_sensor_handle, &filter_cfg) != ESP_OK) {
goto err;
}
/* Register the touch sensor on_active and on_inactive callbacks */
touch_event_callbacks_t callbacks = {
.on_active = __touchOnActiveISR,
.on_inactive = __touchOnInactiveISR,
.on_measure_done = NULL,
.on_scan_done = NULL,
.on_timeout = NULL,
.on_proximity_meas_done = NULL,
};
if (touch_sensor_register_callbacks(touch_sensor_handle, &callbacks, NULL) != ESP_OK) {
goto err;
}
initialized = true;
return;
err:
log_e(" Touch sensor initialization error.");
initialized = false;
return;
}
static void __touchChannelInit(int pad) {
if (channels_initialized[pad]) {
return;
}
// Initial setup with default Threshold
__touchInterruptHandlers[pad].fn = NULL;
touch_channel_config_t chan_cfg = {
.active_thresh = {1000} // default threshold, will be updated after benchmark
};
if (!touchStop() || !touchDisable()) {
log_e("Touch sensor stop and disable failed!");
return;
}
if (touch_sensor_new_channel(touch_sensor_handle, pad, &chan_cfg, &touch_channel_handle[pad]) != ESP_OK) {
log_e("Touch sensor new channel failed!");
return;
}
// Benchmark active threshold and reconfigure pad
if (!touchBenchmarkThreshold(pad)) {
log_e("Touch sensor benchmark threshold failed!");
return;
}
channels_initialized[pad] = true;
used_pads++;
if (!touchEnable() || !touchStart()) {
log_e("Touch sensor enable and start failed!");
}
}
static touch_value_t __touchRead(uint8_t pin) {
int8_t pad = digitalPinToTouchChannel(pin);
if (pad < 0) {
log_e(" No touch pad on selected pin!");
return 0;
}
if (perimanGetPinBus(pin, ESP32_BUS_TYPE_TOUCH) == NULL) {
perimanSetBusDeinit(ESP32_BUS_TYPE_TOUCH, touchDetachBus);
if (!perimanClearPinBus(pin)) {
return 0;
}
__touchInit();
__touchChannelInit(pad);
if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_TOUCH, (void *)(pin + 1), -1, pad)) {
touchDetachBus((void *)(pin + 1));
return 0;
}
}
uint32_t touch_read[_sample_num] = {};
touch_channel_read_data(touch_channel_handle[pad], TOUCH_CHAN_DATA_TYPE_SMOOTH, touch_read);
touch_value_t touch_value = touch_read[0]; // only one sample configuration for now
return touch_value;
}
static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Args, bool callWithArgs, touch_value_t threshold) {
int8_t pad = digitalPinToTouchChannel(pin);
if (pad < 0) {
log_e(" No touch pad on selected pin!");
return;
}
if (userFunc == NULL) {
// detach ISR User Call
__touchInterruptHandlers[pad].fn = NULL;
__touchInterruptHandlers[pad].callWithArgs = false;
__touchInterruptHandlers[pad].arg = NULL;
} else {
// attach ISR User Call
__touchInit();
__touchChannelInit(pad);
__touchInterruptHandlers[pad].fn = userFunc;
__touchInterruptHandlers[pad].callWithArgs = callWithArgs;
__touchInterruptHandlers[pad].arg = Args;
}
if (threshold != 0) {
if (!touchStop() || !touchDisable()) {
log_e("Touch sensor stop and disable failed!");
return;
}
touch_channel_config_t chan_cfg = {};
for (int i = 0; i < _sample_num; i++) {
chan_cfg.active_thresh[i] = threshold;
}
if (touch_sensor_reconfig_channel(touch_channel_handle[pad], &chan_cfg) != ESP_OK) {
log_e("Touch sensor threshold reconfig channel failed!");
}
if (!touchEnable() || !touchStart()) {
log_e("Touch sensor enable and start failed!");
}
}
}
// it keeps backwards compatibility
static void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold) {
__touchConfigInterrupt(pin, userFunc, NULL, threshold, false);
}
// new additional version of the API with User Args
static void __touchAttachArgsInterrupt(uint8_t pin, void (*userFunc)(void), void *args, touch_value_t threshold) {
__touchConfigInterrupt(pin, userFunc, args, threshold, true);
}
// new additional API to detach touch ISR
static void __touchDettachInterrupt(uint8_t pin) {
__touchConfigInterrupt(pin, NULL, NULL, 0, false); // userFunc as NULL acts as detaching
}
// /*
// External Public Touch API Functions
// */
bool touchInterruptGetLastStatus(uint8_t pin) {
int8_t pad = digitalPinToTouchChannel(pin);
if (pad < 0) {
return false;
}
return __touchInterruptHandlers[pad].lastStatusIsPressed;
}
void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold) {
int8_t pad = digitalPinToTouchChannel(pin);
if (pad < 0) {
log_e(" No touch pad on selected pin!");
return;
}
if (perimanGetPinBus(pin, ESP32_BUS_TYPE_TOUCH) == NULL) {
perimanSetBusDeinit(ESP32_BUS_TYPE_TOUCH, touchDetachBus);
__touchInit();
__touchChannelInit(pad);
if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_TOUCH, (void *)(pin + 1), -1, pad)) {
log_e("Failed to set bus to Peripheral manager");
touchDetachBus((void *)(pin + 1));
return;
}
}
log_v("Touch sensor deep sleep wake-up configuration for pad %d with threshold %d", pad, threshold);
if (!touchStop() || !touchDisable()) {
log_e("Touch sensor stop and disable failed!");
return;
}
touch_sleep_config_t deep_slp_cfg = {
.slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP,
.deep_slp_chan = touch_channel_handle[pad],
.deep_slp_thresh = {threshold},
.deep_slp_sens_cfg = NULL, // Use the original touch sensor configuration
};
// Register the deep sleep wake-up
if (touch_sensor_config_sleep_wakeup(touch_sensor_handle, &deep_slp_cfg) != ESP_OK) {
log_e("Touch sensor deep sleep wake-up failed!");
return;
}
if (!touchEnable() || !touchStart()) {
log_e("Touch sensor enable and start failed!");
}
}
void touchSetDefaultThreshold(float percentage) {
s_thresh2bm_ratio = (float)percentage / 100.0f;
}
void touchSetTiming(float measure, uint32_t sleep) {
if (initialized) {
log_e("Touch sensor already initialized. Cannot set cycles.");
return;
}
__touchSleepTime = sleep;
__touchMeasureTime = measure;
}
void touchSetConfig(uint32_t div_num, uint8_t coarse_freq_tune, uint8_t fine_freq_tune) {
if (initialized) {
log_e("Touch sensor already initialized. Cannot set configuration.");
return;
}
_div_num = div_num;
_coarse_freq_tune = coarse_freq_tune;
_fine_freq_tune = fine_freq_tune;
}
extern touch_value_t touchRead(uint8_t) __attribute__((weak, alias("__touchRead")));
extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribute__((weak, alias("__touchAttachInterrupt")));
extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__((weak, alias("__touchAttachArgsInterrupt")));
extern void touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDettachInterrupt")));
#endif /* SOC_TOUCH_SENSOR_VERSION == 3 */
#endif /* SOC_TOUCH_SENSOR_SUPPORTED */

View file

@ -0,0 +1,91 @@
/*
Arduino.h - Main include file for the Arduino SDK
Copyright (c) 2005-2013 Arduino Team. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MAIN_ESP32_HAL_TOUCH_NEW_H_
#define MAIN_ESP32_HAL_TOUCH_NEW_H_
#include "soc/soc_caps.h"
#if SOC_TOUCH_SENSOR_SUPPORTED
#if SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4
#ifdef __cplusplus
extern "C" {
#endif
#include "esp32-hal.h"
typedef uint32_t touch_value_t;
/*
* Set time in us that measurement operation takes
* The result from touchRead, threshold and detection
* accuracy depend on these values.
* Note: must be called before setting up touch pads
**/
void touchSetTiming(float measure, uint32_t sleep);
/*
* Tune the touch pad frequency.
* Note: Must be called before setting up touch pads
*/
void touchSetConfig(uint32_t _div_num, uint8_t coarse_freq_tune, uint8_t fine_freq_tune);
/*
* Read touch pad value.
* You can use this method to chose a good threshold value
* to use as value for touchAttachInterrupt.
* */
touch_value_t touchRead(uint8_t pin);
/*
* Set function to be called if touch pad value rises by given increment (threshold).
* Use touchRead to determine a proper threshold between touched and untouched state.
* */
void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold);
void touchAttachInterruptArg(uint8_t pin, void (*userFunc)(void *), void *arg, touch_value_t threshold);
void touchDetachInterrupt(uint8_t pin);
/*
* Returns true when the latest ISR status for the Touchpad is that it is touched (Active)
* and false when the Touchpad is untoouched (Inactive).
* This function can be used in conjunction with ISR User callback in order to take action
* as soon as the touchpad is touched and/or released.
**/
bool touchInterruptGetLastStatus(uint8_t pin);
/*
* Set the default threshold for touch pads.
* The threshold is a percentage of the benchmark value.
* The default value is 1.5%.
**/
void touchSetDefaultThreshold(float percentage);
/*
* Setup touch pad wake up from deep sleep /light sleep with given threshold.
* When light sleep is used, all used touch pads will be able to wake up the chip.
**/
void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold);
#ifdef __cplusplus
}
#endif
#endif /* SOC_TOUCH_SENSOR_VERSION == 3 */
#endif /* SOC_TOUCH_SENSOR_SUPPORTED */
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */

View file

@ -14,6 +14,8 @@
#include "soc/soc_caps.h"
#if SOC_TOUCH_SENSOR_SUPPORTED
#if SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32, ESP32S2, ESP32S3
#include "driver/touch_sensor.h"
#include "esp32-hal-touch.h"
#include "esp32-hal-periman.h"
@ -22,10 +24,10 @@
Internal Private Touch Data Structure and Functions
*/
#if SOC_TOUCH_VERSION_1 // ESP32
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
static uint16_t __touchSleepCycles = 0x1000;
static uint16_t __touchMeasureCycles = 0x1000;
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
static uint16_t __touchSleepCycles = TOUCH_PAD_SLEEP_CYCLE_DEFAULT;
static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT;
#endif
@ -37,7 +39,7 @@ typedef struct {
voidFuncPtr fn;
bool callWithArgs;
void *arg;
#if SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
#if SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3
bool lastStatusIsPressed;
#endif
} TouchInterruptHandle_t;
@ -51,7 +53,7 @@ static bool initialized = false;
static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = {false};
static void ARDUINO_ISR_ATTR __touchISR(void *arg) {
#if SOC_TOUCH_VERSION_1 // ESP32
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
uint32_t pad_intr = touch_pad_get_status();
//clear interrupt
touch_pad_clear_status();
@ -68,7 +70,7 @@ static void ARDUINO_ISR_ATTR __touchISR(void *arg) {
}
}
}
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
touch_pad_intr_mask_t evt = touch_pad_read_intr_status_mask();
uint8_t pad_num = touch_pad_get_current_meas_channel();
if (evt & TOUCH_PAD_INTR_MASK_ACTIVE) {
@ -93,9 +95,9 @@ static void ARDUINO_ISR_ATTR __touchISR(void *arg) {
static void __touchSetCycles(uint16_t measure, uint16_t sleep) {
__touchSleepCycles = sleep;
__touchMeasureCycles = measure;
#if SOC_TOUCH_VERSION_1 // ESP32
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
touch_pad_set_measurement_clock_cycles(measure);
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
touch_pad_set_charge_discharge_times(measure);
#endif
touch_pad_set_measurement_interval(sleep);
@ -123,7 +125,7 @@ static void __touchInit() {
esp_err_t err = ESP_OK;
#if SOC_TOUCH_VERSION_1 // ESP32
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
err = touch_pad_init();
if (err != ESP_OK) {
goto err;
@ -144,7 +146,7 @@ static void __touchInit() {
goto err;
}
touch_pad_intr_enable(); // returns ESP_OK
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
err = touch_pad_init();
if (err != ESP_OK) {
goto err;
@ -165,7 +167,6 @@ static void __touchInit() {
touch_pad_fsm_start(); // returns ESP_OK
//ISR setup moved to __touchChannelInit
#endif
initialized = true;
return;
err:
@ -179,11 +180,11 @@ static void __touchChannelInit(int pad) {
return;
}
#if SOC_TOUCH_VERSION_1 // ESP32
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
// Initial no Threshold and setup
__touchInterruptHandlers[pad].fn = NULL;
touch_pad_config(pad, SOC_TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
touch_pad_config(pad, TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
// Initial no Threshold and setup
__touchInterruptHandlers[pad].fn = NULL;
touch_pad_config(pad); // returns ESP_OK
@ -238,7 +239,7 @@ static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Ar
if (userFunc == NULL) {
// detach ISR User Call
__touchInterruptHandlers[pad].fn = NULL;
threshold = SOC_TOUCH_PAD_THRESHOLD_MAX; // deactivate the ISR with SOC_TOUCH_PAD_THRESHOLD_MAX
threshold = TOUCH_PAD_THRESHOLD_MAX; // deactivate the ISR with SOC_TOUCH_PAD_THRESHOLD_MAX
} else {
// attach ISR User Call
__touchInit();
@ -270,7 +271,7 @@ static void __touchDettachInterrupt(uint8_t pin) {
External Public Touch API Functions
*/
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC
void touchInterruptSetThresholdDirection(bool mustbeLower) {
if (mustbeLower) {
touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW);
@ -278,7 +279,7 @@ void touchInterruptSetThresholdDirection(bool mustbeLower) {
touch_pad_set_trigger_mode(TOUCH_TRIGGER_ABOVE);
}
}
#elif SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
#elif SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3
// returns true if touch pad has been and continues pressed and false otherwise
bool touchInterruptGetLastStatus(uint8_t pin) {
int8_t pad = digitalPinToTouchChannel(pin);
@ -307,10 +308,10 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold) {
return;
}
}
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC
touch_pad_set_thresh(pad, threshold);
#elif SOC_TOUCH_VERSION_2
#elif SOC_TOUCH_SENSOR_VERSION == 2
touch_pad_sleep_channel_enable(pad, true);
touch_pad_sleep_set_threshold(pad, threshold);
@ -324,4 +325,5 @@ extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value
extern void touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDettachInterrupt")));
extern void touchSetCycles(uint16_t, uint16_t) __attribute__((weak, alias("__touchSetCycles")));
#endif /* SOC_TOUCH_SENSOR_VERSION <= 2 */
#endif /* SOC_TOUCH_SENSOR_SUPPORTED */

View file

@ -22,6 +22,7 @@
#include "soc/soc_caps.h"
#if SOC_TOUCH_SENSOR_SUPPORTED
#if SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32 ESP32S2 ESP32S3
#ifdef __cplusplus
extern "C" {
@ -29,13 +30,13 @@ extern "C" {
#include "esp32-hal.h"
#if !defined(SOC_TOUCH_VERSION_1) && !defined(SOC_TOUCH_VERSION_2)
#if !SOC_TOUCH_SENSOR_SUPPORTED
#error Touch IDF driver Not supported!
#endif
#if SOC_TOUCH_VERSION_1 // ESP32
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
typedef uint16_t touch_value_t;
#elif SOC_TOUCH_VERSION_2 // ESP32S2 ESP32S3
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2 ESP32S3
typedef uint32_t touch_value_t;
#endif
@ -71,7 +72,7 @@ void touchDetachInterrupt(uint8_t pin);
* Default if Lower.
**/
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC
void touchInterruptSetThresholdDirection(bool mustbeLower);
#endif
@ -83,7 +84,7 @@ void touchInterruptSetThresholdDirection(bool mustbeLower);
* as soon as the touchpad is touched and/or released
**/
#if SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
#if SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3
// returns true if touch pad has been and continues pressed and false otherwise
bool touchInterruptGetLastStatus(uint8_t pin);
#endif
@ -97,5 +98,6 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold);
}
#endif
#endif /* SOC_TOUCH_SENSOR_VERSION <= 2 */
#endif /* SOC_TOUCH_SENSOR_SUPPORTED */
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */

View file

@ -34,6 +34,7 @@
#include "esp_rom_gpio.h"
static int s_uart_debug_nr = 0; // UART number for debug output
#define REF_TICK_BAUDRATE_LIMIT 250000 // this is maximum UART badrate using REF_TICK as clock
struct uart_struct_t {
@ -61,12 +62,18 @@ struct uart_struct_t {
static uart_t _uart_bus_array[] = {
{0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
{1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
{2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif
#if SOC_UART_HP_NUM > 3
{3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif
#if SOC_UART_HP_NUM > 4
{4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif
};
#else
@ -81,12 +88,18 @@ static uart_t _uart_bus_array[] = {
static uart_t _uart_bus_array[] = {
{NULL, 0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
{NULL, 1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
{NULL, 2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif
#if SOC_UART_HP_NUM > 3
{NULL, 3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif
#if SOC_UART_HP_NUM > 4
{NULL, 4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif
};
#endif
@ -94,8 +107,8 @@ static uart_t _uart_bus_array[] = {
// Negative Pin Number will keep it unmodified, thus this function can detach individual pins
// This function will also unset the pins in the Peripheral Manager and set the pin to -1 after detaching
static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
if (uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
if (uart_num >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return false;
}
// get UART information
@ -181,8 +194,8 @@ static bool _uartDetachBus_RTS(void *busptr) {
// Attach function for UART
// connects the IO Pad, set Paripheral Manager and internal UART structure data
static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
if (uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
if (uart_num >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return false;
}
// get UART information
@ -308,8 +321,8 @@ bool uartIsDriverInstalled(uart_t *uart) {
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
// When pins are changed, it will detach the previous one
bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
if (uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
if (uart_num >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return false;
}
// get UART information
@ -378,7 +391,7 @@ bool _testUartBegin(
uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint32_t rx_buffer_size, uint32_t tx_buffer_size, bool inverted,
uint8_t rxfifo_full_thrhd
) {
if (uart_nr >= SOC_UART_NUM) {
if (uart_nr >= SOC_UART_HP_NUM) {
return false; // no new driver has to be installed
}
uart_t *uart = &_uart_bus_array[uart_nr];
@ -400,8 +413,8 @@ uart_t *uartBegin(
uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint32_t rx_buffer_size, uint32_t tx_buffer_size, bool inverted,
uint8_t rxfifo_full_thrhd
) {
if (uart_nr >= SOC_UART_NUM) {
log_e("UART number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
if (uart_nr >= SOC_UART_HP_NUM) {
log_e("UART number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return NULL; // no new driver was installed
}
uart_t *uart = &_uart_bus_array[uart_nr];
@ -497,6 +510,8 @@ uart_t *uartBegin(
log_v("UART%d not installed. Starting installation", uart_nr);
}
uart_config_t uart_config;
memset(&uart_config, 0, sizeof(uart_config_t));
uart_config.flags.backup_before_sleep = false; // new flag from IDF v5.3
uart_config.data_bits = (config & 0xc) >> 2;
uart_config.parity = (config & 0x3);
uart_config.stop_bits = (config & 0x30) >> 4;
@ -508,7 +523,7 @@ uart_t *uartBegin(
#if SOC_UART_SUPPORT_XTAL_CLK
uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4
#elif SOC_UART_SUPPORT_REF_TICK
if (baudrate <= 250000) {
if (baudrate <= REF_TICK_BAUDRATE_LIMIT) {
uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
} else {
uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency!
@ -604,8 +619,8 @@ bool uartSetRxFIFOFull(uart_t *uart, uint8_t numBytesFIFOFull) {
}
void uartEnd(uint8_t uart_num) {
if (uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
if (uart_num >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return;
}
// get UART information
@ -623,7 +638,7 @@ void uartSetRxInvert(uart_t *uart, bool invert) {
if (uart == NULL) {
return;
}
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
// POTENTIAL ISSUE :: original code only set/reset rxd_inv bit
// IDF or LL set/reset the whole inv_mask!
// if (invert)
@ -790,6 +805,10 @@ void uartSetBaudRate(uart_t *uart, uint32_t baud_rate) {
return;
}
UART_MUTEX_LOCK();
#if !SOC_UART_SUPPORT_XTAL_CLK
soc_module_clk_t newClkSrc = baud_rate <= REF_TICK_BAUDRATE_LIMIT ? SOC_MOD_CLK_REF_TICK : SOC_MOD_CLK_APB;
uart_ll_set_sclk(UART_LL_GET_HW(uart->num), newClkSrc);
#endif
if (uart_set_baudrate(uart->num, baud_rate) == ESP_OK) {
uart->_baudrate = baud_rate;
} else {
@ -819,28 +838,48 @@ static void ARDUINO_ISR_ATTR uart0_write_char(char c) {
uart_ll_write_txfifo(&UART0, (const uint8_t *)&c, 1);
}
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
static void ARDUINO_ISR_ATTR uart1_write_char(char c) {
while (uart_ll_get_txfifo_len(&UART1) == 0);
uart_ll_write_txfifo(&UART1, (const uint8_t *)&c, 1);
}
#endif
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
static void ARDUINO_ISR_ATTR uart2_write_char(char c) {
while (uart_ll_get_txfifo_len(&UART2) == 0);
uart_ll_write_txfifo(&UART2, (const uint8_t *)&c, 1);
}
#endif
#if SOC_UART_HP_NUM > 3
static void ARDUINO_ISR_ATTR uart3_write_char(char c) {
while (uart_ll_get_txfifo_len(&UART3) == 0);
uart_ll_write_txfifo(&UART3, (const uint8_t *)&c, 1);
}
#endif
#if SOC_UART_HP_NUM > 4
static void ARDUINO_ISR_ATTR uart4_write_char(char c) {
while (uart_ll_get_txfifo_len(&UART4) == 0);
uart_ll_write_txfifo(&UART4, (const uint8_t *)&c, 1);
}
#endif
void uart_install_putc() {
switch (s_uart_debug_nr) {
case 0: ets_install_putc1((void (*)(char)) & uart0_write_char); break;
#if SOC_UART_NUM > 1
#if SOC_UART_HP_NUM > 1
case 1: ets_install_putc1((void (*)(char)) & uart1_write_char); break;
#endif
#if SOC_UART_NUM > 2
#if SOC_UART_HP_NUM > 2
case 2: ets_install_putc1((void (*)(char)) & uart2_write_char); break;
#endif
#if SOC_UART_HP_NUM > 3
case 3: ets_install_putc1((void (*)(char)) & uart3_write_char); break;
#endif
#if SOC_UART_HP_NUM > 4
case 4: ets_install_putc1((void (*)(char)) & uart4_write_char); break;
#endif
default: ets_install_putc1(NULL); break;
}
@ -850,7 +889,7 @@ void uart_install_putc() {
// Routines that take care of UART mode in the HardwareSerial Class code
// used to set UART_MODE_RS485_HALF_DUPLEX auto RTS for TXD for ESP32 chips
bool uartSetMode(uart_t *uart, uart_mode_t mode) {
if (uart == NULL || uart->num >= SOC_UART_NUM) {
if (uart == NULL || uart->num >= SOC_UART_HP_NUM) {
return false;
}
@ -861,7 +900,7 @@ bool uartSetMode(uart_t *uart, uart_mode_t mode) {
}
void uartSetDebug(uart_t *uart) {
if (uart == NULL || uart->num >= SOC_UART_NUM) {
if (uart == NULL || uart->num >= SOC_UART_HP_NUM) {
s_uart_debug_nr = -1;
} else {
s_uart_debug_nr = uart->num;
@ -896,7 +935,7 @@ int log_printfv(const char *format, va_list arg) {
#endif
*/
#if (ARDUINO_USB_CDC_ON_BOOT == 1 && ARDUINO_USB_MODE == 0) || CONFIG_IDF_TARGET_ESP32C3 \
|| ((CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6) && ARDUINO_USB_CDC_ON_BOOT == 1)
|| ((CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4) && ARDUINO_USB_CDC_ON_BOOT == 1)
vsnprintf(temp, len + 1, format, arg);
ets_printf("%s", temp);
#else
@ -1103,19 +1142,35 @@ unsigned long uartDetectBaudrate(uart_t *uart) {
*/
// gets the right TX or RX SIGNAL, based on the UART number from gpio_sig_map.h
#if SOC_UART_NUM > 2
#ifdef CONFIG_IDF_TARGET_ESP32P4
#define UART_TX_SIGNAL(uartNumber) \
(uartNumber == UART_NUM_0 \
? UART0_TXD_PAD_OUT_IDX \
: (uartNumber == UART_NUM_1 \
? UART1_TXD_PAD_OUT_IDX \
: (uartNumber == UART_NUM_2 ? UART2_TXD_PAD_OUT_IDX : (uartNumber == UART_NUM_3 ? UART3_TXD_PAD_OUT_IDX : UART4_TXD_PAD_OUT_IDX))))
#define UART_RX_SIGNAL(uartNumber) \
(uartNumber == UART_NUM_0 \
? UART0_RXD_PAD_IN_IDX \
: (uartNumber == UART_NUM_1 \
? UART1_RXD_PAD_IN_IDX \
: (uartNumber == UART_NUM_2 ? UART2_RXD_PAD_IN_IDX : (uartNumber == UART_NUM_3 ? UART3_RXD_PAD_IN_IDX : UART4_RXD_PAD_IN_IDX))))
#else
#if SOC_UART_HP_NUM > 2
#define UART_TX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0TXD_OUT_IDX : (uartNumber == UART_NUM_1 ? U1TXD_OUT_IDX : U2TXD_OUT_IDX))
#define UART_RX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0RXD_IN_IDX : (uartNumber == UART_NUM_1 ? U1RXD_IN_IDX : U2RXD_IN_IDX))
#else
#define UART_TX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0TXD_OUT_IDX : U1TXD_OUT_IDX)
#define UART_RX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0RXD_IN_IDX : U1RXD_IN_IDX)
#endif
#endif // ifdef CONFIG_IDF_TARGET_ESP32P4
/*
This function internally binds defined UARTs TX signal with defined RX pin of any UART (same or different).
This creates a loop that lets us receive anything we send on the UART without external wires.
*/
void uart_internal_loopback(uint8_t uartNum, int8_t rxPin) {
if (uartNum > SOC_UART_NUM - 1 || !GPIO_IS_VALID_GPIO(rxPin)) {
if (uartNum > SOC_UART_HP_NUM - 1 || !GPIO_IS_VALID_GPIO(rxPin)) {
return;
}
esp_rom_gpio_connect_out_signal(rxPin, UART_TX_SIGNAL(uartNum), false, false);

View file

@ -61,6 +61,19 @@ extern "C" {
#define ARDUINO_EVENT_RUNNING_CORE CONFIG_ARDUINO_EVENT_RUNNING_CORE
#endif
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
static const uint8_t BOOT_PIN = 0;
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C61
static const uint8_t BOOT_PIN = 9;
#elif CONFIG_IDF_TARGET_ESP32P4
static const uint8_t BOOT_PIN = 35;
#elif CONFIG_IDF_TARGET_ESP32C5
static const uint8_t BOOT_PIN = 28;
#else
#error BOOT_PIN not defined for this chip!
#endif
#define BOOT_PIN BOOT_PIN
//forward declaration from freertos/portmacro.h
void vPortYield(void);
void yield(void);
@ -74,6 +87,7 @@ void yield(void);
#include "esp32-hal-uart.h"
#include "esp32-hal-gpio.h"
#include "esp32-hal-touch.h"
#include "esp32-hal-touch-ng.h"
#include "esp32-hal-dac.h"
#include "esp32-hal-adc.h"
#include "esp32-hal-spi.h"

View file

@ -21,9 +21,9 @@ extern "C" {
/** Major version number (X.x.x) */
#define ESP_ARDUINO_VERSION_MAJOR 3
/** Minor version number (x.X.x) */
#define ESP_ARDUINO_VERSION_MINOR 0
#define ESP_ARDUINO_VERSION_MINOR 1
/** Patch version number (x.x.X) */
#define ESP_ARDUINO_VERSION_PATCH 5
#define ESP_ARDUINO_VERSION_PATCH 0
/**
* Macro to convert ARDUINO version number into an integer

View file

@ -0,0 +1,111 @@
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "freertos_stats.h"
#include "sdkconfig.h"
#if CONFIG_FREERTOS_USE_TRACE_FACILITY
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/portable.h"
#endif /* CONFIG_FREERTOS_USE_TRACE_FACILITY */
void printRunningTasks(Print &printer) {
#if CONFIG_FREERTOS_USE_TRACE_FACILITY
#if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
#define FREERTOS_TASK_NUMBER_MAX_NUM 256 // RunTime stats for how many Tasks to be stored
static configRUN_TIME_COUNTER_TYPE ulRunTimeCounters[FREERTOS_TASK_NUMBER_MAX_NUM];
static configRUN_TIME_COUNTER_TYPE ulLastRunTime = 0;
configRUN_TIME_COUNTER_TYPE ulCurrentRunTime = 0, ulTaskRunTime = 0;
#endif
configRUN_TIME_COUNTER_TYPE ulTotalRunTime = 0;
TaskStatus_t *pxTaskStatusArray = NULL;
volatile UBaseType_t uxArraySize = 0, x = 0;
const char *taskStates[] = {"Running", "Ready", "Blocked", "Suspended", "Deleted", "Invalid"};
// Take a snapshot of the number of tasks in case it changes while this function is executing.
uxArraySize = uxTaskGetNumberOfTasks();
// Allocate a TaskStatus_t structure for each task.
pxTaskStatusArray = (TaskStatus_t *)pvPortMalloc(uxArraySize * sizeof(TaskStatus_t));
if (pxTaskStatusArray != NULL) {
// Generate raw status information about each task.
uxArraySize = uxTaskGetSystemState(pxTaskStatusArray, uxArraySize, &ulTotalRunTime);
#if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
ulCurrentRunTime = ulTotalRunTime - ulLastRunTime;
ulLastRunTime = ulTotalRunTime;
#endif
printer.printf(
"Tasks: %u"
#if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
", Runtime: %lus, Period: %luus"
#endif
"\n",
uxArraySize
#if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
,
ulTotalRunTime / 1000000, ulCurrentRunTime
#endif
);
printer.printf("Num\t Name"
#if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
"\tLoad"
#endif
"\tPrio\t Free"
#if CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
"\tCore"
#endif
"\tState\r\n");
for (x = 0; x < uxArraySize; x++) {
#if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
if (pxTaskStatusArray[x].xTaskNumber < FREERTOS_TASK_NUMBER_MAX_NUM) {
ulTaskRunTime = (pxTaskStatusArray[x].ulRunTimeCounter - ulRunTimeCounters[pxTaskStatusArray[x].xTaskNumber]);
ulRunTimeCounters[pxTaskStatusArray[x].xTaskNumber] = pxTaskStatusArray[x].ulRunTimeCounter;
ulTaskRunTime = (ulTaskRunTime * 100) / ulCurrentRunTime; // in percentage
} else {
ulTaskRunTime = 0;
}
#endif
printer.printf(
"%3u\t%16s"
#if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
"\t%3lu%%"
#endif
"\t%4u\t%5lu"
#if CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
"\t%4c"
#endif
"\t%s\r\n",
pxTaskStatusArray[x].xTaskNumber, pxTaskStatusArray[x].pcTaskName,
#if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
ulTaskRunTime,
#endif
pxTaskStatusArray[x].uxCurrentPriority, pxTaskStatusArray[x].usStackHighWaterMark,
#if CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
(pxTaskStatusArray[x].xCoreID == tskNO_AFFINITY) ? '*' : ('0' + pxTaskStatusArray[x].xCoreID),
#endif
taskStates[pxTaskStatusArray[x].eCurrentState]
);
}
// The array is no longer needed, free the memory it consumes.
vPortFree(pxTaskStatusArray);
printer.println();
}
#else
printer.println("FreeRTOS trace facility is not enabled.");
#endif /* CONFIG_FREERTOS_USE_TRACE_FACILITY */
}

View file

@ -0,0 +1,28 @@
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
#include "Print.h"
/*
* Executing this function will cause interrupts and
* the scheduler to be blocked for some time.
* Please use only for debugging purposes.
*/
void printRunningTasks(Print &printer);
#endif

View file

@ -106,7 +106,7 @@ int8_t gpioNumberToDigitalPin(int8_t gpioNumber);
#define spiAttachMOSI(spi, mosi) spiAttachMOSI(spi, digitalPinToGPIONumber(mosi))
#define spiAttachSS(spi, cs_num, ss) spiAttachSS(spi, cs_num, digitalPinToGPIONumber(ss))
// cores/esp32/esp32-hal-touch.h
// cores/esp32/esp32-hal-touch.h && cores/esp32/esp32-hal-touch-ng.h
#define touchInterruptGetLastStatus(pin) touchInterruptGetLastStatus(digitalPinToGPIONumber(pin))
#define touchRead(pin) touchRead(digitalPinToGPIONumber(pin))
#define touchAttachInterruptArg(pin, userFunc, arg, threshold) touchAttachInterruptArg(digitalPinToGPIONumber(pin), userFunc, arg, threshold)

View file

@ -178,6 +178,7 @@ Currently, the default FQBNs are:
* ``espressif:esp32:esp32c3``
* ``espressif:esp32:esp32c6``
* ``espressif:esp32:esp32h2``
* ``espressif:esp32:esp32p4:USBMode=default``
There are two ways to alter the FQBNs used to compile the sketches: by using the ``fqbn`` or ``fqbn_append`` fields in the ``ci.json`` file.
@ -440,6 +441,16 @@ For checking the code style and other code quality checks, we use pre-commit hoo
These hooks will be automatically run by the CI when a Pull Request is marked as ``Status: Pending Merge``.
You can check which hooks are being run in the ``.pre-commit-config.yaml`` file.
Currently, we have hooks for the following tasks:
* Formatters for C, C++, Python, Bash, JSON, Markdown and ReStructuredText files;
* Linters for Python, Bash and prose (spoken language);
* Checking for spelling errors in the code and documentation;
* Removing trailing whitespaces and tabs in the code;
* Checking for the presence of private keys and other sensitive information in the code;
* Fixing the line endings and end of files (EOF) in the code;
* And more.
You can read more about the pre-commit hooks in the `pre-commit documentation <https://pre-commit.com/>`_.
If you want to run the pre-commit hooks locally, you first need to install the required dependencies by running:

View file

@ -157,6 +157,7 @@ This build command will build for the ESP32-S3 target. You can specify other tar
* esp32c3
* esp32c6
* esp32h2
* esp32p4
Set Build Type
^^^^^^^^^^^^^^

View file

@ -1,6 +1,7 @@
#!/bin/bash
# Bash helper functions for adding SSH keys
function add_ssh_keys() {
function add_ssh_keys {
local key_string="${1}"
mkdir -p ~/.ssh
chmod 700 ~/.ssh
@ -9,7 +10,7 @@ function add_ssh_keys() {
chmod 600 ~/.ssh/id_rsa
}
function add_doc_server_ssh_keys() {
function add_doc_server_ssh_keys {
local key_string="${1}"
local server_url="${2}"
local server_user="${3}"

View file

@ -9,6 +9,7 @@ targets:
- esp32c3
- esp32c6
- esp32h2
- esp32p4
tags:
- arduino
files:
@ -20,6 +21,7 @@ files:
- "variants/esp32c3/**/*"
- "variants/esp32c6/**/*"
- "variants/esp32h2/**/*"
- "variants/esp32p4/**/*"
exclude:
- "docs/"
- "docs/**/*"
@ -42,47 +44,72 @@ files:
- "platform.txt"
- "programmers.txt"
dependencies:
idf: ">=5.1,<5.2"
idf: ">=5.3,<5.4"
# mdns 1.2.1 is necessary to build H2 with no WiFi
espressif/mdns:
version: "^1.2.3"
require: public
espressif/esp_modem:
version: "^1.1.0"
espressif/network_provisioning:
version: "~1.0.0"
espressif/esp-zboss-lib:
version: "^1.0.1"
version: "==1.6.0"
require: public
rules:
- if: "target != esp32c2"
- if: "target not in [esp32c2, esp32p4]"
espressif/esp-zigbee-lib:
version: "^1.0.1"
version: "==1.6.0"
require: public
rules:
- if: "target != esp32c2"
- if: "target not in [esp32c2, esp32p4]"
espressif/esp-dsp:
version: "^1.3.4"
rules:
- if: "target != esp32c2"
# RainMaker Start (Fixed versions, because Matter supports only Insights 1.0.1)
espressif/network_provisioning:
version: "1.0.2"
espressif/esp_rainmaker:
version: "^1.0.0"
version: "1.5.0"
rules:
- if: "target != esp32c2"
- if: "target not in [esp32c2, esp32p4]"
espressif/rmaker_common:
version: "^1.4.6"
version: "1.4.6"
rules:
- if: "target != esp32c2"
- if: "target not in [esp32c2, esp32p4]"
espressif/esp_insights:
version: "^1.2.1"
version: "1.0.1"
rules:
- if: "target != esp32c2"
- if: "target not in [esp32c2, esp32p4]"
# New version breaks esp_insights 1.0.1
espressif/esp_diag_data_store:
version: "1.0.1"
rules:
- if: "target not in [esp32c2, esp32p4]"
espressif/esp_diagnostics:
version: "1.0.2"
rules:
- if: "target not in [esp32c2, esp32p4]"
espressif/cbor:
version: "0.6.0~1"
rules:
- if: "target not in [esp32c2, esp32p4]"
espressif/qrcode:
version: "^0.1.0~1"
version: "0.1.0~2"
rules:
- if: "target != esp32c2"
- if: "target not in [esp32c2, esp32p4]"
# RainMaker End
espressif/esp-sr:
version: "^1.4.2"
rules:
- if: "target in [esp32s3]"
espressif/esp_hosted:
version: "^0.0.25"
rules:
- if: "target == esp32p4"
espressif/esp_wifi_remote:
version: "^0.4.1"
rules:
- if: "target == esp32p4"
espressif/libsodium:
version: "^1.0.20~1"
require: public

View file

@ -1,5 +1,5 @@
name=ArduinoOTA
version=3.0.5
version=3.1.0
author=Ivan Grokhotkov and Hristo Gochkov
maintainer=Hristo Gochkov <hristo@espressif.com>
sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download.

View file

@ -134,10 +134,12 @@ void ArduinoOTAClass::begin() {
sprintf(tmp, "esp32-%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
_hostname = tmp;
}
#ifdef CONFIG_MDNS_MAX_INTERFACES
if (_mdnsEnabled) {
MDNS.begin(_hostname.c_str());
MDNS.enableArduino(_port, (_password.length() > 0));
}
#endif
_initialized = true;
_state = OTA_IDLE;
log_i("OTA server at: %s.local:%u", _hostname.c_str(), _port);
@ -372,9 +374,11 @@ void ArduinoOTAClass::_runUpdate() {
void ArduinoOTAClass::end() {
_initialized = false;
_udp_ota.stop();
#ifdef CONFIG_MDNS_MAX_INTERFACES
if (_mdnsEnabled) {
MDNS.end();
}
#endif
_state = OTA_IDLE;
log_i("OTA server stopped.");
}

View file

@ -1,5 +1,5 @@
name=ESP32 Async UDP
version=3.0.5
version=3.1.0
author=Me-No-Dev
maintainer=Me-No-Dev
sentence=Async UDP Library for ESP32

View file

@ -328,25 +328,36 @@ AsyncUDPPacket::AsyncUDPPacket(AsyncUDP *udp, pbuf *pb, const ip_addr_t *raddr,
pbuf_ref(_pb);
//memcpy(&_remoteIp, raddr, sizeof(ip_addr_t));
#if CONFIG_LWIP_IPV6
_remoteIp.type = raddr->type;
_localIp.type = _remoteIp.type;
#endif
eth_hdr *eth = NULL;
udp_hdr *udphdr = (udp_hdr *)(_data - UDP_HLEN);
_localPort = ntohs(udphdr->dest);
_remotePort = ntohs(udphdr->src);
#if CONFIG_LWIP_IPV6
if (_remoteIp.type == IPADDR_TYPE_V4) {
#endif
eth = (eth_hdr *)(_data - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR);
struct ip_hdr *iphdr = (struct ip_hdr *)(_data - UDP_HLEN - IP_HLEN);
#if CONFIG_LWIP_IPV6
_localIp.u_addr.ip4.addr = iphdr->dest.addr;
_remoteIp.u_addr.ip4.addr = iphdr->src.addr;
#else
_localIp.addr = iphdr->dest.addr;
_remoteIp.addr = iphdr->src.addr;
#endif
#if CONFIG_LWIP_IPV6
} else {
eth = (eth_hdr *)(_data - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR);
struct ip6_hdr *ip6hdr = (struct ip6_hdr *)(_data - UDP_HLEN - IP6_HLEN);
memcpy(&_localIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->dest.addr, 16);
memcpy(&_remoteIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->src.addr, 16);
}
#endif
memcpy(_remoteMac, eth->src.addr, 6);
struct netif *netif = NULL;
@ -413,36 +424,48 @@ tcpip_adapter_if_t AsyncUDPPacket::interface() {
}
IPAddress AsyncUDPPacket::localIP() {
#if CONFIG_LWIP_IPV6
if (_localIp.type != IPADDR_TYPE_V4) {
return IPAddress();
}
return IPAddress(_localIp.u_addr.ip4.addr);
#else
return IPAddress(_localIp.addr);
#endif
}
#if CONFIG_LWIP_IPV6
IPAddress AsyncUDPPacket::localIPv6() {
if (_localIp.type != IPADDR_TYPE_V6) {
return IPAddress(IPv6);
}
return IPAddress(IPv6, (const uint8_t *)_localIp.u_addr.ip6.addr, _localIp.u_addr.ip6.zone);
}
#endif
uint16_t AsyncUDPPacket::localPort() {
return _localPort;
}
IPAddress AsyncUDPPacket::remoteIP() {
#if CONFIG_LWIP_IPV6
if (_remoteIp.type != IPADDR_TYPE_V4) {
return IPAddress();
}
return IPAddress(_remoteIp.u_addr.ip4.addr);
#else
return IPAddress(_remoteIp.addr);
#endif
}
#if CONFIG_LWIP_IPV6
IPAddress AsyncUDPPacket::remoteIPv6() {
if (_remoteIp.type != IPADDR_TYPE_V6) {
return IPAddress(IPv6);
}
return IPAddress(IPv6, (const uint8_t *)_remoteIp.u_addr.ip6.addr, _remoteIp.u_addr.ip6.zone);
}
#endif
uint16_t AsyncUDPPacket::remotePort() {
return _remotePort;
@ -453,14 +476,22 @@ void AsyncUDPPacket::remoteMac(uint8_t *mac) {
}
bool AsyncUDPPacket::isIPv6() {
#if CONFIG_LWIP_IPV6
return _localIp.type == IPADDR_TYPE_V6;
#else
return false;
#endif
}
bool AsyncUDPPacket::isBroadcast() {
#if CONFIG_LWIP_IPV6
if (_localIp.type == IPADDR_TYPE_V6) {
return false;
}
uint32_t ip = _localIp.u_addr.ip4.addr;
#else
uint32_t ip = _localIp.addr;
#endif
return ip == 0xFFFFFFFF || ip == 0 || (ip & 0xFF000000) == 0xFF000000;
}
@ -571,6 +602,7 @@ static esp_err_t joinMulticastGroup(const ip_addr_t *addr, bool join, tcpip_adap
}
netif = (struct netif *)nif;
#if CONFIG_LWIP_IPV6
if (addr->type == IPADDR_TYPE_V4) {
if (join) {
if (igmp_joingroup_netif(netif, (const ip4_addr *)&(addr->u_addr.ip4))) {
@ -592,7 +624,19 @@ static esp_err_t joinMulticastGroup(const ip_addr_t *addr, bool join, tcpip_adap
}
}
}
#else
if (join) {
if (igmp_joingroup_netif(netif, (const ip4_addr *)(addr))) {
return ESP_ERR_INVALID_STATE;
}
} else {
if (igmp_leavegroup_netif(netif, (const ip4_addr *)(addr))) {
return ESP_ERR_INVALID_STATE;
}
}
#endif
} else {
#if CONFIG_LWIP_IPV6
if (addr->type == IPADDR_TYPE_V4) {
if (join) {
if (igmp_joingroup((const ip4_addr *)IP4_ADDR_ANY, (const ip4_addr *)&(addr->u_addr.ip4))) {
@ -614,6 +658,17 @@ static esp_err_t joinMulticastGroup(const ip_addr_t *addr, bool join, tcpip_adap
}
}
}
#else
if (join) {
if (igmp_joingroup((const ip4_addr *)IP4_ADDR_ANY, (const ip4_addr *)(addr))) {
return ESP_ERR_INVALID_STATE;
}
} else {
if (igmp_leavegroup((const ip4_addr *)IP4_ADDR_ANY, (const ip4_addr *)(addr))) {
return ESP_ERR_INVALID_STATE;
}
}
#endif
}
return ESP_OK;
}
@ -722,18 +777,24 @@ size_t AsyncUDP::writeTo(const uint8_t *data, size_t len, const IPAddress addr,
}
IPAddress AsyncUDP::listenIP() {
#if CONFIG_LWIP_IPV6
if (!_pcb || _pcb->remote_ip.type != IPADDR_TYPE_V4) {
return IPAddress();
}
return IPAddress(_pcb->remote_ip.u_addr.ip4.addr);
#else
return IPAddress(_pcb->remote_ip.addr);
#endif
}
#if CONFIG_LWIP_IPV6
IPAddress AsyncUDP::listenIPv6() {
if (!_pcb || _pcb->remote_ip.type != IPADDR_TYPE_V6) {
return IPAddress(IPv6);
}
return IPAddress(IPv6, (const uint8_t *)_pcb->remote_ip.u_addr.ip6.addr, _pcb->remote_ip.u_addr.ip6.zone);
}
#endif
size_t AsyncUDP::write(const uint8_t *data, size_t len) {
return writeTo(data, len, &(_pcb->remote_ip), _pcb->remote_port);

View file

@ -79,10 +79,14 @@ public:
tcpip_adapter_if_t interface();
IPAddress localIP();
#if CONFIG_LWIP_IPV6
IPAddress localIPv6();
#endif
uint16_t localPort();
IPAddress remoteIP();
#if CONFIG_LWIP_IPV6
IPAddress remoteIPv6();
#endif
uint16_t remotePort();
void remoteMac(uint8_t *mac);
@ -146,7 +150,9 @@ public:
size_t broadcast(AsyncUDPMessage &message);
IPAddress listenIP();
#if CONFIG_LWIP_IPV6
IPAddress listenIPv6();
#endif
bool connected();
esp_err_t lastErr();
operator bool();

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_50_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_50_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_50_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_50_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_SUPPORTED=y"
]

View file

@ -1,4 +1,5 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_BLE_SUPPORTED=y"
]

Some files were not shown because too many files have changed in this diff Show more