Merge pull request #10202 from espressif/release/v3.1.x

ESP32 Arduino v3.1.x
This commit is contained in:
Me No Dev 2024-12-18 15:56:18 +02:00 committed by GitHub
commit bd7a74ee51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
383 changed files with 13698 additions and 3155 deletions

View file

@ -5,7 +5,7 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
* Before reporting a new issue please check and search in [List of existing issues](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue) * Before reporting a new issue please check and search in [List of existing issues](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue)
* Please check [Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/index.html) * Please check [Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/index.html)
* Take a look on [Troubleshooting guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html) * Take a look on [Troubleshooting guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html)
* If still experiencing the issue, please provide as many details as possible below about your hardware, computer setup and code. * If still experiencing the issue, please provide as many details as possible below about your hardware, computer setup and code.
@ -24,7 +24,7 @@ body:
description: What development board or other hardware is the chip attached to? description: What development board or other hardware is the chip attached to?
placeholder: ex. DevKitC, plain module on breadboard, etc. If your hardware is custom or unusual, please attach a photo. placeholder: ex. DevKitC, plain module on breadboard, etc. If your hardware is custom or unusual, please attach a photo.
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: other-hw id: other-hw
attributes: attributes:
@ -60,7 +60,7 @@ body:
- v2.0.8 - v2.0.8
- v2.0.7 - v2.0.7
- v2.0.6 - v2.0.6
- v2.0.5 - v2.0.5
- v2.0.4 - v2.0.4
- v2.0.3 - v2.0.3
- v2.0.2 - v2.0.2
@ -77,7 +77,7 @@ body:
description: What IDE are you using? description: What IDE are you using?
placeholder: eg. Arduino IDE, VSCode, Sloeber... placeholder: eg. Arduino IDE, VSCode, Sloeber...
validations: validations:
required: true required: true
- type: input - type: input
id: os id: os
attributes: attributes:
@ -95,13 +95,13 @@ body:
validations: validations:
required: true required: true
- type: dropdown - type: dropdown
id: PSRAM id: PSRAM
attributes: attributes:
label: PSRAM enabled label: PSRAM enabled
description: Is PSRAM enabled? description: Is PSRAM enabled?
options: options:
- 'yes' - "yes"
- 'no' - "no"
validations: validations:
required: true required: true
- type: input - type: input
@ -116,8 +116,8 @@ body:
id: Description id: Description
attributes: attributes:
label: Description label: Description
description: Please describe your problem here and expected behaviour description: Please describe your problem here and expected behavior
placeholder: ex. Can't connect/weird behaviour/wrong function/missing parameter.. placeholder: ex. Can't connect/weird behavior/wrong function/missing parameter..
validations: validations:
required: true required: true
- type: textarea - type: textarea
@ -128,7 +128,7 @@ body:
placeholder: ex. Related part of the code to replicate the issue placeholder: ex. Related part of the code to replicate the issue
render: cpp render: cpp
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: Debug id: Debug
attributes: attributes:
@ -137,11 +137,11 @@ body:
placeholder: Enable Core debug level - Debug on tools menu of Arduino IDE, then put the serial output here. placeholder: Enable Core debug level - Debug on tools menu of Arduino IDE, then put the serial output here.
render: plain render: plain
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: other-remarks id: other-remarks
attributes: attributes:
label: Other Steps to Reproduce label: Other Steps to Reproduce
description: Is there any other information you can think of which will help us reproduce this problem? Any additional info can be added as well. description: Is there any other information you can think of which will help us reproduce this problem? Any additional info can be added as well.
placeholder: ex. I also tried on other OS, HW...it works correctly on that setup. placeholder: ex. I also tried on other OS, HW...it works correctly on that setup.
- type: checkboxes - type: checkboxes

View file

@ -5,4 +5,4 @@ contact_links:
about: Community channel for questions and help about: Community channel for questions and help
- name: ESP32 Forum - Arduino - name: ESP32 Forum - Arduino
url: https://esp32.com/viewforum.php?f=19 url: https://esp32.com/viewforum.php?f=19
about: Official Forum for questions about: Official Forum for questions

View file

@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# #
# This script is used in the CI workflow. It checks all non-examples source files in libraries/ and cores/ are listed in # 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 # CMakeLists.txt for the cmake-based IDF component
@ -12,10 +13,10 @@ set -e
git submodule update --init --recursive git submodule update --init --recursive
# find all source files in repo # 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 # 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 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" echo "Source files in repo (-) and source files in CMakeLists.txt (+) don't match"

View file

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

View file

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

View file

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

View file

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

View file

@ -4,7 +4,7 @@
#OSTYPE: 'msys', ARCH: 'x86_64' => win32 #OSTYPE: 'msys', ARCH: 'x86_64' => win32
#OSTYPE: 'darwin18', ARCH: 'i386' => macos #OSTYPE: 'darwin18', ARCH: 'i386' => macos
OSBITS=`uname -m` OSBITS=$(uname -m)
if [[ "$OSTYPE" == "linux"* ]]; then if [[ "$OSTYPE" == "linux"* ]]; then
export OS_IS_LINUX="1" export OS_IS_LINUX="1"
ARCHIVE_FORMAT="tar.xz" ARCHIVE_FORMAT="tar.xz"
@ -77,4 +77,3 @@ if [ ! -d "$ARDUINO_IDE_PATH" ]; then
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'" echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
echo "" echo ""
fi 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,50 +1,58 @@
#!/usr/bin/env python #!/usr/bin/env python
# This script merges two Arduino Board Manager package json files. # This script merges two Arduino Board Manager package json files.
# Usage: # Usage:
# python merge_packages.py package_esp8266com_index.json version/new/package_esp8266com_index.json # python merge_packages.py package_esp8266com_index.json version/new/package_esp8266com_index.json
# Written by Ivan Grokhotkov, 2015 # Written by Ivan Grokhotkov, 2015
# #
from __future__ import print_function from __future__ import print_function
#from distutils.version import LooseVersion
# from distutils.version import LooseVersion
from packaging.version import Version from packaging.version import Version
import re import re
import json import json
import sys import sys
def load_package(filename): def load_package(filename):
pkg = json.load(open(filename))['packages'][0] pkg = json.load(open(filename))["packages"][0]
print("Loaded package {0} from {1}".format(pkg['name'], filename), file=sys.stderr) 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) print("{0} platform(s), {1} tools".format(len(pkg["platforms"]), len(pkg["tools"])), file=sys.stderr)
return pkg return pkg
def merge_objects(versions, obj): def merge_objects(versions, obj):
for o in obj: for o in obj:
name = o['name'].encode('ascii') name = o["name"].encode("ascii")
ver = o['version'].encode('ascii') ver = o["version"].encode("ascii")
if not name in versions: if name not in versions:
print("found new object, {0}".format(name), file=sys.stderr) print("found new object, {0}".format(name), file=sys.stderr)
versions[name] = {} 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) print("found new version {0} for object {1}".format(ver, name), file=sys.stderr)
versions[name][ver] = o versions[name][ver] = o
return versions 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): def pkgVersionNormalized(versionString):
verStr = str(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 len(verParts) == 3:
if (sys.version_info > (3, 0)): # Python 3 if sys.version_info > (3, 0): # Python 3
verStr = str(versionString) + '-rc' + str(sys.maxsize) verStr = str(versionString) + "-rc" + str(sys.maxsize)
else: # Python 2 else: # Python 2
verStr = str(versionString) + '-rc' + str(sys.maxint) verStr = str(versionString) + "-rc" + str(sys.maxint)
elif len(verParts) != 4: elif len(verParts) != 4:
print("pkgVersionNormalized WARNING: unexpected version format: {0})".format(verStr), file=sys.stderr) print("pkgVersionNormalized WARNING: unexpected version format: {0})".format(verStr), file=sys.stderr)
return verStr return verStr
@ -54,31 +62,37 @@ def main(args):
return 1 return 1
tools = {} tools = {}
platforms = {} platforms = {}
pkg1 = load_package(args[1]) pkg1 = load_package(args[1])
tools = merge_objects(tools, pkg1['tools']); tools = merge_objects(tools, pkg1["tools"])
platforms = merge_objects(platforms, pkg1['platforms']); platforms = merge_objects(platforms, pkg1["platforms"])
pkg2 = load_package(args[2]) pkg2 = load_package(args[2])
tools = merge_objects(tools, pkg2['tools']); tools = merge_objects(tools, pkg2["tools"])
platforms = merge_objects(platforms, pkg2['platforms']); platforms = merge_objects(platforms, pkg2["platforms"])
pkg1['tools'] = [] pkg1["tools"] = []
pkg1['platforms'] = [] pkg1["platforms"] = []
for name in tools: for name in tools:
for version in tools[name]: for version in tools[name]:
print("Adding tool {0}-{1}".format(name, version), file=sys.stderr) 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 name in platforms:
for version in platforms[name]: for version in platforms[name]:
print("Adding platform {0}-{1}".format(name, version), file=sys.stderr) 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)
json.dump({'packages':[pkg1]}, sys.stdout, indent=2) # pkg1["platforms"] = sorted(
# pkg1["platforms"], key=lambda k: LooseVersion(pkgVersionNormalized(k["version"])), reverse=True
# )
if __name__ == '__main__': pkg1["platforms"] = sorted(
pkg1["platforms"], key=lambda k: Version(pkgVersionNormalized(k["version"])), reverse=True
)
json.dump({"packages": [pkg1]}, sys.stdout, indent=2)
if __name__ == "__main__":
sys.exit(main(sys.argv)) sys.exit(main(sys.argv))

View file

@ -1,12 +1,13 @@
#/bin/bash #!/bin/bash
set -e set -e
function get_file_size(){ function get_file_size {
local file="$1" local file="$1"
if [[ "$OSTYPE" == "darwin"* ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then
eval `stat -s "$file"` eval "$(stat -s "$file")"
local res="$?" local res="$?"
echo "$st_size" echo "${st_size:?}"
return $res return $res
else else
stat --printf="%s" "$file" stat --printf="%s" "$file"
@ -15,25 +16,32 @@ function get_file_size(){
} }
#git_remove_from_pages <file> #git_remove_from_pages <file>
function git_remove_from_pages(){ function git_remove_from_pages {
local path=$1 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 info
local type=`echo "$info" | jq -r '.type'` local type
if [ ! $type == "file" ]; then local sha
if [ ! $type == "null" ]; then 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'" echo "Wrong type '$type'"
else else
echo "File is not on Pages" echo "File is not on Pages"
fi fi
return 0 return 0
fi 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\"}" 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" 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 path=$1
local src=$2 local src=$2
@ -42,41 +50,50 @@ function git_upload_to_pages(){
return 1 return 1
fi 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 info
local type=`echo "$info" | jq -r '.type'` local type
local message=$(basename $path) local message
local sha="" local sha=""
local content="" local content=""
if [ $type == "file" ]; then 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")
sha=`echo "$info" | jq -r '.sha'` type=$(echo "$info" | jq -r '.type')
message=$(basename "$path")
if [ "$type" == "file" ]; then
sha=$(echo "$info" | jq -r '.sha')
sha=",\"sha\":\"$sha\"" sha=",\"sha\":\"$sha\""
message="Updating $message" message="Updating $message"
elif [ ! $type == "null" ]; then elif [ ! "$type" == "null" ]; then
>&2 echo "Wrong type '$type'" >&2 echo "Wrong type '$type'"
return 1 return 1
else else
message="Creating $message" message="Creating $message"
fi fi
content=`base64 -i "$src"` content=$(base64 -i "$src")
data="{\"branch\":\"gh-pages\",\"message\":\"$message\",\"content\":\"$content\"$sha}" 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" 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 path=$1
local file="$2" local file="$2"
local name=$(basename "$file") local name
local size=`get_file_size "$file"` local size
local upload_res=`git_upload_to_pages "$path" "$file"` local upload_res
if [ $? -ne 0 ]; then
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' ($?)" >&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1 return 1
fi 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" >&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset #git_delete_asset
return 1 return 1

View file

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

View file

@ -1,29 +1,34 @@
#!/bin/bash #!/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'!" echo "Wrong event '$GITHUB_EVENT_NAME'!"
exit 1 exit 1
fi fi
EVENT_JSON=`cat $GITHUB_EVENT_PATH` EVENT_JSON=$(cat "$GITHUB_EVENT_PATH")
action=`echo $EVENT_JSON | jq -r '.action'` action=$(echo "$EVENT_JSON" | jq -r '.action')
if [ ! $action == "published" ]; then if [ ! "$action" == "published" ]; then
echo "Wrong action '$action'. Exiting now..." echo "Wrong action '$action'. Exiting now..."
exit 0 exit 0
fi fi
draft=`echo $EVENT_JSON | jq -r '.release.draft'` draft=$(echo "$EVENT_JSON" | jq -r '.release.draft')
if [ $draft == "true" ]; then if [ "$draft" == "true" ]; then
echo "It's a draft release. Exiting now..." echo "It's a draft release. Exiting now..."
exit 0 exit 0
fi fi
RELEASE_PRE=`echo $EVENT_JSON | jq -r '.release.prerelease'` RELEASE_PRE=$(echo "$EVENT_JSON" | jq -r '.release.prerelease')
RELEASE_TAG=`echo $EVENT_JSON | jq -r '.release.tag_name'` RELEASE_TAG=$(echo "$EVENT_JSON" | jq -r '.release.tag_name')
RELEASE_BRANCH=`echo $EVENT_JSON | jq -r '.release.target_commitish'` RELEASE_BRANCH=$(echo "$EVENT_JSON" | jq -r '.release.target_commitish')
RELEASE_ID=`echo $EVENT_JSON | jq -r '.release.id'` RELEASE_ID=$(echo "$EVENT_JSON" | jq -r '.release.id')
SCRIPTS_DIR="./.github/scripts"
OUTPUT_DIR="$GITHUB_WORKSPACE/build" OUTPUT_DIR="$GITHUB_WORKSPACE/build"
PACKAGE_NAME="esp32-$RELEASE_TAG" PACKAGE_NAME="esp32-$RELEASE_TAG"
PACKAGE_JSON_MERGE="$GITHUB_WORKSPACE/.github/scripts/merge_packages.py" 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" echo "Tag: $RELEASE_TAG, Draft: $draft, Pre-Release: $RELEASE_PRE"
# Try extracting something like a JSON with a "boards" array/element and "vendor" fields # 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` 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` 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
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" local file="$1"
if [[ "$OSTYPE" == "darwin"* ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then
eval `stat -s "$file"` eval "$(stat -s "$file")"
local res="$?" local res="$?"
echo "$st_size" echo "${st_size:?}"
return $res return $res
else else
stat --printf="%s" "$file" stat --printf="%s" "$file"
@ -54,23 +65,29 @@ function get_file_size(){
fi fi
} }
function git_upload_asset(){ function git_upload_asset {
local name=$(basename "$1") local name
name=$(basename "$1")
# local mime=$(file -b --mime-type "$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" 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 file="$1"
local name=$(basename "$file") local name
local size=`get_file_size "$file"` local size
local upload_res=`git_upload_asset "$file"` local upload_res
if [ $? -ne 0 ]; then
name=$(basename "$file")
size=$(get_file_size "$file")
if ! upload_res=$(git_upload_asset "$file"); then
>&2 echo "ERROR: Failed to upload '$name' ($?)" >&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1 return 1
fi 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" >&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset #git_delete_asset
return 1 return 1
@ -79,7 +96,7 @@ function git_safe_upload_asset(){
return $? return $?
} }
function git_upload_to_pages(){ function git_upload_to_pages {
local path=$1 local path=$1
local src=$2 local src=$2
@ -88,41 +105,50 @@ function git_upload_to_pages(){
return 1 return 1
fi 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 info
local type=`echo "$info" | jq -r '.type'` local type
local message=$(basename $path) local message
local sha="" local sha=""
local content="" local content=""
if [ $type == "file" ]; then 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")
sha=`echo "$info" | jq -r '.sha'` type=$(echo "$info" | jq -r '.type')
message=$(basename "$path")
if [ "$type" == "file" ]; then
sha=$(echo "$info" | jq -r '.sha')
sha=",\"sha\":\"$sha\"" sha=",\"sha\":\"$sha\""
message="Updating $message" message="Updating $message"
elif [ ! $type == "null" ]; then elif [ ! "$type" == "null" ]; then
>&2 echo "Wrong type '$type'" >&2 echo "Wrong type '$type'"
return 1 return 1
else else
message="Creating $message" message="Creating $message"
fi fi
content=`base64 -i "$src"` content=$(base64 -i "$src")
data="{\"branch\":\"gh-pages\",\"message\":\"$message\",\"content\":\"$content\"$sha}" 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" 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 path=$1
local file="$2" local file="$2"
local name=$(basename "$file") local name
local size=`get_file_size "$file"` local size
local upload_res=`git_upload_to_pages "$path" "$file"` local upload_res
if [ $? -ne 0 ]; then
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' ($?)" >&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1 return 1
fi 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" >&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset #git_delete_asset
return 1 return 1
@ -131,15 +157,20 @@ function git_safe_upload_to_pages(){
return $? return $?
} }
function merge_package_json(){ function merge_package_json {
local jsonLink=$1 local jsonLink=$1
local jsonOut=$2 local jsonOut=$2
local old_json=$OUTPUT_DIR/oldJson.json local old_json=$OUTPUT_DIR/oldJson.json
local merged_json=$OUTPUT_DIR/mergedJson.json local merged_json=$OUTPUT_DIR/mergedJson.json
local error_code=0
echo "Downloading previous JSON $jsonLink ..." 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 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 ..." echo "Creating new JSON ..."
set +e set +e
@ -147,7 +178,7 @@ function merge_package_json(){
set -e set -e
set -v set -v
if [ ! -s $merged_json ]; then if [ ! -s "$merged_json" ]; then
rm -f "$merged_json" rm -f "$merged_json"
echo "Nothing to merge" echo "Nothing to merge"
else else
@ -188,9 +219,10 @@ else
done done
# Copy only relevant variant files # Copy only relevant variant files
mkdir "$PKG_DIR/variants/" 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/" cp -Rf "$GITHUB_WORKSPACE/variants/${variant}" "$PKG_DIR/variants/"
done done <<< "$board_list"
fi fi
cp -f "$GITHUB_WORKSPACE/CMakeLists.txt" "$PKG_DIR/" cp -f "$GITHUB_WORKSPACE/CMakeLists.txt" "$PKG_DIR/"
cp -f "$GITHUB_WORKSPACE/idf_component.yml" "$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 -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/partitions" "$PKG_DIR/tools/"
cp -Rf "$GITHUB_WORKSPACE/tools/ide-debug" "$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 # Remove unnecessary files in the package folder
echo "Cleaning up folders ..." echo "Cleaning up folders ..."
@ -219,12 +251,8 @@ find "$PKG_DIR" -name '*.git*' -type f -delete
## ##
RVTC_NAME="riscv32-esp-elf-gcc" RVTC_NAME="riscv32-esp-elf-gcc"
RVTC_NEW_NAME="esp-rv32" RVTC_NEW_NAME="esp-rv32"
X32TC_NAME="xtensa-esp32-elf-gcc" X32TC_NAME="xtensa-esp-elf-gcc"
X32TC_NEW_NAME="esp-x32" 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 # Replace tools locations in platform.txt
echo "Generating 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/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.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-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-esp-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.riscv32-esp-elf-gdb/\{runtime.tools.riscv32-esp-elf-gdb.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.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.esptool/\{runtime.tools.esptool_py.path\}/g' | \
sed 's/{runtime\.platform\.path}.tools.openocd-esp32/\{runtime.tools.openocd-esp32.path\}/g' \ sed 's/{runtime\.platform\.path}.tools.openocd-esp32/\{runtime.tools.openocd-esp32.path\}/g' > "$PKG_DIR/platform.txt"
> "$PKG_DIR/platform.txt"
if ! [ -z ${VENDOR} ]; then if [ -n "${VENDOR}" ]; then
# Append vendor name to platform.txt to create a separate section # Append vendor name to platform.txt to create a separate section
sed -i "/^name=.*/s/$/ ($VENDOR)/" "$PKG_DIR/platform.txt" sed -i "/^name=.*/s/$/ ($VENDOR)/" "$PKG_DIR/platform.txt"
fi fi
# Add header with version information # Add header with version information
echo "Generating core_version.h ..." echo "Generating core_version.h ..."
ver_define=`echo $RELEASE_TAG | tr "[:lower:].\055" "[:upper:]_"` ver_define=$(echo "$RELEASE_TAG" | tr "[:lower:].\055" "[:upper:]_")
ver_hex=`git -C "$GITHUB_WORKSPACE" rev-parse --short=8 HEAD 2>/dev/null` 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_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_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"
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 # Compress package folder
echo "Creating ZIP ..." echo "Creating ZIP ..."
pushd "$OUTPUT_DIR" >/dev/null pushd "$OUTPUT_DIR" >/dev/null
zip -qr "$PACKAGE_ZIP" "$PACKAGE_NAME" 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 # Calculate SHA-256
echo "Calculating SHA sum ..." echo "Calculating SHA sum ..."
PACKAGE_PATH="$OUTPUT_DIR/$PACKAGE_ZIP" PACKAGE_PATH="$OUTPUT_DIR/$PACKAGE_ZIP"
PACKAGE_SHA=`shasum -a 256 "$PACKAGE_ZIP" | cut -f 1 -d ' '` PACKAGE_SHA=$(shasum -a 256 "$PACKAGE_ZIP" | cut -f 1 -d ' ')
PACKAGE_SIZE=`get_file_size "$PACKAGE_ZIP"` PACKAGE_SIZE=$(get_file_size "$PACKAGE_ZIP")
popd >/dev/null popd >/dev/null
rm -rf "$PKG_DIR" rm -rf "$PKG_DIR"
echo "'$PACKAGE_ZIP' Created! Size: $PACKAGE_SIZE, SHA-256: $PACKAGE_SHA" echo "'$PACKAGE_ZIP' Created! Size: $PACKAGE_SIZE, SHA-256: $PACKAGE_SHA"
@ -274,7 +302,7 @@ echo
# Upload package to release page # Upload package to release page
echo "Uploading 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 "Package Uploaded"
echo "Download URL: $PACKAGE_URL" echo "Download URL: $PACKAGE_URL"
echo echo
@ -282,9 +310,9 @@ echo
## ##
## TEMP WORKAROUND FOR RV32 LONG PATH ON WINDOWS ## 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 -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="\ rvtc_jq_arg="\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$RVTC_NAME\")).version = \"$RVTC_VERSION\" |\ (.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\" |\ (.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\")).version = \"$RVTC_VERSION\" |\
(.packages[0].platforms[0].toolsDependencies[] | select(.name==\"$X32TC_NAME\")).name = \"$X32TC_NEW_NAME\" |\ (.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\")).version = \"$RVTC_VERSION\" |\
(.packages[0].tools[] | select(.name==\"$X32TC_NAME\")).name = \"$X32TC_NEW_NAME\" |\ (.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\""
cat "$PACKAGE_JSON_TEMPLATE" | jq "$rvtc_jq_arg" > "$OUTPUT_DIR/package-rvfix.json" cat "$PACKAGE_JSON_TEMPLATE" | jq "$rvtc_jq_arg" > "$OUTPUT_DIR/package-rvfix.json"
PACKAGE_JSON_TEMPLATE="$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\"" .packages[0].platforms[0].checksum = \"SHA-256:$PACKAGE_SHA\""
# Generate package JSONs # 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" cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_DEV"
if [ "$RELEASE_PRE" == "false" ]; then 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" cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_REL"
fi fi
# Figure out the last release or pre-release # Figure out the last release or pre-release
echo "Getting previous releases ..." echo "Getting previous releases ..."
releasesJson=`curl -sH "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$GITHUB_REPOSITORY/releases" 2>/dev/null` 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 if [ $? -ne 0 ]; then
echo "ERROR: Get Releases Failed! ($?)"
exit 1
fi
set +e set +e
prev_release=$(echo "$releasesJson" | jq -e -r ". | map(select(.draft == false and .prerelease == false)) | sort_by(.published_at | - fromdateiso8601) | .[0].tag_name") 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 echo
# Merge package JSONs with previous releases # 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 ..." echo "Merging with JSON from $prev_any_release ..."
merge_package_json "$prev_any_release/$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV" merge_package_json "$prev_any_release/$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV"
fi fi
if [ "$RELEASE_PRE" == "false" ]; then 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 ..." echo "Merging with JSON from $prev_release ..."
merge_package_json "$prev_release/$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL" merge_package_json "$prev_release/$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL"
fi fi
@ -363,21 +386,30 @@ fi
echo "Installing arduino-cli ..." echo "Installing arduino-cli ..."
export PATH="/home/runner/bin:$PATH" 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 "Testing $PACKAGE_JSON_DEV install ..."
echo "Installing esp32 ..." echo "Installing esp32 ..."
arduino-cli core install esp32:esp32 --additional-urls "file://$OUTPUT_DIR/$PACKAGE_JSON_DEV" 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 ..." echo "Compiling example ..."
arduino-cli compile --fqbn esp32:esp32:esp32 $GITHUB_WORKSPACE/libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino 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 if [ $? -ne 0 ]; then
echo "ERROR: Failed to compile example ($?)"
exit 1
fi
echo "Uninstalling esp32 ..." echo "Uninstalling esp32 ..."
arduino-cli core uninstall esp32: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!" echo "Test successful!"
@ -386,15 +418,24 @@ if [ "$RELEASE_PRE" == "false" ]; then
echo "Installing esp32 ..." echo "Installing esp32 ..."
arduino-cli core install esp32:esp32 --additional-urls "file://$OUTPUT_DIR/$PACKAGE_JSON_REL" 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 ..." echo "Compiling example ..."
arduino-cli compile --fqbn esp32:esp32:esp32 $GITHUB_WORKSPACE/libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino 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 if [ $? -ne 0 ]; then
echo "ERROR: Failed to compile example ($?)"
exit 1
fi
echo "Uninstalling esp32 ..." echo "Uninstalling esp32 ..."
arduino-cli core uninstall esp32: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!" echo "Test successful!"
fi fi
@ -402,13 +443,13 @@ fi
# Upload package JSONs # Upload package JSONs
echo "Uploading $PACKAGE_JSON_DEV ..." echo "Uploading $PACKAGE_JSON_DEV ..."
echo "Download URL: "`git_safe_upload_asset "$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 "Pages URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV")"
echo echo
if [ "$RELEASE_PRE" == "false" ]; then if [ "$RELEASE_PRE" == "false" ]; then
echo "Uploading $PACKAGE_JSON_REL ..." echo "Uploading $PACKAGE_JSON_REL ..."
echo "Download URL: "`git_safe_upload_asset "$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 "Pages URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL")"
echo echo
fi fi

View file

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

View file

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

View file

@ -3,14 +3,14 @@
USAGE=" USAGE="
USAGE: USAGE:
${0} -c -type <test_type> <chunk_build_opts> ${0} -c -type <test_type> <chunk_build_opts>
Example: ${0} -c -type validation -t esp32 -i 0 -m 15 Example: ${0} -c -type validation -t esp32 -i 0 -m 15
${0} -s sketch_name <build_opts> ${0} -s sketch_name <build_opts>
Example: ${0} -s hello_world -t esp32 Example: ${0} -s hello_world -t esp32
${0} -clean ${0} -clean
Remove build and test generated files Remove build and test generated files
" "
function clean(){ function clean {
rm -rf tests/.pytest_cache rm -rf tests/.pytest_cache
find tests/ -type d -name 'build*' -exec rm -rf "{}" \+ find tests/ -type d -name 'build*' -exec rm -rf "{}" \+
find tests/ -type d -name '__pycache__' -exec rm -rf "{}" \+ find tests/ -type d -name '__pycache__' -exec rm -rf "{}" \+
@ -23,7 +23,7 @@ BUILD_CMD=""
chunk_build=0 chunk_build=0
while [ ! -z "$1" ]; do while [ -n "$1" ]; do
case $1 in case $1 in
-c ) -c )
chunk_build=1 chunk_build=1
@ -45,25 +45,25 @@ while [ ! -z "$1" ]; do
exit 0 exit 0
;; ;;
* ) * )
break break
;; ;;
esac esac
shift shift
done done
source ${SCRIPTS_DIR}/install-arduino-cli.sh source "${SCRIPTS_DIR}/install-arduino-cli.sh"
source ${SCRIPTS_DIR}/install-arduino-core-esp32.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 [[ $test_type == "all" ]] || [[ -z $test_type ]]; then
if [ -n "$sketch" ]; then if [ -n "$sketch" ]; then
tmp_sketch_path=$(find tests -name $sketch.ino) tmp_sketch_path=$(find tests -name "$sketch".ino)
test_type=$(basename $(dirname $(dirname "$tmp_sketch_path"))) test_type=$(basename "$(dirname "$(dirname "$tmp_sketch_path")")")
echo "Sketch $sketch test type: $test_type" echo "Sketch $sketch test type: $test_type"
test_folder="$PWD/tests/$test_type" test_folder="$PWD/tests/$test_type"
else else
test_folder="$PWD/tests" test_folder="$PWD/tests"
fi fi
else else
test_folder="$PWD/tests/$test_type" test_folder="$PWD/tests/$test_type"
@ -71,11 +71,10 @@ fi
if [ $chunk_build -eq 1 ]; then if [ $chunk_build -eq 1 ]; then
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh chunk_build" 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 else
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh build" BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh build"
args+=" -s $test_folder/$sketch" args+=("-s" "$test_folder/$sketch")
fi fi
${BUILD_CMD} ${args} $* ${BUILD_CMD} "${args[@]}" "$@"

View file

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

View file

@ -1,126 +1,130 @@
#!/bin/bash #!/bin/bash
function run_test() { function run_test {
local target=$1 local target=$1
local sketch=$2 local sketch=$2
local options=$3 local options=$3
local erase_flash=$4 local erase_flash=$4
local sketchdir=$(dirname $sketch) local sketchdir
local sketchname=$(basename $sketchdir) local sketchname
local result=0 local result=0
local error=0 local error=0
local sdkconfig_path local sdkconfig_path
local extra_args
if [ $options -eq 0 ] && [ -f $sketchdir/ci.json ]; then sketchdir=$(dirname "$sketch")
len=`jq -r --arg target $target '.fqbn[$target] | length' $sketchdir/ci.json` sketchname=$(basename "$sketchdir")
if [ $len -eq 0 ]; then
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 len=1
fi fi
else else
len=1 len=1
fi fi
if [ $len -eq 1 ]; then if [ "$len" -eq 1 ]; then
sdkconfig_path="$HOME/.arduino/tests/$sketchname/build.tmp/sdkconfig" sdkconfig_path="$HOME/.arduino/tests/$sketchname/build.tmp/sdkconfig"
else else
sdkconfig_path="$HOME/.arduino/tests/$sketchname/build0.tmp/sdkconfig" sdkconfig_path="$HOME/.arduino/tests/$sketchname/build0.tmp/sdkconfig"
fi 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. # 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) is_target=$(jq -r --arg target "$target" '.targets[$target]' "$sketchdir"/ci.json)
selected_platform=$(jq -r --arg platform $platform '.platforms[$platform]' $sketchdir/ci.json) selected_platform=$(jq -r --arg platform "$platform" '.platforms[$platform]' "$sketchdir"/ci.json)
if [[ $is_target == "false" ]] || [[ $selected_platform == "false" ]]; then 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" printf "\n\n\n"
return 0 return 0
fi fi
fi fi
if [ ! -f $sdkconfig_path ]; then if [ ! -f "$sdkconfig_path" ]; then
printf "\033[93mSketch $sketchname not built\nMight be due to missing target requirements or build failure\033[0m\n" printf "\033[93mSketch %s not built\nMight be due to missing target requirements or build failure\033[0m\n" "$sketchname"
printf "\n\n\n" printf "\n\n\n"
return 0 return 0
fi 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 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" printf "\n\n\n"
return 1 return 1
fi fi
if [ $len -eq 1 ]; then if [ "$len" -eq 1 ]; then
# build_dir="$sketchdir/build" # build_dir="$sketchdir/build"
build_dir="$HOME/.arduino/tests/$sketchname/build.tmp" build_dir="$HOME/.arduino/tests/$sketchname/build.tmp"
report_file="$sketchdir/$target/$sketchname.xml" report_file="$sketchdir/$target/$sketchname.xml"
fi fi
for i in `seq 0 $(($len - 1))` for i in $(seq 0 $((len - 1))); do
do
fqbn="Default" fqbn="Default"
if [ $len -ne 1 ]; then if [ "$len" -ne 1 ]; then
fqbn=`jq -r --arg target $target --argjson i $i '.fqbn[$target] | sort | .[$i]' $sketchdir/ci.json` fqbn=$(jq -r --arg target "$target" --argjson i "$i" '.fqbn[$target] | sort | .[$i]' "$sketchdir"/ci.json)
elif [ -f $sketchdir/ci.json ]; then elif [ -f "$sketchdir"/ci.json ]; then
has_fqbn=`jq -r --arg target $target '.fqbn[$target]' $sketchdir/ci.json` has_fqbn=$(jq -r --arg target "$target" '.fqbn[$target]' "$sketchdir"/ci.json)
if [ "$has_fqbn" != "null" ]; then 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
fi fi
printf "\033[95mRunning test: $sketchname -- Config: $fqbn\033[0m\n" printf "\033[95mRunning test: %s -- Config: %s\033[0m\n" "$sketchname" "$fqbn"
if [ $erase_flash -eq 1 ]; then if [ "$erase_flash" -eq 1 ]; then
esptool.py -c $target erase_flash esptool.py -c "$target" erase_flash
fi fi
if [ $len -ne 1 ]; then if [ "$len" -ne 1 ]; then
# build_dir="$sketchdir/build$i" # build_dir="$sketchdir/build$i"
build_dir="$HOME/.arduino/tests/$sketchname/build$i.tmp" build_dir="$HOME/.arduino/tests/$sketchname/build$i.tmp"
report_file="$sketchdir/$target/$sketchname$i.xml" report_file="$sketchdir/$target/$sketchname$i.xml"
fi fi
if [ $platform == "wokwi" ]; then 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 if [[ -f "$sketchdir/scenario.yaml" ]]; then
extra_args+=" --wokwi-scenario $sketchdir/scenario.yaml" extra_args+=("--wokwi-scenario" "$sketchdir/scenario.yaml")
fi fi
if [[ -f "$sketchdir/diagram.$target.json" ]]; then if [[ -f "$sketchdir/diagram.$target.json" ]]; then
extra_args+=" --wokwi-diagram $sketchdir/diagram.$target.json" extra_args+=("--wokwi-diagram" "$sketchdir/diagram.$target.json")
fi fi
elif [ $platform == "qemu" ]; then elif [ $platform == "qemu" ]; then
PATH=$HOME/qemu/bin:$PATH 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 if [ "$target" == "esp32" ] || [ "$target" == "esp32s3" ]; then
extra_args+=" --qemu-prog-path qemu-system-xtensa --qemu-cli-args=\"-machine $target -m 4M -nographic\"" extra_args+=("--qemu-prog-path" "qemu-system-xtensa" "--qemu-cli-args=\"-machine $target -m 4M -nographic\"")
elif [ $target == "esp32c3" ]; then elif [ "$target" == "esp32c3" ]; then
extra_args+=" --qemu-prog-path qemu-system-riscv32 --qemu-cli-args=\"-machine $target -icount 3 -nographic\"" extra_args+=("--qemu-prog-path" "qemu-system-riscv32" "--qemu-cli-args=\"-machine $target -icount 3 -nographic\"")
else else
printf "\033[91mUnsupported QEMU target: $target\033[0m\n" printf "\033[91mUnsupported QEMU target: %s\033[0m\n" "$target"
exit 1 exit 1
fi fi
else else
extra_args="--embedded-services esp,arduino" extra_args=("--embedded-services" "esp,arduino")
fi fi
rm $sketchdir/diagram.json 2>/dev/null || true rm "$sketchdir"/diagram.json 2>/dev/null || true
result=0 result=0
printf "\033[95mpytest $sketchdir/test_$sketchname.py --build-dir $build_dir --junit-xml=$report_file $extra_args\033[0m\n" 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; exit \$?" || result=$? bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" ${extra_args[*]@Q}; exit \$?" || result=$?
printf "\n" printf "\n"
if [ $result -ne 0 ]; then if [ $result -ne 0 ]; then
result=0 result=0
printf "\033[95mRetrying test: $sketchname -- Config: $i\033[0m\n" printf "\033[95mRetrying test: %s -- Config: %s\033[0m\n" "$sketchname" "$i"
printf "\033[95mpytest $sketchdir/test_$sketchname.py --build-dir $build_dir --junit-xml=$report_file $extra_args\033[0m\n" 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; exit \$?" || result=$? bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" ${extra_args[*]@Q}; exit \$?" || result=$?
printf "\n" printf "\n"
if [ $result -ne 0 ]; then 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 error=$result
fi fi
fi fi
done done
@ -136,13 +140,13 @@ chunk_run=0
options=0 options=0
erase=0 erase=0
while [ ! -z "$1" ]; do while [ -n "$1" ]; do
case $1 in case $1 in
-c ) -c )
chunk_run=1 chunk_run=1
;; ;;
-Q ) -Q )
if [ ! -d $QEMU_PATH ]; then if [ ! -d "$QEMU_PATH" ]; then
echo "QEMU path $QEMU_PATH does not exist" echo "QEMU path $QEMU_PATH does not exist"
exit 1 exit 1
fi fi
@ -188,98 +192,97 @@ while [ ! -z "$1" ]; do
test_type=$1 test_type=$1
;; ;;
* ) * )
break break
;; ;;
esac esac
shift shift
done done
if [ ! $platform == "qemu" ]; then if [ ! $platform == "qemu" ]; then
source ${SCRIPTS_DIR}/install-arduino-ide.sh source "${SCRIPTS_DIR}/install-arduino-ide.sh"
fi fi
# If sketch is provided and test type is not, test type is inferred from the sketch path # 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 [[ $test_type == "all" ]] || [[ -z $test_type ]]; then
if [ -n "$sketch" ]; then if [ -n "$sketch" ]; then
tmp_sketch_path=$(find tests -name $sketch.ino) tmp_sketch_path=$(find tests -name "$sketch".ino)
test_type=$(basename $(dirname $(dirname "$tmp_sketch_path"))) test_type=$(basename "$(dirname "$(dirname "$tmp_sketch_path")")")
echo "Sketch $sketch test type: $test_type" echo "Sketch $sketch test type: $test_type"
test_folder="$PWD/tests/$test_type" test_folder="$PWD/tests/$test_type"
else else
test_folder="$PWD/tests" test_folder="$PWD/tests"
fi fi
else else
test_folder="$PWD/tests/$test_type" test_folder="$PWD/tests/$test_type"
fi fi
if [ $chunk_run -eq 0 ]; then if [ $chunk_run -eq 0 ]; then
if [ -z $sketch ]; then if [ -z "$sketch" ]; then
echo "ERROR: Sketch name is required for single test run" echo "ERROR: Sketch name is required for single test run"
exit 1 exit 1
fi fi
run_test $target $test_folder/$sketch/$sketch.ino $options $erase run_test "$target" "$test_folder"/"$sketch"/"$sketch".ino $options $erase
exit $? exit $?
else else
if [ "$chunk_max" -le 0 ]; then if [ "$chunk_max" -le 0 ]; then
echo "ERROR: Chunks count must be positive number" echo "ERROR: Chunks count must be positive number"
exit 1 exit 1
fi fi
if [ "$chunk_index" -ge "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then if [ "$chunk_index" -ge "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then
echo "ERROR: Chunk index must be less than chunks count" echo "ERROR: Chunk index must be less than chunks count"
exit 1 exit 1
fi fi
set +e set +e
# Ignore requirements as we don't have the libs. The requirements will be checked in the run_test function # Ignore requirements as we don't have the libs. The requirements will be checked in the run_test function
${COUNT_SKETCHES} "$test_folder" "$target" "1" ${COUNT_SKETCHES} "$test_folder" "$target" "1"
sketchcount=$? sketchcount=$?
set -e set -e
sketches=$(cat sketches.txt) sketches=$(cat sketches.txt)
rm -rf sketches.txt rm -rf sketches.txt
chunk_size=$(( $sketchcount / $chunk_max )) chunk_size=$(( sketchcount / chunk_max ))
all_chunks=$(( $chunk_max * $chunk_size )) all_chunks=$(( chunk_max * chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 )) chunk_size=$(( chunk_size + 1 ))
fi fi
start_index=0 start_index=0
end_index=0 end_index=0
if [ "$chunk_index" -ge "$chunk_max" ]; then if [ "$chunk_index" -ge "$chunk_max" ]; then
start_index=$chunk_index start_index=$chunk_index
end_index=$sketchcount end_index=$sketchcount
else else
start_index=$(( $chunk_index * $chunk_size )) start_index=$(( chunk_index * chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then if [ "$sketchcount" -le "$start_index" ]; then
exit 0 exit 0
fi fi
end_index=$(( $(( $chunk_index + 1 )) * $chunk_size )) end_index=$(( $(( chunk_index + 1 )) * chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount end_index=$sketchcount
fi fi
fi fi
start_num=$(( $start_index + 1 )) sketchnum=0
sketchnum=0 error=0
error=0
for sketch in $sketches; do for sketch in $sketches; do
sketchnum=$(($sketchnum + 1)) sketchnum=$((sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \ if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then || [ "$sketchnum" -gt "$end_index" ]; then
continue continue
fi fi
printf "\033[95mSketch Index $(($sketchnum - 1))\033[0m\n" printf "\033[95mSketch Index %s\033[0m\n" "$((sketchnum - 1))"
exit_code=0 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 if [ $exit_code -ne 0 ]; then
error=$exit_code error=$exit_code
fi fi
done done
exit $error exit $error
fi fi

View file

@ -1,20 +1,21 @@
#!/bin/bash #!/bin/bash
# shellcheck disable=SC2002
# For reference: add tools for all boards by replacing one line in each board # 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" # "[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"
#cat boards.txt | sed "s/\([a-zA-Z0-9_\-]*\)\.upload\.tool\=esptool_py/\1\.upload\.tool\=esptool_py\\n\1\.upload\.tool\.default\=esptool_py\\n\1\.upload\.tool\.network\=esp_ota/" #cat boards.txt | sed "s/\([a-zA-Z0-9_\-]*\)\.upload\.tool\=esptool_py/\1\.upload\.tool\=esptool_py\\n\1\.upload\.tool\.default\=esptool_py\\n\1\.upload\.tool\.network\=esp_ota/"
if [ ! $# -eq 3 ]; then if [ ! $# -eq 3 ]; then
echo "Bad number of arguments: $#" >&2 echo "Bad number of arguments: $#" >&2
echo "usage: $0 <major> <minor> <patch>" >&2 echo "usage: $0 <major> <minor> <patch>" >&2
exit 1 exit 1
fi fi
re='^[0-9]+$' re='^[0-9]+$'
if [[ ! $1 =~ $re ]] || [[ ! $2 =~ $re ]] || [[ ! $3 =~ $re ]] ; then if [[ ! $1 =~ $re ]] || [[ ! $2 =~ $re ]] || [[ ! $3 =~ $re ]] ; then
echo "error: Not a valid version: $1.$2.$3" >&2 echo "error: Not a valid version: $1.$2.$3" >&2
echo "usage: $0 <major> <minor> <patch>" >&2 echo "usage: $0 <major> <minor> <patch>" >&2
exit 1 exit 1
fi fi
ESP_ARDUINO_VERSION_MAJOR="$1" ESP_ARDUINO_VERSION_MAJOR="$1"
@ -36,11 +37,12 @@ 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_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 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 {} \;)
if [ -f "libraries/$lib/library.properties" ]; then for lib in $libraries; do
echo "Updating Library $lib..." if [ -f "libraries/$lib/library.properties" ]; then
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" echo "Updating Library $lib..."
fi 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"
fi
done done
exit 0 exit 0

View file

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

View file

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

View file

@ -4,9 +4,9 @@ name: Boards Test
on: on:
pull_request: pull_request:
paths: paths:
- 'boards.txt' - "boards.txt"
- 'libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino' - "libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino"
- '.github/workflows/boards.yml' - ".github/workflows/boards.yml"
env: env:
# It's convenient to set variables for values used multiple times in the workflow # 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 uses: dcarbone/install-jq-action@v1.0.1
- name: Get board name - name: Get board name
run: run: bash .github/scripts/find_new_boards.sh ${{ github.repository }} ${{github.base_ref}}
bash .github/scripts/find_new_boards.sh ${{ github.repository }} ${{github.base_ref}}
test-boards: test-boards:
needs: find-boards needs: find-boards
@ -72,7 +71,7 @@ jobs:
./tools/openocd-esp32 ./tools/openocd-esp32
./tools/riscv32-* ./tools/riscv32-*
./tools/xtensa-* ./tools/xtensa-*
- name: Compile sketch - name: Compile sketch
uses: P-R-O-C-H-Y/compile-sketches@main uses: P-R-O-C-H-Y/compile-sketches@main
with: with:
@ -85,6 +84,5 @@ jobs:
cli-compile-flags: | cli-compile-flags: |
- --warnings="all" - --warnings="all"
exit-on-fail: true exit-on-fail: true
sketch-paths: sketch-paths: "- ./libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino"
"- ./libraries/ESP32/examples/CI/CIBoardsTest/CIBoardsTest.ino"
verbose: true verbose: true

View file

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

View file

@ -11,14 +11,14 @@ jobs:
pull-request-style-linter: pull-request-style-linter:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out PR head - name: Check out PR head
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: DangerJS pull request linter - name: DangerJS pull request linter
uses: espressif/shared-github-dangerjs@v1 uses: espressif/shared-github-dangerjs@v1
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
rule-max-commits: 'false' rule-max-commits: "false"
commit-messages-min-summary-length: '10' commit-messages-min-summary-length: "10"

View file

@ -3,18 +3,17 @@ name: Documentation Build and Deploy CI
on: on:
push: push:
branches: branches:
- master - master
- release/v2.x - release/v2.x
paths: paths:
- 'docs/**' - "docs/**"
- '.github/workflows/docs_build.yml' - ".github/workflows/docs_build.yml"
pull_request: pull_request:
paths: paths:
- 'docs/**' - "docs/**"
- '.github/workflows/docs_build.yml' - ".github/workflows/docs_build.yml"
jobs: jobs:
build-docs: build-docs:
name: Build ESP-Docs name: Build ESP-Docs
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
@ -22,25 +21,25 @@ jobs:
run: run:
shell: bash shell: bash
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
submodules: true submodules: true
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
cache-dependency-path: docs/requirements.txt cache-dependency-path: docs/requirements.txt
cache: 'pip' cache: "pip"
python-version: '3.10' python-version: "3.10"
- name: Build - name: Build
run: | run: |
sudo apt update sudo apt update
sudo apt install python3-pip python3-setuptools sudo apt install python3-pip python3-setuptools
# GitHub CI installs pip3 and setuptools outside the path. # GitHub CI installs pip3 and setuptools outside the path.
# Update the path to include them and run. # Update the path to include them and run.
cd ./docs cd ./docs
PATH=/home/runner/.local/bin:$PATH pip3 install -r requirements.txt --prefer-binary PATH=/home/runner/.local/bin:$PATH pip3 install -r requirements.txt --prefer-binary
PATH=/home/runner/.local/bin:$PATH SPHINXOPTS="-W" build-docs -l en PATH=/home/runner/.local/bin:$PATH SPHINXOPTS="-W" build-docs -l en
- name: Archive Docs - name: Archive Docs
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: docs name: docs
path: docs path: docs

View file

@ -7,11 +7,11 @@ on:
- completed - completed
push: push:
branches: branches:
- release/v2.x - release/v2.x
- master - master
paths: paths:
- 'docs/**' - "docs/**"
- '.github/workflows/docs_deploy.yml' - ".github/workflows/docs_deploy.yml"
jobs: jobs:
deploy-prod-docs: deploy-prod-docs:
@ -21,39 +21,39 @@ jobs:
run: run:
shell: bash shell: bash
steps: steps:
- name: Check if release workflow is successful - name: Check if release workflow is successful
if: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.conclusion != 'success' }} if: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.conclusion != 'success' }}
run: | run: |
echo "Release workflow failed. Exiting..." echo "Release workflow failed. Exiting..."
exit 1 exit 1
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
submodules: true submodules: true
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
cache-dependency-path: docs/requirements.txt cache-dependency-path: docs/requirements.txt
cache: 'pip' cache: "pip"
python-version: '3.10' python-version: "3.10"
- name: Deploy Documentation - name: Deploy Documentation
env: env:
# Deploy to production server # Deploy to production server
# DOCS_BUILD_DIR: "./docs/_build/" # DOCS_BUILD_DIR: "./docs/_build/"
DOCS_DEPLOY_PRIVATEKEY: ${{ secrets.DOCS_KEY }} DOCS_DEPLOY_PRIVATEKEY: ${{ secrets.DOCS_KEY }}
DOCS_DEPLOY_PATH: ${{ secrets.DOCS_PATH }} DOCS_DEPLOY_PATH: ${{ secrets.DOCS_PATH }}
DOCS_DEPLOY_SERVER: ${{ secrets.DOCS_SERVER }} DOCS_DEPLOY_SERVER: ${{ secrets.DOCS_SERVER }}
DOCS_DEPLOY_SERVER_USER: ${{ secrets.DOCS_USER }} DOCS_DEPLOY_SERVER_USER: ${{ secrets.DOCS_USER }}
DOCS_DEPLOY_URL_BASE: ${{ secrets.DOCS_URL }} DOCS_DEPLOY_URL_BASE: ${{ secrets.DOCS_URL }}
run: | run: |
sudo apt update sudo apt update
sudo apt install python3-pip python3-setuptools sudo apt install python3-pip python3-setuptools
source ./docs/utils.sh source ./docs/utils.sh
add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
export GIT_VER=$(git describe --always) export GIT_VER=$(git describe --always)
echo "PIP install requirements..." echo "PIP install requirements..."
pip3 install --user -r ./docs/requirements.txt pip3 install --user -r ./docs/requirements.txt
echo "Building the Docs..." echo "Building the Docs..."
cd ./docs && build-docs -l en cd ./docs && build-docs -l en
echo "Deploy the Docs..." echo "Deploy the Docs..."
export DOCS_BUILD_DIR=$GITHUB_WORKSPACE/docs/ export DOCS_BUILD_DIR=$GITHUB_WORKSPACE/docs/
cd $GITHUB_WORKSPACE/docs cd $GITHUB_WORKSPACE/docs
deploy-docs deploy-docs

View file

@ -3,21 +3,20 @@ name: GitHub Pages CI
on: on:
push: push:
branches: branches:
- master - master
- pages - pages
paths: paths:
- 'README.md' - "README.md"
- '.github/scripts/on-pages.sh' - ".github/scripts/on-pages.sh"
- '.github/workflows/gh-pages.yml' - ".github/workflows/gh-pages.yml"
jobs: jobs:
build-pages: build-pages:
name: Build GitHub Pages name: Build GitHub Pages
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Copy Files - name: Copy Files
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash ./.github/scripts/on-pages.sh run: bash ./.github/scripts/on-pages.sh

View file

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

View file

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

View file

@ -47,7 +47,7 @@ jobs:
uses: juliangruber/read-file-action@v1 uses: juliangruber/read-file-action@v1
with: with:
path: ./artifacts/workflows/pr_num.txt path: ./artifacts/workflows/pr_num.txt
- name: Report results - name: Report results
uses: P-R-O-C-H-Y/report-size-deltas@libs uses: P-R-O-C-H-Y/report-size-deltas@libs
with: with:

View file

@ -11,11 +11,11 @@ env:
jobs: jobs:
sizes-test-results: sizes-test-results:
name: Sizes Comparsion Results name: Sizes Comparison Results
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 # This step checks out the repository's code at gh-pages branch uses: actions/checkout@v4 # This step checks out the repository's code at gh-pages branch
with: with:
ref: gh-pages ref: gh-pages
@ -41,8 +41,7 @@ jobs:
destination-file: ${{ env.RESULT_SIZES_TEST_FILE }} destination-file: ${{ env.RESULT_SIZES_TEST_FILE }}
- name: Append file with action URL - name: Append file with action URL
run: run: echo "/ [GitHub Action Link](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})" >> ${{ env.RESULT_SIZES_TEST_FILE }}
echo "/ [GitHub Action Link](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})" >> ${{ env.RESULT_SIZES_TEST_FILE }}
- name: Push to github repo - name: Push to github repo
run: | run: |

View file

@ -14,7 +14,7 @@ env:
jobs: jobs:
sizes-test-results: sizes-test-results:
name: Sizes Comparsion Results name: Sizes Comparison Results
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: | if: |
github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.event == 'pull_request' &&
@ -22,7 +22,7 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 # This step checks out the repository's code at gh-pages branch uses: actions/checkout@v4 # This step checks out the repository's code at gh-pages branch
with: with:
ref: gh-pages ref: gh-pages

View file

@ -2,32 +2,48 @@ name: Compilation Tests
on: on:
workflow_dispatch: 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: push:
branches: branches:
- master - master
- release/* - release/*
pull_request: pull_request:
paths: paths:
- 'cores/**' - "cores/**"
- 'libraries/**' - "libraries/**"
- '!libraries/**.md' - "!libraries/**.md"
- '!libraries/**.txt' - "!libraries/**.txt"
- '!libraries/**.properties' - "!libraries/**.properties"
- '!libraries/**.py' - "!libraries/**.py"
- 'package/**' - "package/**"
- 'tools/**.py' - "tools/**.py"
- 'platform.txt' - "platform.txt"
- 'programmers.txt' - "programmers.txt"
- 'idf_component.yml' - "idf_component.yml"
- 'Kconfig.projbuild' - "Kconfig.projbuild"
- 'package.json' - "package.json"
- 'CMakeLists.txt' - "CMakeLists.txt"
- '.github/workflows/push.yml' - ".github/workflows/push.yml"
- '.github/scripts/**' - ".github/scripts/**"
- '!.github/scripts/find_*' - "!.github/scripts/find_*"
- '!.github/scripts/on-release.sh' - "!.github/scripts/on-release.sh"
- '!.github/scripts/tests_*' - "!.github/scripts/tests_*"
- '!.github/scripts/upload_*' - "!.github/scripts/upload_*"
- "variants/esp32/**/*" - "variants/esp32/**/*"
- "variants/esp32s2/**/*" - "variants/esp32s2/**/*"
- "variants/esp32s3/**/*" - "variants/esp32s3/**/*"
@ -49,8 +65,8 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ !(github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/')) }} if: ${{ !(github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/')) }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: bash ./.github/scripts/check-cmakelists.sh - run: bash ./.github/scripts/check-cmakelists.sh
gen-chunks: gen-chunks:
name: Generate chunks name: Generate chunks
@ -61,27 +77,24 @@ jobs:
build_libraries: ${{ steps.set-chunks.outputs.build_libraries }} build_libraries: ${{ steps.set-chunks.outputs.build_libraries }}
build_static_sketches: ${{ steps.set-chunks.outputs.build_static_sketches }} build_static_sketches: ${{ steps.set-chunks.outputs.build_static_sketches }}
build_idf: ${{ steps.set-chunks.outputs.build_idf }} build_idf: ${{ steps.set-chunks.outputs.build_idf }}
build_platformio: ${{ steps.set-chunks.outputs.build_platformio }}
chunk_count: ${{ steps.set-chunks.outputs.chunk_count }} chunk_count: ${{ steps.set-chunks.outputs.chunk_count }}
chunks: ${{ steps.set-chunks.outputs.chunks }} chunks: ${{ steps.set-chunks.outputs.chunks }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 2 fetch-depth: 2
- name: Get changed files - name: Get changed files
id: changed-files id: changed-files
uses: tj-actions/changed-files@v44 uses: tj-actions/changed-files@v44
with: with:
files_yaml: | files_yaml: |
core: core:
- '.github/**' - '.github/**'
- '!.github/scripts/install-platformio-esp32.sh'
- 'cores/**' - 'cores/**'
- 'package/**' - 'package/**'
- 'tools/**' - 'tools/**'
- '!tools/platformio-build.py'
- 'platform.txt' - 'platform.txt'
- 'programmers.txt' - 'programmers.txt'
- "variants/esp32/**/*" - "variants/esp32/**/*"
@ -110,36 +123,31 @@ jobs:
- 'Kconfig.projbuild' - 'Kconfig.projbuild'
- 'CMakeLists.txt' - 'CMakeLists.txt'
- "variants/esp32c2/**/*" - "variants/esp32c2/**/*"
platformio:
- 'package.json'
- '.github/scripts/install-platformio-esp32.sh'
- 'tools/platformio-build.py'
- name: Set chunks - name: Set chunks
id: set-chunks id: set-chunks
env: env:
LIB_FILES: ${{ steps.changed-files.outputs.libraries_all_changed_files }} LIB_FILES: ${{ steps.changed-files.outputs.libraries_all_changed_files }}
IS_PR: ${{ github.event_name == 'pull_request' }} IS_PR: ${{ github.event_name == 'pull_request' }}
MAX_CHUNKS: ${{ env.MAX_CHUNKS }} 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_IDF: ${{ steps.changed-files.outputs.idf_any_changed == 'true' }} BUILD_LIBRARIES: ${{ steps.changed-files.outputs.libraries_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' }}
BUILD_STATIC_SKETCHES: ${{ steps.changed-files.outputs.static_sketeches_any_changed == 'true' }} FS_CHANGED: ${{ steps.changed-files.outputs.fs_any_changed == 'true' }}
FS_CHANGED: ${{ steps.changed-files.outputs.fs_any_changed == 'true' }} NETWORKING_CHANGED: ${{ steps.changed-files.outputs.networking_any_changed == 'true' }}
NETWORKING_CHANGED: ${{ steps.changed-files.outputs.networking_any_changed == 'true' }} CORE_CHANGED: ${{ steps.changed-files.outputs.core_any_changed == 'true' }}
CORE_CHANGED: ${{ steps.changed-files.outputs.core_any_changed == 'true' }} LIB_CHANGED: ${{ steps.changed-files.outputs.libraries_any_changed == 'true' }}
LIB_CHANGED: ${{ steps.changed-files.outputs.libraries_any_changed == 'true' }} run: |
run: | bash ./.github/scripts/set_push_chunks.sh
bash ./.github/scripts/set_push_chunks.sh
- name: Upload sketches found - name: Upload sketches found
if: ${{ steps.set-chunks.outputs.build_all == 'false' && steps.set-chunks.outputs.build_libraries == 'true' }} if: ${{ steps.set-chunks.outputs.build_all == 'false' && steps.set-chunks.outputs.build_libraries == 'true' }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: sketches_found name: sketches_found
path: sketches_found.txt path: sketches_found.txt
overwrite: true overwrite: true
if-no-files-found: error if-no-files-found: error
# Ubuntu # Ubuntu
build-arduino-linux: build-arduino-linux:
@ -153,45 +161,55 @@ jobs:
chunk: ${{ fromJson(needs.gen-chunks.outputs.chunks) }} chunk: ${{ fromJson(needs.gen-chunks.outputs.chunks) }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: '3.x' python-version: "3.x"
- name: Get libs cache - name: Get libs cache
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
key: libs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package/package_esp32_index.template.json', 'tools/get.py') }} key: libs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package/package_esp32_index.template.json', 'tools/get.py') }}
path: | path: |
./tools/dist ./tools/dist
./tools/esp32-arduino-libs ./tools/esp32-arduino-libs
./tools/esptool ./tools/esptool
./tools/mk* ./tools/mk*
./tools/openocd-esp32 ./tools/openocd-esp32
./tools/riscv32-* ./tools/riscv32-*
./tools/xtensa-* ./tools/xtensa-*
- name: Build all sketches - name: Set Log Level
if: ${{ needs.gen-chunks.outputs.build_all == 'true' }} run: |
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} ${{ env.MAX_CHUNKS }} 1 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: Download sketches found - name: Build all sketches
if: ${{ needs.gen-chunks.outputs.build_all == 'false' && needs.gen-chunks.outputs.build_libraries == 'true' }} if: ${{ needs.gen-chunks.outputs.build_all == 'true' }}
uses: actions/download-artifact@v4 run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} ${{ env.MAX_CHUNKS }} 1 ${{ env.LOG_LEVEL }}
with:
name: sketches_found
- name: Build selected sketches - name: Download sketches found
if: ${{ needs.gen-chunks.outputs.build_all == 'false' && needs.gen-chunks.outputs.build_libraries == 'true' }} 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 uses: actions/download-artifact@v4
with:
name: sketches_found
#Upload cli compile json as artifact - name: Build selected sketches
- name: Upload cli compile json if: ${{ needs.gen-chunks.outputs.build_all == 'false' && needs.gen-chunks.outputs.build_libraries == 'true' }}
uses: actions/upload-artifact@v4 run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} ${{ needs.gen-chunks.outputs.chunk_count }} 1 ${{ env.LOG_LEVEL }} sketches_found.txt
with:
name: pr_cli_compile_${{ matrix.chunk }} #Upload cli compile json as artifact
path: cli_compile_${{ matrix.chunk }}.json - name: Upload cli compile json
overwrite: true uses: actions/upload-artifact@v4
with:
name: pr_cli_compile_${{ matrix.chunk }}
path: cli_compile_${{ matrix.chunk }}.json
overwrite: true
# Windows and MacOS # Windows and MacOS
build-arduino-win-mac: build-arduino-win-mac:
@ -205,34 +223,12 @@ jobs:
os: [windows-latest, macOS-latest] os: [windows-latest, macOS-latest]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: '3.x' python-version: "3.x"
- name: Build Sketches - name: Build Sketches
run: bash ./.github/scripts/on-push.sh 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: build-esp-idf-component:
name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }} name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
@ -249,8 +245,18 @@ jobs:
# See https://hub.docker.com/r/espressif/idf/tags and # 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 # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html
# for details. # for details.
idf_ver: ["release-v5.1"] idf_ver: ["release-v5.3"]
idf_target: ["esp32", "esp32s2", "esp32s3", "esp32c2", "esp32c3", "esp32c6", "esp32h2"] idf_target:
[
"esp32",
"esp32s2",
"esp32s3",
"esp32c2",
"esp32c3",
"esp32c6",
"esp32h2",
"esp32p4"
]
container: espressif/idf:${{ matrix.idf_ver }} container: espressif/idf:${{ matrix.idf_ver }}
steps: steps:
- name: Check out arduino-esp32 as a component - name: Check out arduino-esp32 as a component
@ -275,16 +281,15 @@ jobs:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' if: github.event_name == 'push' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# Check out repository # Check out repository
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
token: ${{secrets.GITHUB_TOKEN}} token: ${{secrets.GITHUB_TOKEN}}
fetch-depth: '0' fetch-depth: "0"
- name: Switch branch - name: Switch branch
run: run: git checkout remotes/origin/gh-pages
git checkout remotes/origin/gh-pages
- name: Download sketches reports artifact - name: Download sketches reports artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4

View file

@ -10,15 +10,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: '3.x' python-version: "3.x"
- run: pip install packaging - run: pip install packaging
- run: pip install pyserial - run: pip install pyserial
- name: Build Release - name: Build Release
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash ./.github/scripts/on-release.sh run: bash ./.github/scripts/on-release.sh

View file

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

View file

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

View file

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

View file

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

View file

@ -18,11 +18,11 @@ jobs:
github.event.workflow_run.conclusion == 'timed_out' github.event.workflow_run.conclusion == 'timed_out'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
actions: write actions: write
statuses: write statuses: write
checks: write checks: write
pull-requests: write pull-requests: write
contents: write contents: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@ -139,22 +139,23 @@ jobs:
core.info(`${name} is ${state}`); core.info(`${name} is ${state}`);
- name: Create output folder - 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: | run: |
rm -rf artifacts rm -rf artifacts
mkdir -p runtime-tests-results mkdir -p runtime-tests-results
- name: Generate badge - 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 uses: jaywcjlove/generated-badges@v1.0.13
with: with:
label: Runtime Tests label: Runtime Tests
status: ${{ job.status }} status: ${{ job.status == 'success' && 'passing' || 'failing' }}
output: runtime-tests-results/badge.svg output: runtime-tests-results/badge.svg
color: ${{ job.status == 'success' && 'green' || 'red' }} color: ${{ job.status == 'success' && 'green' || 'red' }}
style: flat
- name: Push badge - 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: | run: |
git config user.name "github-actions[bot]" git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com" 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' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
with: with:
cache-dependency-path: tests/requirements.txt cache-dependency-path: tests/requirements.txt
cache: 'pip' cache: "pip"
python-version: '3.x' python-version: "3.x"
- name: Install dependencies - name: Install dependencies
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}

View file

@ -12,8 +12,9 @@ default_language_version:
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v4.5.0" rev: "v5.0.0"
hooks: hooks:
# Generic checks
- id: check-case-conflict - id: check-case-conflict
- id: check-symlinks - id: check-symlinks
- id: debug-statements - id: debug-statements
@ -25,6 +26,8 @@ repos:
args: [--fix=lf] args: [--fix=lf]
- id: trailing-whitespace - id: trailing-whitespace
args: [--markdown-linebreak-ext=md] args: [--markdown-linebreak-ext=md]
# JSON formatting
- id: pretty-format-json - id: pretty-format-json
stages: [manual] stages: [manual]
args: [--autofix] args: [--autofix]
@ -35,40 +38,67 @@ repos:
package\.json$| package\.json$|
^package\/.*$ ^package\/.*$
) )
- repo: https://github.com/codespell-project/codespell - repo: https://github.com/codespell-project/codespell
rev: "v2.3.0" rev: "v2.3.0"
hooks: hooks:
# Spell checking
- id: codespell - id: codespell
exclude: ^.*\.(svd|SVD)$ exclude: ^.*\.(svd|SVD)$
- repo: https://github.com/pre-commit/mirrors-clang-format - repo: https://github.com/pre-commit/mirrors-clang-format
rev: "v18.1.3" rev: "v18.1.3"
hooks: hooks:
# C/C++ formatting
- id: clang-format - id: clang-format
types_or: [c, c++] types_or: [c, c++]
exclude: ^.*\/build_opt\.h$ exclude: ^.*\/build_opt\.h$
- repo: https://github.com/psf/black-pre-commit-mirror - repo: https://github.com/psf/black-pre-commit-mirror
rev: "22.10.0" rev: "24.10.0"
hooks: hooks:
# Python formatting
- id: black - id: black
types_or: [python] types_or: [python]
args: [--line-length=120] #From the arduino code style. Add as argument rather than creating a new config file. 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 - repo: https://github.com/PyCQA/flake8
rev: "7.0.0" rev: "7.1.1"
hooks: hooks:
# Python linting
- id: flake8 - id: flake8
types_or: [python] types_or: [python]
additional_dependencies: additional_dependencies:
- flake8-bugbear - flake8-bugbear
- flake8-comprehensions - flake8-comprehensions
- flake8-simplify - flake8-simplify
- repo: https://github.com/pre-commit/mirrors-prettier - repo: https://github.com/pre-commit/mirrors-prettier
rev: "v3.1.0" rev: "v3.1.0"
hooks: hooks:
# YAML formatting
- id: prettier - id: prettier
types_or: [yaml] 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: 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 - id: vale
name: vale-sync name: vale-sync
language_version: "1.21.6" 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 # export ARDUINO_SKIP_IDF_VERSION_CHECK=1
# idf.py build # idf.py build
set(min_supported_idf_version "5.1.0") set(min_supported_idf_version "5.3.0")
set(max_supported_idf_version "5.1.99") set(max_supported_idf_version "5.3.99")
set(idf_version "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}") set(idf_version "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}")
if ("${idf_version}" AND NOT "$ENV{ARDUINO_SKIP_IDF_VERSION_CHECK}") if ("${idf_version}" AND NOT "$ENV{ARDUINO_SKIP_IDF_VERSION_CHECK}")
@ -25,6 +25,7 @@ endif()
set(CORE_SRCS set(CORE_SRCS
cores/esp32/base64.cpp cores/esp32/base64.cpp
cores/esp32/cbuf.cpp cores/esp32/cbuf.cpp
cores/esp32/ColorFormat.c
cores/esp32/chip-debug-report.cpp cores/esp32/chip-debug-report.cpp
cores/esp32/esp32-hal-adc.c cores/esp32/esp32-hal-adc.c
cores/esp32/esp32-hal-bt.c cores/esp32/esp32-hal-bt.c
@ -45,9 +46,11 @@ set(CORE_SRCS
cores/esp32/esp32-hal-timer.c cores/esp32/esp32-hal-timer.c
cores/esp32/esp32-hal-tinyusb.c cores/esp32/esp32-hal-tinyusb.c
cores/esp32/esp32-hal-touch.c cores/esp32/esp32-hal-touch.c
cores/esp32/esp32-hal-touch-ng.c
cores/esp32/esp32-hal-uart.c cores/esp32/esp32-hal-uart.c
cores/esp32/esp32-hal-rmt.c cores/esp32/esp32-hal-rmt.c
cores/esp32/Esp.cpp cores/esp32/Esp.cpp
cores/esp32/freertos_stats.cpp
cores/esp32/FunctionalInterrupt.cpp cores/esp32/FunctionalInterrupt.cpp
cores/esp32/HardwareSerial.cpp cores/esp32/HardwareSerial.cpp
cores/esp32/HEXBuilder.cpp cores/esp32/HEXBuilder.cpp
@ -93,6 +96,7 @@ set(ARDUINO_ALL_LIBRARIES
HTTPUpdate HTTPUpdate
Insights Insights
LittleFS LittleFS
Matter
NetBIOS NetBIOS
Network Network
OpenThread OpenThread
@ -116,7 +120,6 @@ set(ARDUINO_ALL_LIBRARIES
) )
set(ARDUINO_LIBRARY_ArduinoOTA_SRCS libraries/ArduinoOTA/src/ArduinoOTA.cpp) 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) 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_Insights_SRCS libraries/Insights/src/Insights.cpp)
set(ARDUINO_LIBRARY_LittleFS_SRCS libraries/LittleFS/src/LittleFS.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) 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.cpp
libraries/OpenThread/src/OThreadCLI_Util.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 set(ARDUINO_LIBRARY_PPP_SRCS
libraries/PPP/src/PPP.cpp libraries/PPP/src/PPP.cpp
libraries/PPP/src/ppp.c) libraries/PPP/src/ppp.c)
@ -258,10 +276,15 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS
libraries/Zigbee/src/ZigbeeHandlers.cpp libraries/Zigbee/src/ZigbeeHandlers.cpp
libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp
libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp
libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp
libraries/Zigbee/src/ep/ZigbeeLight.cpp libraries/Zigbee/src/ep/ZigbeeLight.cpp
libraries/Zigbee/src/ep/ZigbeeSwitch.cpp libraries/Zigbee/src/ep/ZigbeeSwitch.cpp
libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp
libraries/Zigbee/src/ep/ZigbeeThermostat.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 set(ARDUINO_LIBRARY_BLE_SRCS
@ -317,7 +340,7 @@ endforeach()
set(includedirs variants/${CONFIG_ARDUINO_VARIANT}/ cores/esp32/ ${ARDUINO_LIBRARIES_INCLUDEDIRS}) set(includedirs variants/${CONFIG_ARDUINO_VARIANT}/ cores/esp32/ ${ARDUINO_LIBRARIES_INCLUDEDIRS})
set(srcs ${CORE_SRCS} ${ARDUINO_LIBRARIES_SRCS}) set(srcs ${CORE_SRCS} ${ARDUINO_LIBRARIES_SRCS})
set(priv_includes cores/esp32/libb64) 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}) 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) 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()
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}) 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}") 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() endif()
endfunction() 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) maybe_add_component(arduino_tinyusb)
endif() endif()
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_ArduinoOTA) if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_ArduinoOTA)
maybe_add_component(esp_https_ota) maybe_add_component(esp_https_ota)
endif() 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 depends on ARDUINO_SELECTIVE_COMPILATION
default y default y
config ARDUINO_SELECTIVE_ESP_SR
bool "Enable ESP-SR"
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_EEPROM config ARDUINO_SELECTIVE_EEPROM
bool "Enable EEPROM" bool "Enable EEPROM"
depends on ARDUINO_SELECTIVE_COMPILATION depends on ARDUINO_SELECTIVE_COMPILATION
@ -286,6 +291,11 @@ config ARDUINO_SELECTIVE_Update
depends on ARDUINO_SELECTIVE_COMPILATION depends on ARDUINO_SELECTIVE_COMPILATION
default y default y
config ARDUINO_SELECTIVE_Zigbee
bool "Enable Zigbee"
depends on ARDUINO_SELECTIVE_COMPILATION
default y
config ARDUINO_SELECTIVE_FS config ARDUINO_SELECTIVE_FS
bool "Enable FS" bool "Enable FS"
depends on ARDUINO_SELECTIVE_COMPILATION depends on ARDUINO_SELECTIVE_COMPILATION
@ -358,6 +368,11 @@ config ARDUINO_SELECTIVE_HTTPClient
select ARDUINO_SELECTIVE_NetworkClientSecure select ARDUINO_SELECTIVE_NetworkClientSecure
default y default y
config ARDUINO_SELECTIVE_Matter
bool "Enable Matter"
depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Network
default y
config ARDUINO_SELECTIVE_NetBIOS config ARDUINO_SELECTIVE_NetBIOS
bool "Enable NetBIOS" bool "Enable NetBIOS"
depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Network depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Network
@ -399,4 +414,19 @@ config ARDUINO_SELECTIVE_SimpleBLE
depends on ARDUINO_SELECTIVE_COMPILATION depends on ARDUINO_SELECTIVE_COMPILATION
default y 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 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) ### 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 ### 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 ### 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-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-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-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] > [!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 > 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.name=ESP32H2 Dev Module
esp32h2.bootloader.tool=esptool_py 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=Zigbee RCP (radio co-processor)
esp32h2.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP 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.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=Zigbee RCP (radio co-processor)
esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP 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.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
############################################################## ##############################################################

View file

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

View file

@ -26,7 +26,9 @@
class Client : public Stream { class Client : public Stream {
public: public:
virtual int connect(IPAddress ip, uint16_t port) = 0; 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) = 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(uint8_t) = 0;
virtual size_t write(const uint8_t *buf, size_t size) = 0; virtual size_t write(const uint8_t *buf, size_t size) = 0;
virtual int available() = 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 #elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/spi_flash.h" #include "esp32h2/rom/spi_flash.h"
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32h2 is located at 0x0000 #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 #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif
@ -297,6 +300,7 @@ const char *EspClass::getChipModel(void) {
case CHIP_ESP32C2: return "ESP32-C2"; case CHIP_ESP32C2: return "ESP32-C2";
case CHIP_ESP32C6: return "ESP32-C6"; case CHIP_ESP32C6: return "ESP32-C6";
case CHIP_ESP32H2: return "ESP32-H2"; case CHIP_ESP32H2: return "ESP32-H2";
case CHIP_ESP32P4: return "ESP32-P4";
default: return "UNKNOWN"; default: return "UNKNOWN";
} }
#endif #endif
@ -335,6 +339,8 @@ uint32_t EspClass::getFlashChipSpeed(void) {
return magicFlashChipSpeed(fhdr.spi_speed); return magicFlashChipSpeed(fhdr.spi_speed);
} }
// FIXME for P4
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
FlashMode_t EspClass::getFlashChipMode(void) { FlashMode_t EspClass::getFlashChipMode(void) {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
uint32_t spi_ctrl = REG_READ(PERIPHS_SPI_FLASH_CTRL); uint32_t spi_ctrl = REG_READ(PERIPHS_SPI_FLASH_CTRL);
@ -361,6 +367,7 @@ FlashMode_t EspClass::getFlashChipMode(void) {
} }
return (FM_DOUT); return (FM_DOUT);
} }
#endif // if !defined(CONFIG_IDF_TARGET_ESP32P4)
uint32_t EspClass::magicFlashChipSize(uint8_t byte) { uint32_t EspClass::magicFlashChipSize(uint8_t byte) {
/* /*

View file

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

View file

@ -25,23 +25,37 @@
void serialEvent(void) __attribute__((weak)); void serialEvent(void) __attribute__((weak));
#if SOC_UART_NUM > 1 #if SOC_UART_HP_NUM > 1
void serialEvent1(void) __attribute__((weak)); 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)); 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) #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
// There is always Seria0 for UART0 // There is always Seria0 for UART0
HardwareSerial Serial0(0); HardwareSerial Serial0(0);
#if SOC_UART_NUM > 1 #if SOC_UART_HP_NUM > 1
HardwareSerial Serial1(1); HardwareSerial Serial1(1);
#endif #endif
#if SOC_UART_NUM > 2 #if SOC_UART_HP_NUM > 2
HardwareSerial Serial2(2); HardwareSerial Serial2(2);
#endif #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 #if HWCDC_SERIAL_IS_DEFINED == 1 // Hardware JTAG CDC Event
extern void HWCDCSerialEvent(void) __attribute__((weak)); extern void HWCDCSerialEvent(void) __attribute__((weak));
@ -67,16 +81,26 @@ void serialEventRun(void) {
if (serialEvent && Serial0.available()) { if (serialEvent && Serial0.available()) {
serialEvent(); serialEvent();
} }
#if SOC_UART_NUM > 1 #if SOC_UART_HP_NUM > 1
if (serialEvent1 && Serial1.available()) { if (serialEvent1 && Serial1.available()) {
serialEvent1(); serialEvent1();
} }
#endif #endif
#if SOC_UART_NUM > 2 #if SOC_UART_HP_NUM > 2
if (serialEvent2 && Serial2.available()) { if (serialEvent2 && Serial2.available()) {
serialEvent2(); serialEvent2();
} }
#endif #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 #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) { 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) { if (_uart_nr >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_NUM - 1); log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_HP_NUM - 1);
return; return;
} }
@ -289,6 +313,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
// map logical pins to GPIO numbers // map logical pins to GPIO numbers
rxPin = digitalPinToGPIONumber(rxPin); rxPin = digitalPinToGPIONumber(rxPin);
txPin = digitalPinToGPIONumber(txPin); 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(); HSERIAL_MUTEX_LOCK();
// First Time or after end() --> set default Pins // 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; txPin = _txPin < 0 ? (int8_t)SOC_TX0 : _txPin;
} }
break; 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: case UART_NUM_1:
if (rxPin < 0 && txPin < 0) { if (rxPin < 0 && txPin < 0) {
// do not change RX1/TX1 if it has already been set before // 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; break;
#endif #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: case UART_NUM_2:
if (rxPin < 0 && txPin < 0) { if (rxPin < 0 && txPin < 0) {
// do not change RX2/TX2 if it has already been set before // do not change RX2/TX2 if it has already been set before
#ifdef RX2
rxPin = _rxPin < 0 ? (int8_t)RX2 : _rxPin; rxPin = _rxPin < 0 ? (int8_t)RX2 : _rxPin;
#endif
#ifdef TX2
txPin = _txPin < 0 ? (int8_t)TX2 : _txPin; 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; break;
#endif #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. // IDF UART driver keeps Pin setting on restarting. Negative Pin number will keep it unmodified.
// it will detach previous UART attached pins // it will detach previous UART attached pins

View file

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

View file

@ -22,6 +22,10 @@
#include "lwip/netif.h" #include "lwip/netif.h"
#include "StreamString.h" #include "StreamString.h"
#ifndef CONFIG_LWIP_IPV6
#define IP6_NO_ZONE 0
#endif
IPAddress::IPAddress() : IPAddress(IPv4) {} IPAddress::IPAddress() : IPAddress(IPv4) {}
IPAddress::IPAddress(IPType ip_type) { IPAddress::IPAddress(IPType ip_type) {
@ -201,7 +205,13 @@ bool IPAddress::fromString6(const char *address) {
colons++; colons++;
acc = 0; acc = 0;
} else if (c == '%') { } 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') { while (*address != '\0') {
address++; address++;
} }
@ -344,12 +354,25 @@ size_t IPAddress::printTo(Print &p, bool includeZone) const {
n += p.print(':'); 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) { if (_zone > 0 && includeZone) {
n += p.print('%'); n += p.print('%');
char if_name[NETIF_NAMESIZE]; // look for the interface name
netif_index_to_name(_zone, if_name); for (netif *intf = netif_list; intf != nullptr; intf = intf->next) {
n += p.print(if_name); 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; return n;
} }
@ -368,6 +391,7 @@ IPAddress::IPAddress(const ip_addr_t *addr) {
} }
void IPAddress::to_ip_addr_t(ip_addr_t *addr) const { void IPAddress::to_ip_addr_t(ip_addr_t *addr) const {
#if CONFIG_LWIP_IPV6
if (_type == IPv6) { if (_type == IPv6) {
addr->type = IPADDR_TYPE_V6; addr->type = IPADDR_TYPE_V6;
addr->u_addr.ip6.addr[0] = _address.dword[0]; 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->type = IPADDR_TYPE_V4;
addr->u_addr.ip4.addr = _address.dword[IPADDRESS_V4_DWORD_INDEX]; 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) { IPAddress &IPAddress::from_ip_addr_t(const ip_addr_t *addr) {
#if CONFIG_LWIP_IPV6
if (addr->type == IPADDR_TYPE_V6) { if (addr->type == IPADDR_TYPE_V6) {
_type = IPv6; _type = IPv6;
_address.dword[0] = addr->u_addr.ip6.addr[0]; _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; _zone = addr->u_addr.ip6.zone;
#endif /* LWIP_IPV6_SCOPES */ #endif /* LWIP_IPV6_SCOPES */
} else { } else {
#endif
_type = IPv4; _type = IPv4;
memset(_address.bytes, 0, sizeof(_address.bytes)); memset(_address.bytes, 0, sizeof(_address.bytes));
#if CONFIG_LWIP_IPV6
_address.dword[IPADDRESS_V4_DWORD_INDEX] = addr->u_addr.ip4.addr; _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; return *this;
} }
#if CONFIG_LWIP_IPV6
esp_ip6_addr_type_t IPAddress::addr_type() const { esp_ip6_addr_type_t IPAddress::addr_type() const {
if (_type != IPv6) { if (_type != IPv6) {
return ESP_IP6_ADDR_IS_UNKNOWN; return ESP_IP6_ADDR_IS_UNKNOWN;
@ -409,6 +445,9 @@ esp_ip6_addr_type_t IPAddress::addr_type() const {
to_ip_addr_t(&addr); to_ip_addr_t(&addr);
return esp_netif_ip6_get_addr_type((esp_ip6_addr_t *)(&(addr.u_addr.ip6))); 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); const IPAddress IN6ADDR_ANY(IPv6);
#endif
const IPAddress INADDR_NONE(0, 0, 0, 0); const IPAddress INADDR_NONE(0, 0, 0, 0);

View file

@ -24,6 +24,7 @@
#include "WString.h" #include "WString.h"
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
#include "esp_netif_ip_addr.h" #include "esp_netif_ip_addr.h"
#include "sdkconfig.h"
#define IPADDRESS_V4_BYTES_INDEX 12 #define IPADDRESS_V4_BYTES_INDEX 12
#define IPADDRESS_V4_DWORD_INDEX 3 #define IPADDRESS_V4_DWORD_INDEX 3
@ -115,7 +116,9 @@ public:
IPAddress(const ip_addr_t *addr); IPAddress(const ip_addr_t *addr);
void to_ip_addr_t(ip_addr_t *addr) const; void to_ip_addr_t(ip_addr_t *addr) const;
IPAddress &from_ip_addr_t(const ip_addr_t *addr); IPAddress &from_ip_addr_t(const ip_addr_t *addr);
#if CONFIG_LWIP_IPV6
esp_ip6_addr_type_t addr_type() const; esp_ip6_addr_type_t addr_type() const;
#endif
uint8_t zone() const { uint8_t zone() const {
return (type() == IPv6) ? _zone : 0; 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) { static uint16_t load_cdc_descriptor(uint8_t *dst, uint8_t *itf) {
uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB CDC"); 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. 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; *itf += 2;
memcpy(dst, descriptor, TUD_CDC_DESC_LEN); 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(); uint8_t ep_num = tinyusb_get_free_duplex_endpoint();
TU_VERIFY(ep_num != 0); TU_VERIFY(ep_num != 0);
uint8_t descriptor[TUD_MSC_DESC_LEN] = {// Interface number, string index, EP Out & EP In address, EP size 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; *itf += 1;
memcpy(dst, descriptor, TUD_MSC_DESC_LEN); memcpy(dst, descriptor, TUD_MSC_DESC_LEN);

View file

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

View file

@ -75,7 +75,7 @@ static bool adcDetachBus(void *pin) {
if (err != ESP_OK) { if (err != ESP_OK) {
return false; 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); err = adc_cali_delete_scheme_line_fitting(adc_handle[adc_unit].adc_cali_handle);
if (err != ESP_OK) { if (err != ESP_OK) {
return false; 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); log_e("adc_cali_create_scheme_curve_fitting failed with error: %d", err);
return 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); 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); err = adc_cali_delete_scheme_line_fitting(adc_handle[adc_unit].adc_cali_handle);
if (err != ESP_OK) { if (err != ESP_OK) {
@ -310,7 +310,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin) {
.bitwidth = __analogWidth, .bitwidth = __analogWidth,
}; };
err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_handle[adc_unit].adc_cali_handle); 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 = { adc_cali_line_fitting_config_t cali_config = {
.unit_id = adc_unit, .unit_id = adc_unit,
.bitwidth = __analogWidth, .bitwidth = __analogWidth,
@ -379,7 +379,7 @@ static bool adcContinuousDetachBus(void *adc_unit_number) {
if (err != ESP_OK) { if (err != ESP_OK) {
return false; 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); err = adc_cali_delete_scheme_line_fitting(adc_handle[adc_unit].adc_cali_handle);
if (err != ESP_OK) { if (err != ESP_OK) {
return false; return false;
@ -552,7 +552,7 @@ bool analogContinuous(const uint8_t pins[], size_t pins_count, uint32_t conversi
.bitwidth = __adcContinuousWidth, .bitwidth = __adcContinuousWidth,
}; };
err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_handle[adc_unit].adc_cali_handle); 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 = { adc_cali_line_fitting_config_t cali_config = {
.unit_id = adc_unit, .unit_id = adc_unit,
.bitwidth = __adcContinuousWidth, .bitwidth = __adcContinuousWidth,

View file

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

View file

@ -41,21 +41,40 @@
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "soc/i2c_reg.h" #include "soc/i2c_reg.h"
#include "soc/i2c_struct.h" #include "soc/i2c_struct.h"
#include "soc/periph_defs.h"
#include "hal/i2c_ll.h" #include "hal/i2c_ll.h"
#include "hal/clk_gate_ll.h" #include "hal/clk_gate_ll.h"
#include "esp32-hal-log.h" #include "esp32-hal-log.h"
#include "esp32-hal-i2c-slave.h" #include "esp32-hal-i2c-slave.h"
#include "esp32-hal-periman.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 #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_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)) #define I2C_SDA_IDX(p) ((p == 0) ? I2CEXT0_SDA_OUT_IDX : ((p == 1) ? I2CEXT1_SDA_OUT_IDX : 0))
#else #else
#define I2C_SCL_IDX(p) I2CEXT0_SCL_OUT_IDX #define I2C_SCL_IDX(p) I2CEXT0_SCL_OUT_IDX
#define I2C_SDA_IDX(p) I2CEXT0_SDA_OUT_IDX #define I2C_SDA_IDX(p) I2CEXT0_SDA_OUT_IDX
#endif #endif
#endif // ifdef CONFIG_IDF_TARGET_ESP32P4
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
#define I2C_TXFIFO_WM_INT_ENA I2C_TXFIFO_EMPTY_INT_ENA #define I2C_TXFIFO_WM_INT_ENA I2C_TXFIFO_EMPTY_INT_ENA
@ -99,14 +118,14 @@ typedef union {
uint32_t val; uint32_t val;
} i2c_slave_queue_event_t; } 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 {&I2C0, 0, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
#if !CONFIG_DISABLE_HAL_LOCKS #if !CONFIG_DISABLE_HAL_LOCKS
, ,
NULL NULL
#endif #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 {&I2C1, 1, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
#if !CONFIG_DISABLE_HAL_LOCKS #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) { 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 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
return hw->sr.slave_addressed;
#else
return hw->status_reg.slave_addressed; return hw->status_reg.slave_addressed;
#else
return hw->sr.slave_addressed;
#endif #endif
} }
static inline bool i2c_ll_slave_rw(i2c_dev_t *hw) //not exposed by hal_ll 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 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
return hw->sr.slave_rw;
#else
return hw->status_reg.slave_rw; return hw->status_reg.slave_rw;
#else
return hw->sr.slave_rw;
#endif #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) { 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); log_e("Invalid port num: %u", num);
return ESP_ERR_INVALID_ARG; 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) { 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); log_e("Invalid port num: %u", num);
return ESP_ERR_INVALID_ARG; 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 = 100000L;
} }
frequency = (frequency * 5) / 4; frequency = (frequency * 5) / 4;
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
if (i2c->num == 0) { if (i2c->num == 0) {
periph_ll_enable_clk_clear_rst(PERIPH_I2C0_MODULE); periph_ll_enable_clk_clear_rst(PERIPH_I2C0_MODULE);
#if SOC_I2C_NUM > 1 #if SOC_HP_I2C_NUM > 1
} else { } else {
periph_ll_enable_clk_clear_rst(PERIPH_I2C1_MODULE); periph_ll_enable_clk_clear_rst(PERIPH_I2C1_MODULE);
#endif #endif
} }
#endif // !defined(CONFIG_IDF_TARGET_ESP32P4)
i2c_ll_slave_init(i2c->dev); 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_slave_addr(i2c->dev, slaveID, false);
i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT); i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT);
i2c_slave_set_frequency(i2c, frequency); 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_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK);
i2c_ll_clear_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) { if (!i2c->intr_handle) {
uint32_t flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED; uint32_t flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED;
if (i2c->num == 0) { 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); 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 { } 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); 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 #endif
} }
@ -375,7 +403,7 @@ fail:
} }
esp_err_t i2cSlaveDeinit(uint8_t num) { 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); log_e("Invalid port num: %u", num);
return ESP_ERR_INVALID_ARG; 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) { 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); log_e("Invalid port num: %u", num);
return 0; 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; i2c_hal_clk_config_t clk_cal;
#if SOC_I2C_SUPPORT_APB #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_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_APB); /*!< I2C source clock from APB, 80M*/ 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 #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_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_XTAL); /*!< I2C source clock from XTAL, 40M */ I2C_CLOCK_SRC_ATOMIC() {
i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_XTAL); /*!< I2C source clock from XTAL, 40M */
}
#endif #endif
i2c_ll_set_txfifo_empty_thr(i2c->dev, a); 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_rxfifo_full_thr(i2c->dev, SOC_I2C_FIFO_LEN - a);
i2c_ll_set_bus_timing(i2c->dev, &clk_cal); i2c_ll_master_set_bus_timing(i2c->dev, &clk_cal);
i2c_ll_set_filter(i2c->dev, 3); i2c_ll_master_set_filter(i2c->dev, 3);
return true; return true;
} }

View file

@ -29,6 +29,19 @@
#include "hal/i2c_ll.h" #include "hal/i2c_ll.h"
#include "driver/i2c.h" #include "driver/i2c.h"
#include "esp32-hal-periman.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 #if SOC_I2C_SUPPORT_APB || SOC_I2C_SUPPORT_XTAL
#include "esp_private/esp_clk.h" #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(); periph_rtc_dig_clk8m_enable();
} }
#endif #endif
i2c_hal_set_bus_timing(&(hal), frequency, i2c_clk_alloc[src_clk].clk, i2c_clk_alloc[src_clk].clk_freq); 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; bus[i2c_num].frequency = frequency;
//Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2 //Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT); 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); ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC);
if (bus != NULL) { if (bus != NULL) {
gpio_set_level(pin, out_invert); 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 #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); 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 #else
esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT0_IDX + ((bus->channel) % 8), out_invert, 0); esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT0_IDX + ((bus->channel) % 8), out_invert, 0);
#endif #endif
#endif // ifdef CONFIG_IDF_TARGET_ESP32P4
return true; return true;
} }
return false; return false;

View file

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

View file

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

View file

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

View file

@ -21,7 +21,8 @@ extern "C" {
#include "sdkconfig.h" #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 #ifdef CONFIG_SPIRAM_SUPPORT
#undef CONFIG_SPIRAM_SUPPORT #undef CONFIG_SPIRAM_SUPPORT
#endif #endif

View file

@ -22,11 +22,13 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/spi_reg.h" #include "soc/spi_reg.h"
#include "soc/spi_struct.h" #include "soc/spi_struct.h"
#include "soc/periph_defs.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
#include "soc/gpio_sig_map.h" #include "soc/gpio_sig_map.h"
#include "soc/rtc.h" #include "soc/rtc.h"
#include "hal/clk_gate_ll.h" #include "hal/clk_gate_ll.h"
#include "esp32-hal-periman.h" #include "esp32-hal-periman.h"
#include "esp_private/periph_ctrl.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
@ -55,12 +57,15 @@
#elif CONFIG_IDF_TARGET_ESP32H2 #elif CONFIG_IDF_TARGET_ESP32H2
#include "esp32h2/rom/ets_sys.h" #include "esp32h2/rom/ets_sys.h"
#include "esp32h2/rom/gpio.h" #include "esp32h2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/ets_sys.h"
#include "esp32p4/rom/gpio.h"
#else #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif
struct spi_struct_t { struct spi_struct_t {
spi_dev_t *dev; volatile spi_dev_t *dev;
#if !CONFIG_DISABLE_HAL_LOCKS #if !CONFIG_DISABLE_HAL_LOCKS
SemaphoreHandle_t lock; SemaphoreHandle_t lock;
#endif #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_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)) #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 #elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
// ESP32C3 // ESP32C3
#define SPI_COUNT (1) #define SPI_COUNT (1)
@ -125,14 +148,15 @@ struct spi_struct_t {
#if CONFIG_DISABLE_HAL_LOCKS #if CONFIG_DISABLE_HAL_LOCKS
#define SPI_MUTEX_LOCK() #define SPI_MUTEX_LOCK()
#define SPI_MUTEX_UNLOCK() #define SPI_MUTEX_UNLOCK()
// clang-format off
static spi_t _spi_bus_array[] = { static spi_t _spi_bus_array[] = {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0, -1, -1, -1, -1}, {(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_SPI2_BASE), 1, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2, -1, -1, -1, -1} {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 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), 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1, -1, -1, -1, -1} {(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 #elif CONFIG_IDF_TARGET_ESP32C2
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1} {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32C3 #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} {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 3, -1, -1, -1, -1}
#endif #endif
}; };
// clang-format on
#else #else
#define SPI_MUTEX_LOCK() \ #define SPI_MUTEX_LOCK() \
do { \ 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_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_SPI2_BASE), NULL, 1, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2, -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} {(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 #elif CONFIG_IDF_TARGET_ESP32C2
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1} {(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; return;
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.val &= ~(ss_mask & SPI_SS_MASK_ALL);
#else
spi->dev->pin.val &= ~(ss_mask & SPI_SS_MASK_ALL); spi->dev->pin.val &= ~(ss_mask & SPI_SS_MASK_ALL);
#else
spi->dev->misc.val &= ~(ss_mask & SPI_SS_MASK_ALL);
#endif #endif
SPI_MUTEX_UNLOCK(); SPI_MUTEX_UNLOCK();
} }
@ -383,11 +407,10 @@ void spiDisableSSPins(spi_t *spi, uint8_t ss_mask) {
return; return;
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.val |= (ss_mask & SPI_SS_MASK_ALL);
#else
spi->dev->pin.val |= (ss_mask & SPI_SS_MASK_ALL); spi->dev->pin.val |= (ss_mask & SPI_SS_MASK_ALL);
#else
spi->dev->misc.val |= (ss_mask & SPI_SS_MASK_ALL);
#endif #endif
SPI_MUTEX_UNLOCK(); SPI_MUTEX_UNLOCK();
} }
@ -417,11 +440,10 @@ void spiSSSet(spi_t *spi) {
return; return;
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.cs_keep_active = 1;
#else
spi->dev->pin.cs_keep_active = 1; spi->dev->pin.cs_keep_active = 1;
#else
spi->dev->misc.cs_keep_active = 1;
#endif #endif
SPI_MUTEX_UNLOCK(); SPI_MUTEX_UNLOCK();
} }
@ -431,11 +453,10 @@ void spiSSClear(spi_t *spi) {
return; return;
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.cs_keep_active = 0;
#else
spi->dev->pin.cs_keep_active = 0; spi->dev->pin.cs_keep_active = 0;
#else
spi->dev->misc.cs_keep_active = 0;
#endif #endif
SPI_MUTEX_UNLOCK(); SPI_MUTEX_UNLOCK();
} }
@ -460,11 +481,10 @@ uint8_t spiGetDataMode(spi_t *spi) {
if (!spi) { if (!spi) {
return 0; return 0;
} }
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
bool idleEdge = spi->dev->misc.ck_idle_edge;
#else
bool idleEdge = spi->dev->pin.ck_idle_edge; bool idleEdge = spi->dev->pin.ck_idle_edge;
#else
bool idleEdge = spi->dev->misc.ck_idle_edge;
#endif #endif
bool outEdge = spi->dev->user.ck_out_edge; bool outEdge = spi->dev->user.ck_out_edge;
if (idleEdge) { if (idleEdge) {
@ -486,39 +506,35 @@ void spiSetDataMode(spi_t *spi, uint8_t dataMode) {
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
switch (dataMode) { switch (dataMode) {
case SPI_MODE1: case SPI_MODE1:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 0;
#else
spi->dev->pin.ck_idle_edge = 0; spi->dev->pin.ck_idle_edge = 0;
#else
spi->dev->misc.ck_idle_edge = 0;
#endif #endif
spi->dev->user.ck_out_edge = 1; spi->dev->user.ck_out_edge = 1;
break; break;
case SPI_MODE2: case SPI_MODE2:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 1;
#else
spi->dev->pin.ck_idle_edge = 1; spi->dev->pin.ck_idle_edge = 1;
#else
spi->dev->misc.ck_idle_edge = 1;
#endif #endif
spi->dev->user.ck_out_edge = 1; spi->dev->user.ck_out_edge = 1;
break; break;
case SPI_MODE3: case SPI_MODE3:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 1;
#else
spi->dev->pin.ck_idle_edge = 1; spi->dev->pin.ck_idle_edge = 1;
#else
spi->dev->misc.ck_idle_edge = 1;
#endif #endif
spi->dev->user.ck_out_edge = 0; spi->dev->user.ck_out_edge = 0;
break; break;
case SPI_MODE0: case SPI_MODE0:
default: default:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 0;
#else
spi->dev->pin.ck_idle_edge = 0; spi->dev->pin.ck_idle_edge = 0;
#else
spi->dev->misc.ck_idle_edge = 0;
#endif #endif
spi->dev->user.ck_out_edge = 0; spi->dev->user.ck_out_edge = 0;
break; break;
@ -564,11 +580,10 @@ static void spiInitBus(spi_t *spi) {
spi->dev->slave.trans_done = 0; spi->dev->slave.trans_done = 0;
#endif #endif
spi->dev->slave.val = 0; 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 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.val = 0;
#else
spi->dev->pin.val = 0; spi->dev->pin.val = 0;
#else
spi->dev->misc.val = 0;
#endif #endif
spi->dev->user.val = 0; spi->dev->user.val = 0;
spi->dev->user1.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_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); 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_reset(PERIPH_SPI2_MODULE);
periph_ll_enable_clk_clear_rst(PERIPH_SPI2_MODULE); periph_ll_enable_clk_clear_rst(PERIPH_SPI2_MODULE);
#endif #endif
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spiInitBus(spi); 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.clk_en = 1;
spi->dev->clk_gate.mst_clk_sel = 1; spi->dev->clk_gate.mst_clk_sel = 1;
spi->dev->clk_gate.mst_clk_active = 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.tx_seg_trans_clr_en = 1;
spi->dev->dma_conf.rx_seg_trans_clr_en = 1; spi->dev->dma_conf.rx_seg_trans_clr_en = 1;
spi->dev->dma_conf.dma_seg_trans_en = 0; 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; spi->dev->user.doutdin = 1;
int i; int i;
for (i = 0; i < 16; 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; spi->dev->data_buf[i].val = 0x00000000;
#else #else
spi->dev->data_buf[i] = 0x00000000; spi->dev->data_buf[i] = 0x00000000;
@ -697,7 +712,7 @@ void spiWaitReady(spi_t *spi) {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
#define usr_mosi_dbitlen usr_mosi_bit_len #define usr_mosi_dbitlen usr_mosi_bit_len
#define usr_miso_dbitlen usr_miso_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_mosi_dbitlen ms_data_bitlen
#define usr_miso_dbitlen ms_data_bitlen #define usr_miso_dbitlen ms_data_bitlen
#define mosi_dlen ms_dlen #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; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
for (i = 0; i < len; i++) { 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]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #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->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1; spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1;
for (i = 0; i < len; i++) { 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]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
for (i = 0; i < len; i++) { 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; data[i] = spi->dev->data_buf[i].val;
#else #else
data[i] = spi->dev->data_buf[i]; 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 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -798,18 +813,18 @@ uint8_t spiTransferByte(spi_t *spi, uint8_t data) {
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); 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; data = spi->dev->data_buf[0].val & 0xFF;
#else #else
data = spi->dev->data_buf[0] & 0xFF; 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 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -863,18 +878,18 @@ uint16_t spiTransferWord(spi_t *spi, uint16_t data) {
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
spi->dev->miso_dlen.usr_miso_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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); 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; data = spi->dev->data_buf[0].val;
#else #else
data = spi->dev->data_buf[0]; 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 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -922,18 +937,18 @@ uint32_t spiTransferLong(spi_t *spi, uint32_t data) {
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
spi->dev->miso_dlen.usr_miso_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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); 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; data = spi->dev->data_buf[0].val;
#else #else
data = spi->dev->data_buf[0]; 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); spi->dev->miso_dlen.usr_miso_dbitlen = ((bytes * 8) - 1);
for (i = 0; i < words; i++) { 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 spi->dev->data_buf[i].val = wordsBuf[i]; //copy buffer to spi fifo
#else #else
spi->dev->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo spi->dev->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -989,7 +1004,7 @@ static void __spiTransferBytes(spi_t *spi, const uint8_t *data, uint8_t *out, ui
if (out) { if (out) {
for (i = 0; i < words; i++) { 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 wordsBuf[i] = spi->dev->data_buf[i].val; //copy spi fifo to buffer
#else #else
wordsBuf[i] = spi->dev->data_buf[i]; //copy spi fifo to buffer 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; spi->dev->clock.val = clockDiv;
switch (dataMode) { switch (dataMode) {
case SPI_MODE1: case SPI_MODE1:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 0;
#else
spi->dev->pin.ck_idle_edge = 0; spi->dev->pin.ck_idle_edge = 0;
#else
spi->dev->misc.ck_idle_edge = 0;
#endif #endif
spi->dev->user.ck_out_edge = 1; spi->dev->user.ck_out_edge = 1;
break; break;
case SPI_MODE2: case SPI_MODE2:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 1;
#else
spi->dev->pin.ck_idle_edge = 1; spi->dev->pin.ck_idle_edge = 1;
#else
spi->dev->misc.ck_idle_edge = 1;
#endif #endif
spi->dev->user.ck_out_edge = 1; spi->dev->user.ck_out_edge = 1;
break; break;
case SPI_MODE3: case SPI_MODE3:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 1;
#else
spi->dev->pin.ck_idle_edge = 1; spi->dev->pin.ck_idle_edge = 1;
#else
spi->dev->misc.ck_idle_edge = 1;
#endif #endif
spi->dev->user.ck_out_edge = 0; spi->dev->user.ck_out_edge = 0;
break; break;
case SPI_MODE0: case SPI_MODE0:
default: default:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 \ #if CONFIG_IDF_TARGET_ESP32
|| CONFIG_IDF_TARGET_ESP32H2
spi->dev->misc.ck_idle_edge = 0;
#else
spi->dev->pin.ck_idle_edge = 0; spi->dev->pin.ck_idle_edge = 0;
#else
spi->dev->misc.ck_idle_edge = 0;
#endif #endif
spi->dev->user.ck_out_edge = 0; spi->dev->user.ck_out_edge = 0;
break; 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.wr_bit_order = 1;
spi->dev->ctrl.rd_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 // Sync new config with hardware, fixes https://github.com/espressif/arduino-esp32/issues/9221
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); 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 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1153,18 +1164,18 @@ uint8_t spiTransferByteNL(spi_t *spi, uint8_t data) {
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); 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; data = spi->dev->data_buf[0].val & 0xFF;
#else #else
data = spi->dev->data_buf[0] & 0xFF; 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 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1205,18 +1216,18 @@ uint16_t spiTransferShortNL(spi_t *spi, uint16_t data) {
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
spi->dev->miso_dlen.usr_miso_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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); 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; data = spi->dev->data_buf[0].val & 0xFFFF;
#else #else
data = spi->dev->data_buf[0] & 0xFFFF; 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 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1260,18 +1271,18 @@ uint32_t spiTransferLongNL(spi_t *spi, uint32_t data) {
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
spi->dev->miso_dlen.usr_miso_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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); 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; data = spi->dev->data_buf[0].val;
#else #else
data = spi->dev->data_buf[0]; 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; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
for (size_t i = 0; i < c_longs; i++) { 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]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #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; spi->dev->miso_dlen.usr_miso_dbitlen = (c_len * 8) - 1;
if (data) { if (data) {
for (size_t i = 0; i < c_longs; i++) { 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]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; 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 { } else {
for (size_t i = 0; i < c_longs; i++) { 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; spi->dev->data_buf[i].val = 0xFFFFFFFF;
#else #else
spi->dev->data_buf[i] = 0xFFFFFFFF; spi->dev->data_buf[i] = 0xFFFFFFFF;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1365,13 +1376,13 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
if (result) { if (result) {
if (c_len & 3) { if (c_len & 3) {
for (size_t i = 0; i < (c_longs - 1); i++) { 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; result[i] = spi->dev->data_buf[i].val;
#else #else
result[i] = spi->dev->data_buf[i]; result[i] = spi->dev->data_buf[i];
#endif #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; uint32_t last_data = spi->dev->data_buf[c_longs - 1].val;
#else #else
uint32_t last_data = spi->dev->data_buf[c_longs - 1]; 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 { } else {
for (size_t i = 0; i < c_longs; i++) { 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; result[i] = spi->dev->data_buf[i].val;
#else #else
result[i] = spi->dev->data_buf[i]; 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->mosi_dlen.usr_mosi_dbitlen = (bits - 1);
spi->dev->miso_dlen.usr_miso_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; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); 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; data = spi->dev->data_buf[0].val;
#else #else
data = spi->dev->data_buf[0]; 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 (msb) {
if (l_bytes && i == (c_longs - 1)) { if (l_bytes && i == (c_longs - 1)) {
if (l_bytes == 2) { 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]); MSB_16_SET(spi->dev->data_buf[i].val, data[i]);
#else #else
MSB_16_SET(spi->dev->data_buf[i], data[i]); MSB_16_SET(spi->dev->data_buf[i], data[i]);
#endif #endif
} else { } 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; spi->dev->data_buf[i].val = data[i] & 0xFF;
#else #else
spi->dev->data_buf[i] = data[i] & 0xFF; spi->dev->data_buf[i] = data[i] & 0xFF;
#endif #endif
} }
} else { } 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]); MSB_PIX_SET(spi->dev->data_buf[i].val, data[i]);
#else #else
MSB_PIX_SET(spi->dev->data_buf[i], data[i]); MSB_PIX_SET(spi->dev->data_buf[i], data[i]);
#endif #endif
} }
} else { } 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]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
#endif #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; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1528,7 +1539,7 @@ typedef union {
uint32_t clkcnt_l : 6; /*it must be equal to spi_clkcnt_N.*/ 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_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)*/ 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 clkdiv_pre : 4; /*it is pre-divider of spi_clk.*/
uint32_t reserved : 9; /*reserved*/ uint32_t reserved : 9; /*reserved*/
#else #else
@ -1573,7 +1584,7 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq) {
while (calPreVari++ <= 1) { while (calPreVari++ <= 1) {
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari; 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) { if (calPre > 0xF) {
reg.clkdiv_pre = 0xF; reg.clkdiv_pre = 0xF;
#else #else

View file

@ -28,10 +28,7 @@ extern "C" {
#define SPI_HAS_TRANSACTION #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 #ifdef CONFIG_IDF_TARGET_ESP32S2
#define FSPI 0
#define HSPI 1
#elif 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 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 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 #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 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 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 #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 #endif
// This defines are not representing the real Divider of the ESP32 // This defines are not representing the real Divider of the ESP32

View file

@ -10,12 +10,15 @@
#include "soc/soc.h" #include "soc/soc.h"
#include "soc/efuse_reg.h" #include "soc/efuse_reg.h"
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "soc/usb_struct.h" #include "soc/usb_struct.h"
#include "soc/usb_reg.h" #include "soc/usb_reg.h"
#include "soc/usb_wrap_reg.h" #include "soc/usb_wrap_reg.h"
#include "soc/usb_wrap_struct.h" #include "soc/usb_wrap_struct.h"
#include "soc/usb_periph.h" #include "soc/usb_periph.h"
#endif
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "soc/timer_group_struct.h" #include "soc/timer_group_struct.h"
#include "soc/system_reg.h" #include "soc/system_reg.h"
@ -34,8 +37,8 @@
#include "esp32-hal.h" #include "esp32-hal.h"
#include "esp32-hal-periman.h" #include "esp32-hal-periman.h"
#include "esp32-hal-tinyusb.h" #include "esp32-hal-tinyusb.h"
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/usb/usb_persist.h" #include "esp32s2/rom/usb/usb_persist.h"
#include "esp32s2/rom/usb/usb_dc.h" #include "esp32s2/rom/usb/usb_dc.h"
@ -50,6 +53,7 @@
#include "esp32s3/rom/usb/usb_persist.h" #include "esp32s3/rom/usb/usb_persist.h"
#include "esp32s3/rom/usb/usb_dc.h" #include "esp32s3/rom/usb/usb_dc.h"
#include "esp32s3/rom/usb/chip_usb_dw_wrapper.h" #include "esp32s3/rom/usb/chip_usb_dw_wrapper.h"
#elif CONFIG_IDF_TARGET_ESP32P4
#endif #endif
typedef enum { typedef enum {
@ -127,7 +131,11 @@ esp_err_t init_usb_hal(bool external_phy) {
.controller = USB_PHY_CTRL_OTG, .controller = USB_PHY_CTRL_OTG,
.target = USB_PHY_TARGET_INT, .target = USB_PHY_TARGET_INT,
.otg_mode = USB_OTG_MODE_DEVICE, .otg_mode = USB_OTG_MODE_DEVICE,
#if CONFIG_IDF_TARGET_ESP32P4
.otg_speed = USB_PHY_SPEED_HIGH,
#else
.otg_speed = USB_PHY_SPEED_FULL, .otg_speed = USB_PHY_SPEED_FULL,
#endif
.ext_io_conf = NULL, .ext_io_conf = NULL,
.otg_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) { esp_err_t tinyusb_driver_install(const tinyusb_config_t *config) {
init_usb_hal(config->external_phy); 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."); log_e("Can't initialize the TinyUSB stack.");
return ESP_FAIL; return ESP_FAIL;
} }
@ -275,15 +292,14 @@ enum {
VENDOR_REQUEST_MICROSOFT = 2 VENDOR_REQUEST_MICROSOFT = 2
}; };
static uint8_t const tinyusb_bos_descriptor[] = { static uint8_t const tinyusb_bos_descriptor[] = {// total length, number of device caps
// total length, number of device caps TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2),
TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2),
// Vendor Code, iLandingPage // Vendor Code, iLandingPage
TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1), TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1),
// Microsoft OS 2.0 descriptor // Microsoft OS 2.0 descriptor
TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT) TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT)
}; };
/* /*
@ -467,8 +483,10 @@ __attribute__((weak)) void tud_network_init_cb(void) {}
/* /*
* Private API * Private API
* */ * */
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
static bool usb_persist_enabled = false; static bool usb_persist_enabled = false;
static restart_type_t usb_persist_mode = RESTART_NO_PERSIST; static restart_type_t usb_persist_mode = RESTART_NO_PERSIST;
#endif
#if CONFIG_IDF_TARGET_ESP32S3 #if CONFIG_IDF_TARGET_ESP32S3
@ -549,6 +567,7 @@ static void usb_switch_to_cdc_jtag() {
} }
#endif #endif
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
static void IRAM_ATTR usb_persist_shutdown_handler(void) { static void IRAM_ATTR usb_persist_shutdown_handler(void) {
if (usb_persist_mode != RESTART_NO_PERSIST) { if (usb_persist_mode != RESTART_NO_PERSIST) {
if (usb_persist_enabled) { 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) { 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) { if (mode < RESTART_TYPE_MAX && esp_register_shutdown_handler(usb_persist_shutdown_handler) == ESP_OK) {
usb_persist_mode = mode; usb_persist_mode = mode;
#if CONFIG_IDF_TARGET_ESP32S3 #if CONFIG_IDF_TARGET_ESP32S3
@ -591,6 +612,7 @@ void usb_persist_restart(restart_type_t mode) {
#endif #endif
esp_restart(); esp_restart();
} }
#endif
} }
static bool tinyusb_reserve_in_endpoint(uint8_t endpoint) { 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) { static void set_usb_serial_num(void) {
/* Get the MAC address */ /* 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 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); const uint32_t mac1 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_1_REG, EFUSE_MAC_1);
#endif
uint8_t mac_bytes[6]; uint8_t mac_bytes[6];
memcpy(mac_bytes, &mac0, 4); memcpy(mac_bytes, &mac0, 4);
memcpy(mac_bytes + 4, &mac1, 2); memcpy(mac_bytes + 4, &mac1, 2);
@ -794,6 +821,7 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
return ESP_FAIL; return ESP_FAIL;
} }
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
bool usb_did_persist = (USB_WRAP.date.val == USBDC_PERSIST_ENA); bool usb_did_persist = (USB_WRAP.date.val == USBDC_PERSIST_ENA);
//if(usb_did_persist && usb_persist_enabled){ //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_reset(PERIPH_USB_MODULE);
periph_ll_enable_clk_clear_rst(PERIPH_USB_MODULE); periph_ll_enable_clk_clear_rst(PERIPH_USB_MODULE);
} }
#endif
tinyusb_config_t tusb_cfg = { tinyusb_config_t tusb_cfg = {
.external_phy = false // In the most cases you need to use a `false` value .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_ESPRESSIF_VID 0x303A
#define USB_STRING_DESCRIPTOR_ARRAY_SIZE 10 #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 { typedef struct {
uint16_t vid; uint16_t vid;
uint16_t pid; 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" #include "soc/soc_caps.h"
#if SOC_TOUCH_SENSOR_SUPPORTED #if SOC_TOUCH_SENSOR_SUPPORTED
#if SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32, ESP32S2, ESP32S3
#include "driver/touch_sensor.h" #include "driver/touch_sensor.h"
#include "esp32-hal-touch.h" #include "esp32-hal-touch.h"
#include "esp32-hal-periman.h" #include "esp32-hal-periman.h"
@ -22,10 +24,10 @@
Internal Private Touch Data Structure and Functions 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 __touchSleepCycles = 0x1000;
static uint16_t __touchMeasureCycles = 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 __touchSleepCycles = TOUCH_PAD_SLEEP_CYCLE_DEFAULT;
static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT; static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT;
#endif #endif
@ -37,7 +39,7 @@ typedef struct {
voidFuncPtr fn; voidFuncPtr fn;
bool callWithArgs; bool callWithArgs;
void *arg; 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; bool lastStatusIsPressed;
#endif #endif
} TouchInterruptHandle_t; } TouchInterruptHandle_t;
@ -51,7 +53,7 @@ static bool initialized = false;
static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = {false}; static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = {false};
static void ARDUINO_ISR_ATTR __touchISR(void *arg) { 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(); uint32_t pad_intr = touch_pad_get_status();
//clear interrupt //clear interrupt
touch_pad_clear_status(); 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(); touch_pad_intr_mask_t evt = touch_pad_read_intr_status_mask();
uint8_t pad_num = touch_pad_get_current_meas_channel(); uint8_t pad_num = touch_pad_get_current_meas_channel();
if (evt & TOUCH_PAD_INTR_MASK_ACTIVE) { 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) { static void __touchSetCycles(uint16_t measure, uint16_t sleep) {
__touchSleepCycles = sleep; __touchSleepCycles = sleep;
__touchMeasureCycles = measure; __touchMeasureCycles = measure;
#if SOC_TOUCH_VERSION_1 // ESP32 #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
touch_pad_set_measurement_clock_cycles(measure); 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); touch_pad_set_charge_discharge_times(measure);
#endif #endif
touch_pad_set_measurement_interval(sleep); touch_pad_set_measurement_interval(sleep);
@ -123,7 +125,7 @@ static void __touchInit() {
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
#if SOC_TOUCH_VERSION_1 // ESP32 #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
err = touch_pad_init(); err = touch_pad_init();
if (err != ESP_OK) { if (err != ESP_OK) {
goto err; goto err;
@ -143,8 +145,8 @@ static void __touchInit() {
if (err != ESP_OK) { if (err != ESP_OK) {
goto err; goto err;
} }
touch_pad_intr_enable(); // returns ESP_OK 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(); err = touch_pad_init();
if (err != ESP_OK) { if (err != ESP_OK) {
goto err; goto err;
@ -165,7 +167,6 @@ static void __touchInit() {
touch_pad_fsm_start(); // returns ESP_OK touch_pad_fsm_start(); // returns ESP_OK
//ISR setup moved to __touchChannelInit //ISR setup moved to __touchChannelInit
#endif #endif
initialized = true; initialized = true;
return; return;
err: err:
@ -179,11 +180,11 @@ static void __touchChannelInit(int pad) {
return; return;
} }
#if SOC_TOUCH_VERSION_1 // ESP32 #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
// Initial no Threshold and setup // Initial no Threshold and setup
__touchInterruptHandlers[pad].fn = NULL; __touchInterruptHandlers[pad].fn = NULL;
touch_pad_config(pad, SOC_TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK touch_pad_config(pad, TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3 #elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
// Initial no Threshold and setup // Initial no Threshold and setup
__touchInterruptHandlers[pad].fn = NULL; __touchInterruptHandlers[pad].fn = NULL;
touch_pad_config(pad); // returns ESP_OK 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) { if (userFunc == NULL) {
// detach ISR User Call // detach ISR User Call
__touchInterruptHandlers[pad].fn = NULL; __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 { } else {
// attach ISR User Call // attach ISR User Call
__touchInit(); __touchInit();
@ -270,7 +271,7 @@ static void __touchDettachInterrupt(uint8_t pin) {
External Public Touch API Functions 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) { void touchInterruptSetThresholdDirection(bool mustbeLower) {
if (mustbeLower) { if (mustbeLower) {
touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW); touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW);
@ -278,7 +279,7 @@ void touchInterruptSetThresholdDirection(bool mustbeLower) {
touch_pad_set_trigger_mode(TOUCH_TRIGGER_ABOVE); 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 // returns true if touch pad has been and continues pressed and false otherwise
bool touchInterruptGetLastStatus(uint8_t pin) { bool touchInterruptGetLastStatus(uint8_t pin) {
int8_t pad = digitalPinToTouchChannel(pin); int8_t pad = digitalPinToTouchChannel(pin);
@ -307,10 +308,10 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold) {
return; 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); 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_channel_enable(pad, true);
touch_pad_sleep_set_threshold(pad, threshold); 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 touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDettachInterrupt")));
extern void touchSetCycles(uint16_t, uint16_t) __attribute__((weak, alias("__touchSetCycles"))); extern void touchSetCycles(uint16_t, uint16_t) __attribute__((weak, alias("__touchSetCycles")));
#endif /* SOC_TOUCH_SENSOR_VERSION <= 2 */
#endif /* SOC_TOUCH_SENSOR_SUPPORTED */ #endif /* SOC_TOUCH_SENSOR_SUPPORTED */

View file

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

View file

@ -33,7 +33,8 @@
#include "hal/gpio_hal.h" #include "hal/gpio_hal.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
static int s_uart_debug_nr = 0; // UART number for debug output 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 { struct uart_struct_t {
@ -61,12 +62,18 @@ struct uart_struct_t {
static uart_t _uart_bus_array[] = { static uart_t _uart_bus_array[] = {
{0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {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}, {1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif #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}, {2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif #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 #else
@ -81,12 +88,18 @@ static uart_t _uart_bus_array[] = {
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}, {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}, {NULL, 1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif #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}, {NULL, 2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0},
#endif #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 #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 // 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 // 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) { 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) { if (uart_num >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return false; return false;
} }
// get UART information // get UART information
@ -181,8 +194,8 @@ static bool _uartDetachBus_RTS(void *busptr) {
// Attach function for UART // Attach function for UART
// connects the IO Pad, set Paripheral Manager and internal UART structure data // 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) { 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) { if (uart_num >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return false; return false;
} }
// get UART information // 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 // Negative Pin Number will keep it unmodified, thus this function can set individual pins
// When pins are changed, it will detach the previous one // 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) { bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
if (uart_num >= SOC_UART_NUM) { if (uart_num >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return false; return false;
} }
// get UART information // 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 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 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 return false; // no new driver has to be installed
} }
uart_t *uart = &_uart_bus_array[uart_nr]; 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 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 uint8_t rxfifo_full_thrhd
) { ) {
if (uart_nr >= SOC_UART_NUM) { if (uart_nr >= SOC_UART_HP_NUM) {
log_e("UART number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); 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 return NULL; // no new driver was installed
} }
uart_t *uart = &_uart_bus_array[uart_nr]; 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); log_v("UART%d not installed. Starting installation", uart_nr);
} }
uart_config_t uart_config; 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.data_bits = (config & 0xc) >> 2;
uart_config.parity = (config & 0x3); uart_config.parity = (config & 0x3);
uart_config.stop_bits = (config & 0x30) >> 4; uart_config.stop_bits = (config & 0x30) >> 4;
@ -508,7 +523,7 @@ uart_t *uartBegin(
#if SOC_UART_SUPPORT_XTAL_CLK #if SOC_UART_SUPPORT_XTAL_CLK
uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4 uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4
#elif SOC_UART_SUPPORT_REF_TICK #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 uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
} else { } else {
uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency! 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) { void uartEnd(uint8_t uart_num) {
if (uart_num >= SOC_UART_NUM) { if (uart_num >= SOC_UART_HP_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1);
return; return;
} }
// get UART information // get UART information
@ -623,7 +638,7 @@ void uartSetRxInvert(uart_t *uart, bool invert) {
if (uart == NULL) { if (uart == NULL) {
return; 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 // POTENTIAL ISSUE :: original code only set/reset rxd_inv bit
// IDF or LL set/reset the whole inv_mask! // IDF or LL set/reset the whole inv_mask!
// if (invert) // if (invert)
@ -790,6 +805,10 @@ void uartSetBaudRate(uart_t *uart, uint32_t baud_rate) {
return; return;
} }
UART_MUTEX_LOCK(); 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) { if (uart_set_baudrate(uart->num, baud_rate) == ESP_OK) {
uart->_baudrate = baud_rate; uart->_baudrate = baud_rate;
} else { } 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); 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) { static void ARDUINO_ISR_ATTR uart1_write_char(char c) {
while (uart_ll_get_txfifo_len(&UART1) == 0); while (uart_ll_get_txfifo_len(&UART1) == 0);
uart_ll_write_txfifo(&UART1, (const uint8_t *)&c, 1); uart_ll_write_txfifo(&UART1, (const uint8_t *)&c, 1);
} }
#endif #endif
#if SOC_UART_NUM > 2 #if SOC_UART_HP_NUM > 2
static void ARDUINO_ISR_ATTR uart2_write_char(char c) { static void ARDUINO_ISR_ATTR uart2_write_char(char c) {
while (uart_ll_get_txfifo_len(&UART2) == 0); while (uart_ll_get_txfifo_len(&UART2) == 0);
uart_ll_write_txfifo(&UART2, (const uint8_t *)&c, 1); uart_ll_write_txfifo(&UART2, (const uint8_t *)&c, 1);
} }
#endif #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() { void uart_install_putc() {
switch (s_uart_debug_nr) { switch (s_uart_debug_nr) {
case 0: ets_install_putc1((void (*)(char)) & uart0_write_char); break; 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; case 1: ets_install_putc1((void (*)(char)) & uart1_write_char); break;
#endif #endif
#if SOC_UART_NUM > 2 #if SOC_UART_HP_NUM > 2
case 2: ets_install_putc1((void (*)(char)) & uart2_write_char); break; 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 #endif
default: ets_install_putc1(NULL); break; 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 // 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 // used to set UART_MODE_RS485_HALF_DUPLEX auto RTS for TXD for ESP32 chips
bool uartSetMode(uart_t *uart, uart_mode_t mode) { 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; return false;
} }
@ -861,7 +900,7 @@ bool uartSetMode(uart_t *uart, uart_mode_t mode) {
} }
void uartSetDebug(uart_t *uart) { 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; s_uart_debug_nr = -1;
} else { } else {
s_uart_debug_nr = uart->num; s_uart_debug_nr = uart->num;
@ -896,7 +935,7 @@ int log_printfv(const char *format, va_list arg) {
#endif #endif
*/ */
#if (ARDUINO_USB_CDC_ON_BOOT == 1 && ARDUINO_USB_MODE == 0) || CONFIG_IDF_TARGET_ESP32C3 \ #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); vsnprintf(temp, len + 1, format, arg);
ets_printf("%s", temp); ets_printf("%s", temp);
#else #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 // 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_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)) #define UART_RX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0RXD_IN_IDX : (uartNumber == UART_NUM_1 ? U1RXD_IN_IDX : U2RXD_IN_IDX))
#else #else
#define UART_TX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0TXD_OUT_IDX : U1TXD_OUT_IDX) #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) #define UART_RX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0RXD_IN_IDX : U1RXD_IN_IDX)
#endif #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 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. 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) { 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; return;
} }
esp_rom_gpio_connect_out_signal(rxPin, UART_TX_SIGNAL(uartNum), false, false); 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 #define ARDUINO_EVENT_RUNNING_CORE CONFIG_ARDUINO_EVENT_RUNNING_CORE
#endif #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 //forward declaration from freertos/portmacro.h
void vPortYield(void); void vPortYield(void);
void yield(void); void yield(void);
@ -74,6 +87,7 @@ void yield(void);
#include "esp32-hal-uart.h" #include "esp32-hal-uart.h"
#include "esp32-hal-gpio.h" #include "esp32-hal-gpio.h"
#include "esp32-hal-touch.h" #include "esp32-hal-touch.h"
#include "esp32-hal-touch-ng.h"
#include "esp32-hal-dac.h" #include "esp32-hal-dac.h"
#include "esp32-hal-adc.h" #include "esp32-hal-adc.h"
#include "esp32-hal-spi.h" #include "esp32-hal-spi.h"

View file

@ -21,9 +21,9 @@ extern "C" {
/** Major version number (X.x.x) */ /** Major version number (X.x.x) */
#define ESP_ARDUINO_VERSION_MAJOR 3 #define ESP_ARDUINO_VERSION_MAJOR 3
/** Minor version number (x.X.x) */ /** Minor version number (x.X.x) */
#define ESP_ARDUINO_VERSION_MINOR 0 #define ESP_ARDUINO_VERSION_MINOR 1
/** Patch version number (x.x.X) */ /** 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 * 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 spiAttachMOSI(spi, mosi) spiAttachMOSI(spi, digitalPinToGPIONumber(mosi))
#define spiAttachSS(spi, cs_num, ss) spiAttachSS(spi, cs_num, digitalPinToGPIONumber(ss)) #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 touchInterruptGetLastStatus(pin) touchInterruptGetLastStatus(digitalPinToGPIONumber(pin))
#define touchRead(pin) touchRead(digitalPinToGPIONumber(pin)) #define touchRead(pin) touchRead(digitalPinToGPIONumber(pin))
#define touchAttachInterruptArg(pin, userFunc, arg, threshold) touchAttachInterruptArg(digitalPinToGPIONumber(pin), userFunc, arg, threshold) #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:esp32c3``
* ``espressif:esp32:esp32c6`` * ``espressif:esp32:esp32c6``
* ``espressif:esp32:esp32h2`` * ``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. 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``. 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. 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/>`_. 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: 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 * esp32c3
* esp32c6 * esp32c6
* esp32h2 * esp32h2
* esp32p4
Set Build Type Set Build Type
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^

View file

@ -1,18 +1,19 @@
#!/bin/bash
# Bash helper functions for adding SSH keys # Bash helper functions for adding SSH keys
function add_ssh_keys() { function add_ssh_keys {
local key_string="${1}" local key_string="${1}"
mkdir -p ~/.ssh mkdir -p ~/.ssh
chmod 700 ~/.ssh chmod 700 ~/.ssh
echo -n "${key_string}" >~/.ssh/id_rsa_base64 echo -n "${key_string}" >~/.ssh/id_rsa_base64
base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 >~/.ssh/id_rsa base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 >~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa
} }
function add_doc_server_ssh_keys() { function add_doc_server_ssh_keys {
local key_string="${1}" local key_string="${1}"
local server_url="${2}" local server_url="${2}"
local server_user="${3}" local server_user="${3}"
add_ssh_keys "${key_string}" add_ssh_keys "${key_string}"
echo -e "Host ${server_url}\n\tStrictHostKeyChecking no\n\tUser ${server_user}\n" >>~/.ssh/config echo -e "Host ${server_url}\n\tStrictHostKeyChecking no\n\tUser ${server_user}\n" >>~/.ssh/config
} }

View file

@ -9,6 +9,7 @@ targets:
- esp32c3 - esp32c3
- esp32c6 - esp32c6
- esp32h2 - esp32h2
- esp32p4
tags: tags:
- arduino - arduino
files: files:
@ -20,6 +21,7 @@ files:
- "variants/esp32c3/**/*" - "variants/esp32c3/**/*"
- "variants/esp32c6/**/*" - "variants/esp32c6/**/*"
- "variants/esp32h2/**/*" - "variants/esp32h2/**/*"
- "variants/esp32p4/**/*"
exclude: exclude:
- "docs/" - "docs/"
- "docs/**/*" - "docs/**/*"
@ -42,47 +44,72 @@ files:
- "platform.txt" - "platform.txt"
- "programmers.txt" - "programmers.txt"
dependencies: dependencies:
idf: ">=5.1,<5.2" idf: ">=5.3,<5.4"
# mdns 1.2.1 is necessary to build H2 with no WiFi # mdns 1.2.1 is necessary to build H2 with no WiFi
espressif/mdns: espressif/mdns:
version: "^1.2.3" version: "^1.2.3"
require: public require: public
espressif/esp_modem: espressif/esp_modem:
version: "^1.1.0" version: "^1.1.0"
espressif/network_provisioning:
version: "~1.0.0"
espressif/esp-zboss-lib: espressif/esp-zboss-lib:
version: "^1.0.1" version: "==1.6.0"
require: public
rules: rules:
- if: "target != esp32c2" - if: "target not in [esp32c2, esp32p4]"
espressif/esp-zigbee-lib: espressif/esp-zigbee-lib:
version: "^1.0.1" version: "==1.6.0"
require: public
rules: rules:
- if: "target != esp32c2" - if: "target not in [esp32c2, esp32p4]"
espressif/esp-dsp: espressif/esp-dsp:
version: "^1.3.4" version: "^1.3.4"
rules: rules:
- if: "target != esp32c2" - 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: espressif/esp_rainmaker:
version: "^1.0.0" version: "1.5.0"
rules: rules:
- if: "target != esp32c2" - if: "target not in [esp32c2, esp32p4]"
espressif/rmaker_common: espressif/rmaker_common:
version: "^1.4.6" version: "1.4.6"
rules: rules:
- if: "target != esp32c2" - if: "target not in [esp32c2, esp32p4]"
espressif/esp_insights: espressif/esp_insights:
version: "^1.2.1" version: "1.0.1"
rules: 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: espressif/qrcode:
version: "^0.1.0~1" version: "0.1.0~2"
rules: rules:
- if: "target != esp32c2" - if: "target not in [esp32c2, esp32p4]"
# RainMaker End
espressif/esp-sr: espressif/esp-sr:
version: "^1.4.2" version: "^1.4.2"
rules: rules:
- if: "target in [esp32s3]" - 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: espressif/libsodium:
version: "^1.0.20~1" version: "^1.0.20~1"
require: public require: public

View file

@ -1,5 +1,5 @@
name=ArduinoOTA name=ArduinoOTA
version=3.0.5 version=3.1.0
author=Ivan Grokhotkov and Hristo Gochkov author=Ivan Grokhotkov and Hristo Gochkov
maintainer=Hristo Gochkov <hristo@espressif.com> maintainer=Hristo Gochkov <hristo@espressif.com>
sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download. 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]); sprintf(tmp, "esp32-%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
_hostname = tmp; _hostname = tmp;
} }
#ifdef CONFIG_MDNS_MAX_INTERFACES
if (_mdnsEnabled) { if (_mdnsEnabled) {
MDNS.begin(_hostname.c_str()); MDNS.begin(_hostname.c_str());
MDNS.enableArduino(_port, (_password.length() > 0)); MDNS.enableArduino(_port, (_password.length() > 0));
} }
#endif
_initialized = true; _initialized = true;
_state = OTA_IDLE; _state = OTA_IDLE;
log_i("OTA server at: %s.local:%u", _hostname.c_str(), _port); log_i("OTA server at: %s.local:%u", _hostname.c_str(), _port);
@ -372,9 +374,11 @@ void ArduinoOTAClass::_runUpdate() {
void ArduinoOTAClass::end() { void ArduinoOTAClass::end() {
_initialized = false; _initialized = false;
_udp_ota.stop(); _udp_ota.stop();
#ifdef CONFIG_MDNS_MAX_INTERFACES
if (_mdnsEnabled) { if (_mdnsEnabled) {
MDNS.end(); MDNS.end();
} }
#endif
_state = OTA_IDLE; _state = OTA_IDLE;
log_i("OTA server stopped."); log_i("OTA server stopped.");
} }

View file

@ -1,5 +1,5 @@
name=ESP32 Async UDP name=ESP32 Async UDP
version=3.0.5 version=3.1.0
author=Me-No-Dev author=Me-No-Dev
maintainer=Me-No-Dev maintainer=Me-No-Dev
sentence=Async UDP Library for ESP32 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); pbuf_ref(_pb);
//memcpy(&_remoteIp, raddr, sizeof(ip_addr_t)); //memcpy(&_remoteIp, raddr, sizeof(ip_addr_t));
#if CONFIG_LWIP_IPV6
_remoteIp.type = raddr->type; _remoteIp.type = raddr->type;
_localIp.type = _remoteIp.type; _localIp.type = _remoteIp.type;
#endif
eth_hdr *eth = NULL; eth_hdr *eth = NULL;
udp_hdr *udphdr = (udp_hdr *)(_data - UDP_HLEN); udp_hdr *udphdr = (udp_hdr *)(_data - UDP_HLEN);
_localPort = ntohs(udphdr->dest); _localPort = ntohs(udphdr->dest);
_remotePort = ntohs(udphdr->src); _remotePort = ntohs(udphdr->src);
#if CONFIG_LWIP_IPV6
if (_remoteIp.type == IPADDR_TYPE_V4) { if (_remoteIp.type == IPADDR_TYPE_V4) {
#endif
eth = (eth_hdr *)(_data - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR); eth = (eth_hdr *)(_data - UDP_HLEN - IP_HLEN - SIZEOF_ETH_HDR);
struct ip_hdr *iphdr = (struct ip_hdr *)(_data - UDP_HLEN - IP_HLEN); struct ip_hdr *iphdr = (struct ip_hdr *)(_data - UDP_HLEN - IP_HLEN);
#if CONFIG_LWIP_IPV6
_localIp.u_addr.ip4.addr = iphdr->dest.addr; _localIp.u_addr.ip4.addr = iphdr->dest.addr;
_remoteIp.u_addr.ip4.addr = iphdr->src.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 { } else {
eth = (eth_hdr *)(_data - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR); eth = (eth_hdr *)(_data - UDP_HLEN - IP6_HLEN - SIZEOF_ETH_HDR);
struct ip6_hdr *ip6hdr = (struct ip6_hdr *)(_data - UDP_HLEN - IP6_HLEN); 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(&_localIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->dest.addr, 16);
memcpy(&_remoteIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->src.addr, 16); memcpy(&_remoteIp.u_addr.ip6.addr, (uint8_t *)ip6hdr->src.addr, 16);
} }
#endif
memcpy(_remoteMac, eth->src.addr, 6); memcpy(_remoteMac, eth->src.addr, 6);
struct netif *netif = NULL; struct netif *netif = NULL;
@ -413,36 +424,48 @@ tcpip_adapter_if_t AsyncUDPPacket::interface() {
} }
IPAddress AsyncUDPPacket::localIP() { IPAddress AsyncUDPPacket::localIP() {
#if CONFIG_LWIP_IPV6
if (_localIp.type != IPADDR_TYPE_V4) { if (_localIp.type != IPADDR_TYPE_V4) {
return IPAddress(); return IPAddress();
} }
return IPAddress(_localIp.u_addr.ip4.addr); return IPAddress(_localIp.u_addr.ip4.addr);
#else
return IPAddress(_localIp.addr);
#endif
} }
#if CONFIG_LWIP_IPV6
IPAddress AsyncUDPPacket::localIPv6() { IPAddress AsyncUDPPacket::localIPv6() {
if (_localIp.type != IPADDR_TYPE_V6) { if (_localIp.type != IPADDR_TYPE_V6) {
return IPAddress(IPv6); return IPAddress(IPv6);
} }
return IPAddress(IPv6, (const uint8_t *)_localIp.u_addr.ip6.addr, _localIp.u_addr.ip6.zone); return IPAddress(IPv6, (const uint8_t *)_localIp.u_addr.ip6.addr, _localIp.u_addr.ip6.zone);
} }
#endif
uint16_t AsyncUDPPacket::localPort() { uint16_t AsyncUDPPacket::localPort() {
return _localPort; return _localPort;
} }
IPAddress AsyncUDPPacket::remoteIP() { IPAddress AsyncUDPPacket::remoteIP() {
#if CONFIG_LWIP_IPV6
if (_remoteIp.type != IPADDR_TYPE_V4) { if (_remoteIp.type != IPADDR_TYPE_V4) {
return IPAddress(); return IPAddress();
} }
return IPAddress(_remoteIp.u_addr.ip4.addr); return IPAddress(_remoteIp.u_addr.ip4.addr);
#else
return IPAddress(_remoteIp.addr);
#endif
} }
#if CONFIG_LWIP_IPV6
IPAddress AsyncUDPPacket::remoteIPv6() { IPAddress AsyncUDPPacket::remoteIPv6() {
if (_remoteIp.type != IPADDR_TYPE_V6) { if (_remoteIp.type != IPADDR_TYPE_V6) {
return IPAddress(IPv6); return IPAddress(IPv6);
} }
return IPAddress(IPv6, (const uint8_t *)_remoteIp.u_addr.ip6.addr, _remoteIp.u_addr.ip6.zone); return IPAddress(IPv6, (const uint8_t *)_remoteIp.u_addr.ip6.addr, _remoteIp.u_addr.ip6.zone);
} }
#endif
uint16_t AsyncUDPPacket::remotePort() { uint16_t AsyncUDPPacket::remotePort() {
return _remotePort; return _remotePort;
@ -453,14 +476,22 @@ void AsyncUDPPacket::remoteMac(uint8_t *mac) {
} }
bool AsyncUDPPacket::isIPv6() { bool AsyncUDPPacket::isIPv6() {
#if CONFIG_LWIP_IPV6
return _localIp.type == IPADDR_TYPE_V6; return _localIp.type == IPADDR_TYPE_V6;
#else
return false;
#endif
} }
bool AsyncUDPPacket::isBroadcast() { bool AsyncUDPPacket::isBroadcast() {
#if CONFIG_LWIP_IPV6
if (_localIp.type == IPADDR_TYPE_V6) { if (_localIp.type == IPADDR_TYPE_V6) {
return false; return false;
} }
uint32_t ip = _localIp.u_addr.ip4.addr; uint32_t ip = _localIp.u_addr.ip4.addr;
#else
uint32_t ip = _localIp.addr;
#endif
return ip == 0xFFFFFFFF || ip == 0 || (ip & 0xFF000000) == 0xFF000000; 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; netif = (struct netif *)nif;
#if CONFIG_LWIP_IPV6
if (addr->type == IPADDR_TYPE_V4) { if (addr->type == IPADDR_TYPE_V4) {
if (join) { if (join) {
if (igmp_joingroup_netif(netif, (const ip4_addr *)&(addr->u_addr.ip4))) { 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 { } else {
#if CONFIG_LWIP_IPV6
if (addr->type == IPADDR_TYPE_V4) { if (addr->type == IPADDR_TYPE_V4) {
if (join) { if (join) {
if (igmp_joingroup((const ip4_addr *)IP4_ADDR_ANY, (const ip4_addr *)&(addr->u_addr.ip4))) { 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; return ESP_OK;
} }
@ -722,18 +777,24 @@ size_t AsyncUDP::writeTo(const uint8_t *data, size_t len, const IPAddress addr,
} }
IPAddress AsyncUDP::listenIP() { IPAddress AsyncUDP::listenIP() {
#if CONFIG_LWIP_IPV6
if (!_pcb || _pcb->remote_ip.type != IPADDR_TYPE_V4) { if (!_pcb || _pcb->remote_ip.type != IPADDR_TYPE_V4) {
return IPAddress(); return IPAddress();
} }
return IPAddress(_pcb->remote_ip.u_addr.ip4.addr); return IPAddress(_pcb->remote_ip.u_addr.ip4.addr);
#else
return IPAddress(_pcb->remote_ip.addr);
#endif
} }
#if CONFIG_LWIP_IPV6
IPAddress AsyncUDP::listenIPv6() { IPAddress AsyncUDP::listenIPv6() {
if (!_pcb || _pcb->remote_ip.type != IPADDR_TYPE_V6) { if (!_pcb || _pcb->remote_ip.type != IPADDR_TYPE_V6) {
return IPAddress(IPv6); return IPAddress(IPv6);
} }
return IPAddress(IPv6, (const uint8_t *)_pcb->remote_ip.u_addr.ip6.addr, _pcb->remote_ip.u_addr.ip6.zone); 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) { size_t AsyncUDP::write(const uint8_t *data, size_t len) {
return writeTo(data, len, &(_pcb->remote_ip), _pcb->remote_port); return writeTo(data, len, &(_pcb->remote_ip), _pcb->remote_port);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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