forked from espressif/arduino-esp32
Compare commits
160 Commits
Author | SHA1 | Date | |
---|---|---|---|
142fceb856 | |||
ba591fd958 | |||
4453ca5493 | |||
ce2cd111a1 | |||
5f6d093d4a | |||
51bf1832b8 | |||
384dbc2081 | |||
f2cfe78705 | |||
45583af189 | |||
f60cd8a069 | |||
5fa0c2010e | |||
adfaaecc65 | |||
0dd517dc9f | |||
823fe77e41 | |||
a9d33de70e | |||
d7ffd573d0 | |||
b88a70a0bd | |||
f3bdfb31f9 | |||
d8a99ed449 | |||
0a1ba74b60 | |||
1aa16104ff | |||
22c51579da | |||
f0636d515f | |||
b3c203db26 | |||
323bbbf63b | |||
02f4178b72 | |||
e1c9606531 | |||
fb60efd592 | |||
12045d335b | |||
45b7fa05b6 | |||
d3340837c7 | |||
6cfe4613e4 | |||
7dc8ca4e1e | |||
d4e20294e5 | |||
f1acc432af | |||
6fe1c4c5d6 | |||
5d6b9d0939 | |||
6b72fee59b | |||
a1409ef90d | |||
ab197e12a9 | |||
1e388a24ce | |||
7c9b837cdb | |||
5c5a112ffa | |||
31510f4e17 | |||
aa783e6ac4 | |||
9d188f5c67 | |||
51040cc4eb | |||
c26e3f4299 | |||
ab34321a16 | |||
8ee5f0a11e | |||
3f79097d5f | |||
e03a9f5c53 | |||
528c071299 | |||
7b89b39e10 | |||
905f8f2991 | |||
c25feca639 | |||
6014ff433f | |||
77e95311e0 | |||
8fe0efe8c0 | |||
0b10c8b79e | |||
d977359e34 | |||
ba8024c0d2 | |||
e87b87d04c | |||
9b9744f25f | |||
68daea4a4a | |||
52e018198b | |||
883241229e | |||
9b00d4ae6b | |||
66596fa581 | |||
02a3a71e7c | |||
3a7dfa14db | |||
96f8f5e3ef | |||
4da1051266 | |||
7d4992a811 | |||
95b8e7e42b | |||
e8d6050a7b | |||
683dbf3b1b | |||
c2e5957f35 | |||
eae67a9fb4 | |||
52575d63f4 | |||
d1f0d6c0fc | |||
bf58ab65e9 | |||
c280225738 | |||
4f7e88a177 | |||
b254765ef8 | |||
8899de760a | |||
524279d468 | |||
f319804521 | |||
2884215f85 | |||
a57cac63e4 | |||
de6994187d | |||
491444c15a | |||
a135169176 | |||
b5f3d6c836 | |||
d5e8c9dddc | |||
65cfab7868 | |||
4517b9c8fc | |||
dad946a641 | |||
7c58696223 | |||
02a70bbd21 | |||
50e9772ecf | |||
01303b700d | |||
4900979906 | |||
c7cc5c90eb | |||
70b7c3afcb | |||
e83a9b5f60 | |||
7be846cb23 | |||
2c7052a64c | |||
c99f594b63 | |||
05d8cddee7 | |||
c4954dd582 | |||
4cbb7389db | |||
ab6e010c20 | |||
7eec41dcb5 | |||
9dbc908784 | |||
9b066ea61c | |||
bb4d9027dd | |||
1046f59f6b | |||
6591f5bd4c | |||
0ea485e518 | |||
3a96fc0e4a | |||
5be3ff74ea | |||
dafdc05249 | |||
ef35baffb0 | |||
7a6dae02aa | |||
9f08cf4767 | |||
96a5ddcd0e | |||
9fe34f6553 | |||
cbeb7c4df8 | |||
754ceddf48 | |||
39a2080922 | |||
9555ed4b76 | |||
0d665d7e55 | |||
bb7df04446 | |||
ce68d72157 | |||
6a7bcabd6b | |||
a61609376a | |||
4a1cbeb69b | |||
a5932064f9 | |||
a45790b20e | |||
0b4516eef5 | |||
cbfcfbf970 | |||
c9b0dc99d3 | |||
a134088a0b | |||
78b2df74f5 | |||
77756d8a06 | |||
c6e30e0027 | |||
41d972564c | |||
a0beb81a4c | |||
460af2e1a5 | |||
48a722aae8 | |||
702db50627 | |||
1ac3aefa61 | |||
e84e9c153e | |||
1d3ff0520a | |||
b3b3403296 | |||
c014eaf352 | |||
5ae3886c66 | |||
1bbe61ab6f | |||
841599c248 |
8
.github/ISSUE_TEMPLATE/Feature-request.yml
vendored
8
.github/ISSUE_TEMPLATE/Feature-request.yml
vendored
@ -52,3 +52,11 @@ body:
|
||||
label: Additional context
|
||||
description: Please add any other context or screenshots about the feature request here.
|
||||
placeholder: ex. This would work only when ...
|
||||
- type: checkboxes
|
||||
id: confirmation
|
||||
attributes:
|
||||
label: I have checked existing list of Feature requests and the Contribution Guide
|
||||
description: You agree to check all the resources above before opening a new Feature request.
|
||||
options:
|
||||
- label: I confirm I have checked existing list of Feature requests and Contribution Guide.
|
||||
required: true
|
||||
|
10
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
10
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
@ -39,7 +39,9 @@ body:
|
||||
label: Version
|
||||
description: What version of Arduino ESP32 are you running? If possible, consider updating to the latest version.
|
||||
options:
|
||||
- latest master
|
||||
- latest master (checkout manually)
|
||||
- latest development Release Candidate (RC-X)
|
||||
- v2.0.2
|
||||
- v2.0.1
|
||||
- v2.0.0
|
||||
- v1.0.6
|
||||
@ -51,7 +53,7 @@ body:
|
||||
attributes:
|
||||
label: IDE Name
|
||||
description: What IDE are you using?
|
||||
placeholder: eg. Arduino IDE, PlatformIO, IDF component...
|
||||
placeholder: eg. Arduino IDE, PlatformIO, Sloeber...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
@ -100,8 +102,8 @@ body:
|
||||
id: sketch
|
||||
attributes:
|
||||
label: Sketch
|
||||
description: Please provide your sketch/code which was run
|
||||
placeholder: ex. related part of the code
|
||||
description: Please provide full minimal sketch/code which can be run to reproduce your issue
|
||||
placeholder: ex. Related part of the code to replicate the issue
|
||||
render: cpp
|
||||
validations:
|
||||
required: true
|
||||
|
21
.github/PULL_REQUEST_TEMPLATE.md
vendored
21
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,18 +1,23 @@
|
||||
*By completing this PR sufficiently, you help us to improve the quality of Release Notes*
|
||||
*By completing this PR sufficiently, you help us to review this Pull Request quicker and also help improve the quality of Release Notes*
|
||||
|
||||
### Checklist
|
||||
1. [ ] Please provide specific title of the PR describing the change, including the component name (eg. *„Update of Documentation link on Readme.md“*)
|
||||
2. [ ] Please provide related links (eg. Issue, other Project, submodule PR..)
|
||||
3. [ ] Please check [Contributing guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html)
|
||||
1. [ ] Please provide specific title of the PR describing the change, including the component name (*eg. „Update of Documentation link on Readme.md“*)
|
||||
2. [ ] Please provide related links (*eg. Issue which will be closed by this Pull Request*)
|
||||
3. [ ] Please **update relevant Documentation** if applicable
|
||||
4. [ ] Please check [Contributing guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html)
|
||||
|
||||
*This entire section above can be deleted if all items are checked.*
|
||||
|
||||
-----------
|
||||
## Summary
|
||||
Please describe your proposed PR and what it contains.
|
||||
## Description of Change
|
||||
Please describe your proposed Pull Request and it's impact.
|
||||
|
||||
## Impact
|
||||
Please describe impact of your PR and it's function.
|
||||
## Tests scenarios
|
||||
Please describe on what Hardware and Software combinations you have tested this Pull Request and how.
|
||||
|
||||
(*eg. I have tested my Pull Request on Arduino-esp32 core v2.0.2 with ESP32 and ESP32-S2 Board with this scenario*)
|
||||
|
||||
## Related links
|
||||
Please provide links to related issue, PRs etc.
|
||||
|
||||
(*eg. Closes #number of issue*)
|
||||
|
50
.github/scripts/install-arduino-core-esp32.sh
vendored
50
.github/scripts/install-arduino-core-esp32.sh
vendored
@ -2,35 +2,35 @@
|
||||
|
||||
export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32"
|
||||
if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
|
||||
echo "Installing ESP32 Arduino Core ..."
|
||||
script_init_path="$PWD"
|
||||
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif"
|
||||
cd "$ARDUINO_USR_PATH/hardware/espressif"
|
||||
echo "Installing ESP32 Arduino Core ..."
|
||||
script_init_path="$PWD"
|
||||
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif"
|
||||
cd "$ARDUINO_USR_PATH/hardware/espressif"
|
||||
|
||||
echo "Installing Python Serial ..."
|
||||
pip install pyserial > /dev/null
|
||||
echo "Installing Python Serial ..."
|
||||
pip install pyserial > /dev/null
|
||||
|
||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||
echo "Installing Python Requests ..."
|
||||
pip install requests > /dev/null
|
||||
fi
|
||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||
echo "Installing Python Requests ..."
|
||||
pip install requests > /dev/null
|
||||
fi
|
||||
|
||||
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
|
||||
echo "Linking Core..."
|
||||
ln -s $GITHUB_WORKSPACE esp32
|
||||
else
|
||||
echo "Cloning Core Repository..."
|
||||
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
|
||||
fi
|
||||
if [ ! -z "$GITHUB_REPOSITORY" ]; then
|
||||
echo "Linking Core..."
|
||||
ln -s $GITHUB_WORKSPACE esp32
|
||||
else
|
||||
echo "Cloning Core Repository..."
|
||||
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
#echo "Updating Submodules ..."
|
||||
cd esp32
|
||||
#git submodule update --init --recursive > /dev/null 2>&1
|
||||
#echo "Updating Submodules ..."
|
||||
cd esp32
|
||||
#git submodule update --init --recursive > /dev/null 2>&1
|
||||
|
||||
echo "Installing Platform Tools ..."
|
||||
cd tools && python get.py
|
||||
cd $script_init_path
|
||||
echo "Installing Platform Tools ..."
|
||||
cd tools && python get.py
|
||||
cd $script_init_path
|
||||
|
||||
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"
|
||||
echo ""
|
||||
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"
|
||||
echo ""
|
||||
fi
|
||||
|
258
.github/scripts/install-arduino-ide.sh
vendored
258
.github/scripts/install-arduino-ide.sh
vendored
@ -6,46 +6,43 @@
|
||||
|
||||
OSBITS=`arch`
|
||||
if [[ "$OSTYPE" == "linux"* ]]; then
|
||||
export OS_IS_LINUX="1"
|
||||
ARCHIVE_FORMAT="tar.xz"
|
||||
if [[ "$OSBITS" == "i686" ]]; then
|
||||
OS_NAME="linux32"
|
||||
elif [[ "$OSBITS" == "x86_64" ]]; then
|
||||
OS_NAME="linux64"
|
||||
elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then
|
||||
OS_NAME="linuxarm"
|
||||
else
|
||||
OS_NAME="$OSTYPE-$OSBITS"
|
||||
echo "Unknown OS '$OS_NAME'"
|
||||
exit 1
|
||||
fi
|
||||
export OS_IS_LINUX="1"
|
||||
ARCHIVE_FORMAT="tar.xz"
|
||||
if [[ "$OSBITS" == "i686" ]]; then
|
||||
OS_NAME="linux32"
|
||||
elif [[ "$OSBITS" == "x86_64" ]]; then
|
||||
OS_NAME="linux64"
|
||||
elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then
|
||||
OS_NAME="linuxarm"
|
||||
else
|
||||
OS_NAME="$OSTYPE-$OSBITS"
|
||||
echo "Unknown OS '$OS_NAME'"
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
export OS_IS_MACOS="1"
|
||||
ARCHIVE_FORMAT="zip"
|
||||
OS_NAME="macosx"
|
||||
export OS_IS_MACOS="1"
|
||||
ARCHIVE_FORMAT="zip"
|
||||
OS_NAME="macosx"
|
||||
elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
|
||||
export OS_IS_WINDOWS="1"
|
||||
ARCHIVE_FORMAT="zip"
|
||||
OS_NAME="windows"
|
||||
export OS_IS_WINDOWS="1"
|
||||
ARCHIVE_FORMAT="zip"
|
||||
OS_NAME="windows"
|
||||
else
|
||||
OS_NAME="$OSTYPE-$OSBITS"
|
||||
echo "Unknown OS '$OS_NAME'"
|
||||
exit 1
|
||||
OS_NAME="$OSTYPE-$OSBITS"
|
||||
echo "Unknown OS '$OS_NAME'"
|
||||
exit 1
|
||||
fi
|
||||
export OS_NAME
|
||||
|
||||
ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
|
||||
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
|
||||
|
||||
if [ "$OS_IS_MACOS" == "1" ]; then
|
||||
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java"
|
||||
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
|
||||
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java"
|
||||
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
|
||||
elif [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
|
||||
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
|
||||
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
|
||||
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
|
||||
else
|
||||
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
|
||||
export ARDUINO_USR_PATH="$HOME/Arduino"
|
||||
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
|
||||
export ARDUINO_USR_PATH="$HOME/Arduino"
|
||||
fi
|
||||
|
||||
# Updated as of Nov 3rd 2020
|
||||
@ -55,184 +52,29 @@ ARDUINO_IDE_URL="https://github.com/espressif/arduino-esp32/releases/download/1.
|
||||
#ARDUINO_IDE_URL="https://www.arduino.cc/download.php?f=/arduino-nightly-"
|
||||
|
||||
if [ ! -d "$ARDUINO_IDE_PATH" ]; then
|
||||
echo "Installing Arduino IDE on $OS_NAME ..."
|
||||
echo "Downloading '$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
|
||||
if [ "$OS_IS_LINUX" == "1" ]; then
|
||||
wget -O "arduino.$ARCHIVE_FORMAT" "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
|
||||
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
|
||||
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
|
||||
mv arduino-nightly "$ARDUINO_IDE_PATH"
|
||||
else
|
||||
curl -o "arduino.$ARCHIVE_FORMAT" -L "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
|
||||
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
|
||||
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
|
||||
if [ "$OS_IS_MACOS" == "1" ]; then
|
||||
mv "Arduino.app" "/Applications/Arduino.app"
|
||||
else
|
||||
mv arduino-nightly "$ARDUINO_IDE_PATH"
|
||||
fi
|
||||
fi
|
||||
rm -rf "arduino.$ARCHIVE_FORMAT"
|
||||
echo "Installing Arduino IDE on $OS_NAME ..."
|
||||
echo "Downloading '$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
|
||||
if [ "$OS_IS_LINUX" == "1" ]; then
|
||||
wget -O "arduino.$ARCHIVE_FORMAT" "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
|
||||
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
|
||||
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
|
||||
mv arduino-nightly "$ARDUINO_IDE_PATH"
|
||||
else
|
||||
curl -o "arduino.$ARCHIVE_FORMAT" -L "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
|
||||
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
|
||||
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
|
||||
if [ "$OS_IS_MACOS" == "1" ]; then
|
||||
mv "Arduino.app" "/Applications/Arduino.app"
|
||||
else
|
||||
mv arduino-nightly "$ARDUINO_IDE_PATH"
|
||||
fi
|
||||
fi
|
||||
rm -rf "arduino.$ARCHIVE_FORMAT"
|
||||
|
||||
mkdir -p "$ARDUINO_USR_PATH/libraries"
|
||||
mkdir -p "$ARDUINO_USR_PATH/hardware"
|
||||
mkdir -p "$ARDUINO_USR_PATH/libraries"
|
||||
mkdir -p "$ARDUINO_USR_PATH/hardware"
|
||||
|
||||
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
|
||||
echo ""
|
||||
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
|
||||
if [ "$#" -lt 2 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: build_sketch <fqbn> <path-to-ino> [extra-options]"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local fqbn="$1"
|
||||
local sketch="$2"
|
||||
local xtra_opts="$3"
|
||||
local win_opts=""
|
||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
|
||||
local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
|
||||
win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
|
||||
fi
|
||||
|
||||
#echo ""
|
||||
#echo "Compiling '"$(basename "$sketch")"' ..."
|
||||
mkdir -p "$ARDUINO_BUILD_DIR"
|
||||
mkdir -p "$ARDUINO_CACHE_DIR"
|
||||
$ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 \
|
||||
-fqbn=$fqbn \
|
||||
-warnings="all" \
|
||||
-tools "$ARDUINO_IDE_PATH/tools-builder" \
|
||||
-tools "$ARDUINO_IDE_PATH/tools" \
|
||||
-built-in-libraries "$ARDUINO_IDE_PATH/libraries" \
|
||||
-hardware "$ARDUINO_IDE_PATH/hardware" \
|
||||
-hardware "$ARDUINO_USR_PATH/hardware" \
|
||||
-libraries "$ARDUINO_USR_PATH/libraries" \
|
||||
-build-cache "$ARDUINO_CACHE_DIR" \
|
||||
-build-path "$ARDUINO_BUILD_DIR" \
|
||||
$win_opts $xtra_opts "$sketch"
|
||||
}
|
||||
|
||||
function count_sketches() # count_sketches <examples-path> <target-mcu>
|
||||
{
|
||||
local examples="$1"
|
||||
local target="$2"
|
||||
rm -rf sketches.txt
|
||||
if [ ! -d "$examples" ]; then
|
||||
touch sketches.txt
|
||||
return 0
|
||||
fi
|
||||
local sketches=$(find $examples -name *.ino)
|
||||
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/.skip.$target" ]]; then
|
||||
continue
|
||||
else
|
||||
echo $sketch >> sketches.txt
|
||||
sketchnum=$(($sketchnum + 1))
|
||||
fi
|
||||
done
|
||||
return $sketchnum
|
||||
}
|
||||
|
||||
function build_sketches() # build_sketches <fqbn> <target-mcu> <examples-path> <chunk> <total-chunks> [extra-options]
|
||||
{
|
||||
local fqbn=$1
|
||||
local target="$2"
|
||||
local examples=$3
|
||||
local chunk_idex=$4
|
||||
local chunks_num=$5
|
||||
local xtra_opts=$6
|
||||
|
||||
if [ "$#" -lt 3 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: build_sketches <fqbn> <target-mcu <examples-path> [<chunk> <total-chunks>] [extra-options]"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$#" -lt 5 ]; then
|
||||
chunk_idex="0"
|
||||
chunks_num="1"
|
||||
xtra_opts=$4
|
||||
fi
|
||||
|
||||
if [ "$chunks_num" -le 0 ]; then
|
||||
echo "ERROR: Chunks count must be positive number"
|
||||
return 1
|
||||
fi
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
|
||||
echo "ERROR: Chunk index must be less than chunks count"
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
count_sketches "$examples" "$target"
|
||||
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=0
|
||||
local end_index=0
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ]; then
|
||||
start_index=$chunk_idex
|
||||
end_index=$sketchcount
|
||||
else
|
||||
start_index=$(( $chunk_idex * $chunk_size ))
|
||||
if [ "$sketchcount" -le "$start_index" ]; then
|
||||
echo "Skipping job"
|
||||
return 0
|
||||
fi
|
||||
|
||||
end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
|
||||
if [ "$end_index" -gt "$sketchcount" ]; then
|
||||
end_index=$sketchcount
|
||||
fi
|
||||
fi
|
||||
|
||||
local start_num=$(( $start_index + 1 ))
|
||||
echo "Found $sketchcount Sketches for target '$target'";
|
||||
echo "Chunk Index : $chunk_idex"
|
||||
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" ] \
|
||||
|| [ -f "$sketchdir/.skip.$target" ]; then
|
||||
continue
|
||||
fi
|
||||
sketchnum=$(($sketchnum + 1))
|
||||
if [ "$sketchnum" -le "$start_index" ] \
|
||||
|| [ "$sketchnum" -gt "$end_index" ]; then
|
||||
continue
|
||||
fi
|
||||
echo ""
|
||||
echo "Building Sketch Index $(($sketchnum - 1)) - $sketchdirname"
|
||||
build_sketch "$fqbn" "$sketch" "$xtra_opts"
|
||||
local result=$?
|
||||
if [ $result -ne 0 ]; then
|
||||
return $result
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
31
.github/scripts/install-platformio-esp32.sh
vendored
31
.github/scripts/install-platformio-esp32.sh
vendored
@ -1,11 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
|
||||
PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master"
|
||||
PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git"
|
||||
|
||||
XTENSA32_TOOLCHAIN_VERSION="8.4.0+2021r1"
|
||||
XTENSA32S2_TOOLCHAIN_VERSION="8.4.0+2021r1"
|
||||
RISCV_TOOLCHAIN_VERSION="8.4.0+2021r1"
|
||||
TOOLCHAIN_VERSION="8.4.0+2021r2-patch3"
|
||||
ESPTOOLPY_VERSION="~1.30100.0"
|
||||
ESPRESSIF_ORGANIZATION_NAME="espressif"
|
||||
|
||||
@ -30,9 +28,12 @@ replace_script+="data['packages']['toolchain-xtensa-esp32']['owner']='$ESPRESSIF
|
||||
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']='$XTENSA32_TOOLCHAIN_VERSION';"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$XTENSA32S2_TOOLCHAIN_VERSION';"
|
||||
replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$RISCV_TOOLCHAIN_VERSION';"
|
||||
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-riscv32-esp']['version']='$TOOLCHAIN_VERSION';"
|
||||
# Add ESP32-S3 Toolchain
|
||||
replace_script+="data['packages'].update({'toolchain-xtensa-esp32s3':{'type':'toolchain','optional':True,'owner':'$ESPRESSIF_ORGANIZATION_NAME','version':'$TOOLCHAIN_VERSION'}});"
|
||||
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
|
||||
@ -40,11 +41,11 @@ 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"
|
||||
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
|
||||
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"
|
||||
@ -66,8 +67,7 @@ function build_pio_sketch(){ # build_pio_sketch <board> <options> <path-to-ino>
|
||||
python -m platformio ci --board "$board" "$sketch_dir" --project-option="$options"
|
||||
}
|
||||
|
||||
function count_sketches() # count_sketches <examples-path>
|
||||
{
|
||||
function count_sketches(){ # count_sketches <examples-path>
|
||||
local examples="$1"
|
||||
rm -rf sketches.txt
|
||||
if [ ! -d "$examples" ]; then
|
||||
@ -82,7 +82,7 @@ function count_sketches() # count_sketches <examples-path>
|
||||
local sketchname=$(basename $sketch)
|
||||
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
|
||||
continue
|
||||
fi;
|
||||
fi
|
||||
if [[ -f "$sketchdir/.test.skip" ]]; then
|
||||
continue
|
||||
fi
|
||||
@ -92,8 +92,7 @@ function count_sketches() # count_sketches <examples-path>
|
||||
return $sketchnum
|
||||
}
|
||||
|
||||
function build_pio_sketches() # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks>
|
||||
{
|
||||
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>]"
|
||||
|
2
.github/scripts/on-pages.sh
vendored
2
.github/scripts/on-pages.sh
vendored
@ -71,7 +71,7 @@ function git_safe_upload_to_pages(){
|
||||
local name=$(basename "$file")
|
||||
local size=`get_file_size "$file"`
|
||||
local upload_res=`git_upload_to_pages "$path" "$file"`
|
||||
if [ $? -ne 0 ]; then
|
||||
if [ $? -ne 0 ]; then
|
||||
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||
return 1
|
||||
fi
|
||||
|
154
.github/scripts/on-push.sh
vendored
154
.github/scripts/on-push.sh
vendored
@ -2,92 +2,118 @@
|
||||
|
||||
set -e
|
||||
|
||||
export ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
|
||||
|
||||
function build(){
|
||||
local target=$1
|
||||
local fqbn=$2
|
||||
local chunk_index=$3
|
||||
local chunks_cnt=$4
|
||||
local sketches=$5
|
||||
|
||||
local BUILD_SKETCH="${SCRIPTS_DIR}/sketch_utils.sh build"
|
||||
local BUILD_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
|
||||
|
||||
local args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH"
|
||||
|
||||
args+=" \"$fqbn\""
|
||||
|
||||
if [ "$OS_IS_LINUX" == "1" ]; then
|
||||
args+=" $target"
|
||||
args+=" $ARDUINO_ESP32_PATH/libraries"
|
||||
args+=" $chunk_index $chunks_cnt"
|
||||
${BUILD_SKETCHES} ${args}
|
||||
else
|
||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
|
||||
local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
|
||||
win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version
|
||||
-prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
|
||||
args+=" ${win_opts}"
|
||||
fi
|
||||
|
||||
for sketch in ${sketches}; do
|
||||
${BUILD_SKETCH} ${args} ${sketch}
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -z "$GITHUB_WORKSPACE" ]; then
|
||||
export GITHUB_WORKSPACE="$PWD"
|
||||
export GITHUB_REPOSITORY="espressif/arduino-esp32"
|
||||
export GITHUB_WORKSPACE="$PWD"
|
||||
export GITHUB_REPOSITORY="espressif/arduino-esp32"
|
||||
fi
|
||||
|
||||
CHUNK_INDEX=$1
|
||||
CHUNKS_CNT=$2
|
||||
BUILD_PIO=0
|
||||
if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then
|
||||
CHUNK_INDEX=0
|
||||
CHUNKS_CNT=1
|
||||
CHUNK_INDEX=0
|
||||
CHUNKS_CNT=1
|
||||
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
|
||||
BUILD_PIO=1
|
||||
fi
|
||||
|
||||
#echo "Updating submodules ..."
|
||||
#git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
|
||||
|
||||
SCRIPTS_DIR="./.github/scripts"
|
||||
if [ "$BUILD_PIO" -eq 0 ]; then
|
||||
# ArduinoIDE ESP32 Test
|
||||
TARGET="esp32"
|
||||
FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
|
||||
source ./.github/scripts/install-arduino-ide.sh
|
||||
source ./.github/scripts/install-arduino-core-esp32.sh
|
||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
|
||||
elif [ "$OS_IS_MACOS" == "1" ]; then
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
|
||||
else
|
||||
# CMake Test
|
||||
if [ "$CHUNK_INDEX" -eq 0 ]; then
|
||||
bash "$ARDUINO_ESP32_PATH/.github/scripts/check-cmakelists.sh"
|
||||
fi
|
||||
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
|
||||
fi
|
||||
source ${SCRIPTS_DIR}/install-arduino-ide.sh
|
||||
source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
|
||||
|
||||
# ArduinoIDE ESP32S2 Test
|
||||
TARGET="esp32s2"
|
||||
FQBN="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
|
||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
|
||||
elif [ "$OS_IS_MACOS" == "1" ]; then
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
|
||||
else
|
||||
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
|
||||
fi
|
||||
FQBN_ESP32="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
|
||||
FQBN_ESP32S2="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
|
||||
FQBN_ESP32S3="espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
|
||||
FQBN_ESP32C3="espressif:esp32:esp32c3:PartitionScheme=huge_app"
|
||||
|
||||
# ArduinoIDE ESP32C3 Test
|
||||
TARGET="esp32c3"
|
||||
FQBN="espressif:esp32:esp32c3:PartitionScheme=huge_app"
|
||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
|
||||
elif [ "$OS_IS_MACOS" == "1" ]; then
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
|
||||
else
|
||||
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
|
||||
fi
|
||||
SKETCHES_ESP32="\
|
||||
$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\
|
||||
$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino\
|
||||
$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\
|
||||
"
|
||||
|
||||
SKETCHES_ESP32XX="\
|
||||
$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\
|
||||
$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino\
|
||||
"
|
||||
|
||||
build "esp32s3" $FQBN_ESP32S3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32
|
||||
build "esp32s2" $FQBN_ESP32S2 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX
|
||||
build "esp32c3" $FQBN_ESP32C3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX
|
||||
build "esp32" $FQBN_ESP32 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32
|
||||
else
|
||||
source ./.github/scripts/install-platformio-esp32.sh
|
||||
# PlatformIO ESP32 Test
|
||||
BOARD="esp32dev"
|
||||
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/WiFiClientSecure/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/BLE_server/BLE_server.ino" && \
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
|
||||
|
||||
# PlatformIO ESP32 Test
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/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/BLE_server/BLE_server.ino" && \
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
|
||||
|
||||
# PlatformIO ESP32 Test
|
||||
# OPTIONS="board_build.mcu = esp32s2"
|
||||
# build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
# build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
|
||||
|
||||
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s2" --project-option="board_build.partitions = huge_app.csv"
|
||||
|
||||
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
|
||||
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32c3" --project-option="board_build.partitions = huge_app.csv"
|
||||
|
||||
echo "Hacking in S3 support ..."
|
||||
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);"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32']['optional']=True;"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32s3']['optional']=False;"
|
||||
replace_script+="data['packages']['tool-esptoolpy']['owner']='tasmota';"
|
||||
replace_script+="data['packages']['tool-esptoolpy']['version']='https://github.com/tasmota/esptool/releases/download/v3.3/esptool-3.3.zip';"
|
||||
replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close()"
|
||||
python -c "$replace_script"
|
||||
|
||||
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s3" --project-option="board_build.partitions = huge_app.csv"
|
||||
|
||||
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
|
||||
fi
|
||||
|
19
.github/scripts/on-release.sh
vendored
19
.github/scripts/on-release.sh
vendored
@ -33,7 +33,7 @@ PACKAGE_JSON_DEV="package_esp32_dev_index.json"
|
||||
PACKAGE_JSON_REL="package_esp32_index.json"
|
||||
|
||||
echo "Event: $GITHUB_EVENT_NAME, Repo: $GITHUB_REPOSITORY, Path: $GITHUB_WORKSPACE, Ref: $GITHUB_REF"
|
||||
echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID"
|
||||
echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID"
|
||||
echo "Tag: $RELEASE_TAG, Draft: $draft, Pre-Release: $RELEASE_PRE"
|
||||
|
||||
function get_file_size(){
|
||||
@ -60,7 +60,7 @@ function git_safe_upload_asset(){
|
||||
local name=$(basename "$file")
|
||||
local size=`get_file_size "$file"`
|
||||
local upload_res=`git_upload_asset "$file"`
|
||||
if [ $? -ne 0 ]; then
|
||||
if [ $? -ne 0 ]; then
|
||||
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||
return 1
|
||||
fi
|
||||
@ -112,7 +112,7 @@ function git_safe_upload_to_pages(){
|
||||
local name=$(basename "$file")
|
||||
local size=`get_file_size "$file"`
|
||||
local upload_res=`git_upload_to_pages "$path" "$file"`
|
||||
if [ $? -ne 0 ]; then
|
||||
if [ $? -ne 0 ]; then
|
||||
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||
return 1
|
||||
fi
|
||||
@ -131,7 +131,7 @@ function merge_package_json(){
|
||||
local jsonOut=$2
|
||||
local old_json=$OUTPUT_DIR/oldJson.json
|
||||
local merged_json=$OUTPUT_DIR/mergedJson.json
|
||||
|
||||
|
||||
echo "Downloading previous JSON $jsonLink ..."
|
||||
curl -L -o "$old_json" "https://github.com/$GITHUB_REPOSITORY/releases/download/$jsonLink?access_token=$GITHUB_TOKEN" 2>/dev/null
|
||||
if [ $? -ne 0 ]; then echo "ERROR: Download Failed! $?"; exit 1; fi
|
||||
@ -140,7 +140,7 @@ function merge_package_json(){
|
||||
set +e
|
||||
stdbuf -oL python "$PACKAGE_JSON_MERGE" "$jsonOut" "$old_json" > "$merged_json"
|
||||
set -e
|
||||
|
||||
|
||||
set -v
|
||||
if [ ! -s $merged_json ]; then
|
||||
rm -f "$merged_json"
|
||||
@ -172,6 +172,7 @@ mkdir -p "$PKG_DIR/tools"
|
||||
# Copy all core files to the package folder
|
||||
echo "Copying files for packaging ..."
|
||||
cp -f "$GITHUB_WORKSPACE/boards.txt" "$PKG_DIR/"
|
||||
cp -f "$GITHUB_WORKSPACE/package.json" "$PKG_DIR/"
|
||||
cp -f "$GITHUB_WORKSPACE/programmers.txt" "$PKG_DIR/"
|
||||
cp -Rf "$GITHUB_WORKSPACE/cores" "$PKG_DIR/"
|
||||
cp -Rf "$GITHUB_WORKSPACE/libraries" "$PKG_DIR/"
|
||||
@ -317,7 +318,7 @@ releaseNotes=""
|
||||
relNotesRaw=`git -C "$GITHUB_WORKSPACE" show -s --format=%b $RELEASE_TAG`
|
||||
readarray -t msgArray <<<"$relNotesRaw"
|
||||
arrLen=${#msgArray[@]}
|
||||
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
|
||||
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
|
||||
ind=3
|
||||
while [ $ind -lt $arrLen ]; do
|
||||
if [ $ind -eq 3 ]; then
|
||||
@ -327,7 +328,7 @@ if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
|
||||
oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')"
|
||||
if [ ${#oneLine} -gt 0 ]; then
|
||||
if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi
|
||||
if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi
|
||||
if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi
|
||||
releaseNotes+="$oneLine"
|
||||
releaseNotes+=$'\r\n'
|
||||
fi
|
||||
@ -368,9 +369,9 @@ done
|
||||
rm -f $commitFile
|
||||
|
||||
# Prepend the original release body
|
||||
if [ "${RELEASE_BODY: -1}" == $'\r' ]; then
|
||||
if [ "${RELEASE_BODY: -1}" == $'\r' ]; then
|
||||
RELEASE_BODY="${RELEASE_BODY:0:-1}"
|
||||
else
|
||||
else
|
||||
RELEASE_BODY="$RELEASE_BODY"
|
||||
fi
|
||||
RELEASE_BODY+=$'\r\n'
|
||||
|
192
.github/scripts/sketch_utils.sh
vendored
Executable file
192
.github/scripts/sketch_utils.sh
vendored
Executable file
@ -0,0 +1,192 @@
|
||||
#!/bin/bash
|
||||
|
||||
function build_sketch(){ # build_sketch <ide_path> <user_path> <fqbn> <path-to-ino> [extra-options]
|
||||
if [ "$#" -lt 4 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: ${0} build <ide_path> <user_path> <fqbn> <path-to-ino> [extra-options]"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local ide_path=$1
|
||||
local usr_path=$2
|
||||
local fqbn=$3
|
||||
local sketch=$4
|
||||
local xtra_opts=$5
|
||||
local win_opts=$6
|
||||
|
||||
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
|
||||
if [ -z "$ARDUINO_BUILD_DIR" ]; then
|
||||
build_dir="$(dirname $sketch)/build"
|
||||
else
|
||||
build_dir="$ARDUINO_BUILD_DIR"
|
||||
fi
|
||||
|
||||
echo $sketch
|
||||
|
||||
rm -rf "$build_dir"
|
||||
mkdir -p "$build_dir"
|
||||
mkdir -p "$ARDUINO_CACHE_DIR"
|
||||
$ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \
|
||||
-fqbn=$fqbn \
|
||||
-warnings="all" \
|
||||
-tools "$ide_path/tools-builder" \
|
||||
-tools "$ide_path/tools" \
|
||||
-built-in-libraries "$ide_path/libraries" \
|
||||
-hardware "$ide_path/hardware" \
|
||||
-hardware "$usr_path/hardware" \
|
||||
-libraries "$usr_path/libraries" \
|
||||
-build-cache "$ARDUINO_CACHE_DIR" \
|
||||
-build-path "$build_dir" \
|
||||
$win_opts $xtra_opts "$sketch"
|
||||
}
|
||||
|
||||
function count_sketches(){ # count_sketches <path> [target]
|
||||
local path=$1
|
||||
local target=$2
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: ${0} count <path> [target]"
|
||||
fi
|
||||
|
||||
rm -rf sketches.txt
|
||||
if [ ! -d "$path" ]; then
|
||||
touch sketches.txt
|
||||
return 0
|
||||
fi
|
||||
|
||||
local sketches=$(find $path -name *.ino | sort)
|
||||
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 [[ -n $target ]] && [[ -f "$sketchdir/.skip.$target" ]]; then
|
||||
continue
|
||||
else
|
||||
echo $sketch >> sketches.txt
|
||||
sketchnum=$(($sketchnum + 1))
|
||||
fi
|
||||
done
|
||||
return $sketchnum
|
||||
}
|
||||
|
||||
function build_sketches(){ # build_sketches <ide_path> <user_path> <fqbn> <target> <path> <chunk> <total-chunks> [extra-options]
|
||||
local ide_path=$1
|
||||
local usr_path=$2
|
||||
local fqbn=$3
|
||||
local target=$4
|
||||
local path=$5
|
||||
local chunk_idex=$6
|
||||
local chunks_num=$7
|
||||
local xtra_opts=$8
|
||||
|
||||
if [ "$#" -lt 7 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: ${0} chunk_build <ide_path> <user_path> <fqbn> <target> <path> [<chunk> <total-chunks>] [extra-options]"
|
||||
return 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" ] && [ "$chunks_num" -ge 2 ]; then
|
||||
echo "ERROR: Chunk index must be less than chunks count"
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
count_sketches "$path" "$target"
|
||||
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=0
|
||||
local end_index=0
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ]; then
|
||||
start_index=$chunk_idex
|
||||
end_index=$sketchcount
|
||||
else
|
||||
start_index=$(( $chunk_idex * $chunk_size ))
|
||||
if [ "$sketchcount" -le "$start_index" ]; then
|
||||
echo "Skipping job"
|
||||
return 0
|
||||
fi
|
||||
|
||||
end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
|
||||
if [ "$end_index" -gt "$sketchcount" ]; then
|
||||
end_index=$sketchcount
|
||||
fi
|
||||
fi
|
||||
|
||||
local start_num=$(( $start_index + 1 ))
|
||||
echo "Found $sketchcount Sketches for target '$target'";
|
||||
echo "Chunk Index : $chunk_idex"
|
||||
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)
|
||||
sketchnum=$(($sketchnum + 1))
|
||||
if [ "$sketchnum" -le "$start_index" ] \
|
||||
|| [ "$sketchnum" -gt "$end_index" ]; then
|
||||
continue
|
||||
fi
|
||||
echo ""
|
||||
echo "Building Sketch Index $(($sketchnum - 1)) - $sketchdirname"
|
||||
build_sketch "$ide_path" "$usr_path" "$fqbn" "$sketch" "$xtra_opts"
|
||||
local result=$?
|
||||
if [ $result -ne 0 ]; then
|
||||
return $result
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
USAGE="
|
||||
USAGE: ${0} [command] [options]
|
||||
Available commands:
|
||||
count: Count sketches.
|
||||
build: Build a sketch.
|
||||
chunk_build: Build a chunk of sketches.
|
||||
"
|
||||
|
||||
cmd=$1
|
||||
shift
|
||||
if [ -z $cmd ]; then
|
||||
echo "ERROR: No command supplied"
|
||||
echo "$USAGE"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "$cmd" in
|
||||
"count")
|
||||
count_sketches $*
|
||||
;;
|
||||
"build")
|
||||
build_sketch $*
|
||||
;;
|
||||
"chunk_build")
|
||||
build_sketches $*
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unrecognized command"
|
||||
echo "$USAGE"
|
||||
exit 2
|
||||
esac
|
||||
|
58
.github/scripts/tests_build.sh
vendored
Executable file
58
.github/scripts/tests_build.sh
vendored
Executable file
@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPTS_DIR="./.github/scripts"
|
||||
BUILD_CMD=""
|
||||
|
||||
if [ $# -eq 3 ]; then
|
||||
chunk_build=1
|
||||
elif [ $# -eq 2 ]; then
|
||||
chunk_build=0
|
||||
else
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE:
|
||||
${0} <target> <sketch_dir>
|
||||
${0} <target> <chunk> <total_chunks>
|
||||
"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
target=$1
|
||||
|
||||
case "$target" in
|
||||
"esp32") fqbn="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
|
||||
;;
|
||||
"esp32s2") fqbn="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
|
||||
;;
|
||||
"esp32c3") fqbn="espressif:esp32:esp32c3:PartitionScheme=huge_app"
|
||||
;;
|
||||
"esp32s3") fqbn="espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z $fqbn ]; then
|
||||
echo "Unvalid chip $1"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
source ${SCRIPTS_DIR}/install-arduino-ide.sh
|
||||
source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
|
||||
|
||||
args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH \"$fqbn\""
|
||||
|
||||
if [ $chunk_build -eq 1 ]; then
|
||||
chunk_index=$2
|
||||
chunk_max=$3
|
||||
|
||||
if [ "$chunk_index" -gt "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then
|
||||
chunk_index=$chunk_max
|
||||
fi
|
||||
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
|
||||
args+=" $target $PWD/tests $chunk_index $chunk_max"
|
||||
else
|
||||
sketchdir=$2
|
||||
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh build"
|
||||
args+=" $PWD/tests/$sketchdir/$sketchdir.ino"
|
||||
fi
|
||||
|
||||
${BUILD_CMD} ${args}
|
||||
|
71
.github/scripts/tests_run.sh
vendored
Executable file
71
.github/scripts/tests_run.sh
vendored
Executable file
@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
|
||||
target=$1
|
||||
chunk_idex=$2
|
||||
chunks_num=$3
|
||||
|
||||
SCRIPTS_DIR="./.github/scripts"
|
||||
COUNT_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh count"
|
||||
|
||||
source ${SCRIPTS_DIR}/install-arduino-ide.sh
|
||||
|
||||
if [ "$chunks_num" -le 0 ]; then
|
||||
echo "ERROR: Chunks count must be positive number"
|
||||
return 1
|
||||
fi
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
|
||||
echo "ERROR: Chunk index must be less than chunks count"
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
${COUNT_SKETCHES} $PWD/tests $target
|
||||
sketchcount=$?
|
||||
set -e
|
||||
sketches=$(cat sketches.txt)
|
||||
rm -rf sketches.txt
|
||||
|
||||
chunk_size=$(( $sketchcount / $chunks_num ))
|
||||
all_chunks=$(( $chunks_num * $chunk_size ))
|
||||
if [ "$all_chunks" -lt "$sketchcount" ]; then
|
||||
chunk_size=$(( $chunk_size + 1 ))
|
||||
fi
|
||||
|
||||
start_index=0
|
||||
end_index=0
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ]; then
|
||||
start_index=$chunk_idex
|
||||
end_index=$sketchcount
|
||||
else
|
||||
start_index=$(( $chunk_idex * $chunk_size ))
|
||||
if [ "$sketchcount" -le "$start_index" ]; then
|
||||
echo "Skipping job"
|
||||
return 0
|
||||
fi
|
||||
|
||||
end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
|
||||
if [ "$end_index" -gt "$sketchcount" ]; then
|
||||
end_index=$sketchcount
|
||||
fi
|
||||
fi
|
||||
|
||||
start_num=$(( $start_index + 1 ))
|
||||
sketchnum=0
|
||||
|
||||
for sketch in $sketches; do
|
||||
sketchdir=$(dirname $sketch)
|
||||
sketchdirname=$(basename $sketchdir)
|
||||
sketchname=$(basename $sketch)
|
||||
sketchnum=$(($sketchnum + 1))
|
||||
if [ "$sketchnum" -le "$start_index" ] \
|
||||
|| [ "$sketchnum" -gt "$end_index" ]; then
|
||||
continue
|
||||
fi
|
||||
echo ""
|
||||
echo "Test for Sketch Index $(($sketchnum - 1)) - $sketchdirname"
|
||||
pytest tests -k test_$sketchdirname --junit-xml=tests/$sketchdirname/$sketchdirname.xml
|
||||
result=$?
|
||||
if [ $result -ne 0 ]; then
|
||||
return $result
|
||||
fi
|
||||
done
|
39
.github/scripts/update-version.sh
vendored
Executable file
39
.github/scripts/update-version.sh
vendored
Executable file
@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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"
|
||||
#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
|
||||
echo "Bad number of arguments: $#" >&2
|
||||
echo "usage: $0 <major> <minor> <patch>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
re='^[0-9]+$'
|
||||
if [[ ! $1 =~ $re ]] || [[ ! $2 =~ $re ]] || [[ ! $3 =~ $re ]] ; then
|
||||
echo "error: Not a valid version: $1.$2.$3" >&2
|
||||
echo "usage: $0 <major> <minor> <patch>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ESP_ARDUINO_VERSION_MAJOR="$1"
|
||||
ESP_ARDUINO_VERSION_MINOR="$2"
|
||||
ESP_ARDUINO_VERSION_PATCH="$3"
|
||||
ESP_ARDUINO_VERSION="$ESP_ARDUINO_VERSION_MAJOR.$ESP_ARDUINO_VERSION_MINOR.$ESP_ARDUINO_VERSION_PATCH"
|
||||
|
||||
echo "New Arduino Version: $ESP_ARDUINO_VERSION"
|
||||
|
||||
echo "Updating platform.txt..."
|
||||
cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > __platform.txt && mv __platform.txt platform.txt
|
||||
|
||||
echo "Updating package.json..."
|
||||
cat package.json | sed "s/.*\"version\":.*/ \"version\": \"$ESP_ARDUINO_VERSION\",/g" > __package.json && mv __package.json package.json
|
||||
|
||||
echo "Updating cores/esp32/esp_arduino_version.h..."
|
||||
cat cores/esp32/esp_arduino_version.h | \
|
||||
sed "s/#define ESP_ARDUINO_VERSION_MAJOR.*/#define ESP_ARDUINO_VERSION_MAJOR $ESP_ARDUINO_VERSION_MAJOR/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
|
||||
|
||||
exit 0
|
26
.github/stale.yml
vendored
26
.github/stale.yml
vendored
@ -1,26 +0,0 @@
|
||||
# This workflow firstly warns and then closes issues that have had no activity for a specified amount of time.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information can be found here: https://github.com/actions/stale
|
||||
|
||||
name: Mark stale issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 9 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.'
|
||||
days-before-stale: 60
|
||||
days-before-close: 14
|
||||
exempt-issue-labels: 'Type: For reference,Type: To be implemented,Type: Feature request'
|
||||
stale-issue-label: 'Status: Stale'
|
121
.github/workflows/hil.yml
vendored
Normal file
121
.github/workflows/hil.yml
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
name: Run tests in hardware
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize, labeled]
|
||||
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
|
||||
env:
|
||||
MAX_CHUNKS: 15
|
||||
|
||||
concurrency:
|
||||
group: hil-${{github.event.pull_request.number || github.ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
gen_chunks:
|
||||
if: |
|
||||
contains(github.event.pull_request.labels.*.name, 'hil_test') ||
|
||||
github.event_name == 'schedule'
|
||||
name: Generate Chunks matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
chunks: ${{ steps.gen-chunks.outputs.chunks }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Generate Chunks matrix
|
||||
id: gen-chunks
|
||||
run: |
|
||||
set +e
|
||||
bash .github/scripts/sketch_utils.sh count tests
|
||||
sketches=$((? - 1))
|
||||
if [[ $sketches -gt ${{env.MAX_CHUNKS}} ]]; then
|
||||
$sketches=${{env.MAX_CHUNKS}}
|
||||
fi
|
||||
set -e
|
||||
rm sketches.txt
|
||||
CHUNKS=$(jq -c -n '$ARGS.positional' --args `seq 0 1 $sketches`)
|
||||
echo "::set-output name=chunks::${CHUNKS}"
|
||||
|
||||
Build:
|
||||
needs: gen_chunks
|
||||
name: ${{matrix.chip}}-Build#${{matrix.chunks}}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
|
||||
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build sketches
|
||||
run: |
|
||||
bash .github/scripts/tests_build.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
|
||||
- name: Upload ${{matrix.chip}}-${{matrix.chunks}} artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
|
||||
path: |
|
||||
tests/*/build/*.bin
|
||||
tests/*/build/*.json
|
||||
Test:
|
||||
needs: [gen_chunks, Build]
|
||||
name: ${{matrix.chip}}-Test#${{matrix.chunks}}
|
||||
runs-on:
|
||||
- ESP32
|
||||
- ESP32-S2
|
||||
- ESP32-S3
|
||||
- ESP32-C3
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
|
||||
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
|
||||
container:
|
||||
image: python:3.10.1-bullseye
|
||||
options: --privileged
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Download ${{matrix.chip}}-${{matrix.chunks}} artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
|
||||
path: tests/
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install -U pip
|
||||
pip install -r tests/requirements.txt
|
||||
|
||||
- name: Run Tests
|
||||
run: |
|
||||
bash .github/scripts/tests_run.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
|
||||
|
||||
- name: Upload test result artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: test_results-${{matrix.chip}}-${{matrix.chunks}}
|
||||
path: tests/*/*.xml
|
||||
|
||||
event_file:
|
||||
name: "Event File"
|
||||
if: ${{ always() }}
|
||||
needs: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Event File
|
||||
path: ${{github.event_path}}
|
38
.github/workflows/publish.yml
vendored
Normal file
38
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: Unit Test Results
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Run tests in hardware]
|
||||
branches-ignore: [master]
|
||||
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
unit-test-results:
|
||||
name: Unit Test Results
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.event.workflow_run.event == 'pull_request' &&
|
||||
(github.event.workflow_run.conclusion == 'success' ||
|
||||
github.event.workflow_run.conclusion == 'failure')
|
||||
steps:
|
||||
- name: Download and Extract Artifacts
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
run: |
|
||||
mkdir -p artifacts && cd artifacts
|
||||
artifacts_url=${{ github.event.workflow_run.artifacts_url }}
|
||||
gh api "$artifacts_url" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact
|
||||
do
|
||||
IFS=$'\t' read name url <<< "$artifact"
|
||||
gh api $url > "$name.zip"
|
||||
unzip -d "$name" "$name.zip"
|
||||
done
|
||||
- name: Publish Unit Test Results
|
||||
uses: EnricoMi/publish-unit-test-result-action@v1
|
||||
with:
|
||||
commit: ${{ github.event.workflow_run.head_sha }}
|
||||
event_file: artifacts/Event File/event.json
|
||||
event_name: ${{ github.event.workflow_run.event }}
|
||||
files: "artifacts/**/*.xml"
|
57
.github/workflows/push.yml
vendored
57
.github/workflows/push.yml
vendored
@ -1,14 +1,26 @@
|
||||
name: ESP32 Arduino CI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: build-${{github.event.pull_request.number || github.ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
|
||||
cmake-check:
|
||||
name: Check cmake file
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: bash ./.github/scripts/check-cmakelists.sh
|
||||
|
||||
# Ubuntu
|
||||
build-arduino-linux:
|
||||
name: Arduino ${{ matrix.chunk }} on ubuntu-latest
|
||||
@ -16,12 +28,22 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Cache tools
|
||||
id: cache-linux
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
./tools/dist
|
||||
~/arduino_ide
|
||||
key: ${{ runner.os }}-${{ hashFiles('package/package_esp32_index.template.json',
|
||||
'tools/get.py',
|
||||
'.github/scripts/install-arduino-ide.sh') }}
|
||||
- name: Build Sketches
|
||||
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} 15
|
||||
|
||||
@ -32,7 +54,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, macOS-latest]
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
@ -48,7 +70,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
@ -56,3 +78,30 @@ jobs:
|
||||
python-version: '3.x'
|
||||
- name: Build Sketches
|
||||
run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO
|
||||
|
||||
build-esp-idf-component:
|
||||
name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
# The version names here correspond to the versions of espressif/idf Docker image.
|
||||
# See https://hub.docker.com/r/espressif/idf/tags and
|
||||
# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html
|
||||
# for details.
|
||||
idf_ver: ["release-v4.4"]
|
||||
idf_target: ["esp32", "esp32s2", "esp32s3", "esp32c3"]
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
steps:
|
||||
- name: Check out arduino-esp32 as a component
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
path: components/arduino-esp32
|
||||
- name: Build
|
||||
env:
|
||||
IDF_TARGET: ${{ matrix.idf_target }}
|
||||
shell: bash
|
||||
run: |
|
||||
. ${IDF_PATH}/export.sh
|
||||
idf.py create-project test
|
||||
idf.py -C test -DEXTRA_COMPONENT_DIRS=$PWD/components build
|
||||
|
28
.github/workflows/test_selfhosted_runner.yml
vendored
28
.github/workflows/test_selfhosted_runner.yml
vendored
@ -1,28 +0,0 @@
|
||||
name: Test Github action on self hosted RPI runnes
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Dummy test - self hosted GHR
|
||||
runs-on: self-hosted
|
||||
if: github.repository == 'espressif/arduino-esp32'
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Test message 1
|
||||
run: echo "This is test message"
|
||||
- name: Test message 2
|
||||
run: echo "This is test message2"
|
||||
- name: List directory
|
||||
run: ls
|
||||
- name: Create copy of README
|
||||
run: cp README.md README2.md
|
||||
- name: Read README2
|
||||
run: cat README2.md
|
||||
- name: Delete README2
|
||||
run: rm README2.md
|
19
.github/workflows/upload-idf-component.yml
vendored
Normal file
19
.github/workflows/upload-idf-component.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: Push components to https://components.espressif.com
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
jobs:
|
||||
upload_components:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Upload components to the component registry
|
||||
uses: espressif/github-actions/upload_components@master
|
||||
with:
|
||||
name: arduino-esp32
|
||||
namespace: espressif
|
||||
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
tools/xtensa-esp32-elf
|
||||
tools/xtensa-esp32s2-elf
|
||||
tools/xtensa-esp32s3-elf
|
||||
tools/riscv32-esp-elf
|
||||
tools/dist
|
||||
tools/esptool
|
||||
@ -22,3 +23,6 @@ boards.sloeber.txt
|
||||
# Ignore docs build (Sphinx)
|
||||
docs/build
|
||||
docs/source/_build
|
||||
|
||||
# Test log files
|
||||
*.log
|
||||
|
@ -57,6 +57,7 @@ set(CORE_SRCS
|
||||
cores/esp32/stdlib_noniso.c
|
||||
cores/esp32/Stream.cpp
|
||||
cores/esp32/StreamString.cpp
|
||||
cores/esp32/Tone.cpp
|
||||
cores/esp32/HWCDC.cpp
|
||||
cores/esp32/USB.cpp
|
||||
cores/esp32/USBCDC.cpp
|
||||
@ -86,6 +87,7 @@ set(LIBRARY_SRCS
|
||||
libraries/HTTPClient/src/HTTPClient.cpp
|
||||
libraries/HTTPUpdate/src/HTTPUpdate.cpp
|
||||
libraries/LittleFS/src/LittleFS.cpp
|
||||
libraries/I2S/src/I2S.cpp
|
||||
libraries/NetBIOS/src/NetBIOS.cpp
|
||||
libraries/Preferences/src/Preferences.cpp
|
||||
libraries/RainMaker/src/RMaker.cpp
|
||||
@ -115,6 +117,7 @@ set(LIBRARY_SRCS
|
||||
libraries/WebServer/src/Parsing.cpp
|
||||
libraries/WebServer/src/detail/mimetable.cpp
|
||||
libraries/WiFiClientSecure/src/ssl_client.cpp
|
||||
libraries/WiFiClientSecure/src/esp_crt_bundle.c
|
||||
libraries/WiFiClientSecure/src/WiFiClientSecure.cpp
|
||||
libraries/WiFi/src/WiFiAP.cpp
|
||||
libraries/WiFi/src/WiFiClient.cpp
|
||||
@ -161,7 +164,6 @@ set(BLE_SRCS
|
||||
libraries/BLE/src/GeneralUtils.cpp
|
||||
)
|
||||
|
||||
|
||||
set(includedirs
|
||||
variants/${IDF_TARGET}/
|
||||
cores/esp32/
|
||||
@ -173,11 +175,13 @@ set(includedirs
|
||||
libraries/EEPROM/src
|
||||
libraries/ESP32/src
|
||||
libraries/ESPmDNS/src
|
||||
libraries/Ethernet/src
|
||||
libraries/FFat/src
|
||||
libraries/FS/src
|
||||
libraries/HTTPClient/src
|
||||
libraries/HTTPUpdate/src
|
||||
libraries/LittleFS/src
|
||||
libraries/I2S/src
|
||||
libraries/NetBIOS/src
|
||||
libraries/Preferences/src
|
||||
libraries/RainMaker/src
|
||||
@ -198,7 +202,7 @@ set(includedirs
|
||||
|
||||
set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS})
|
||||
set(priv_includes cores/esp32/libb64)
|
||||
set(requires spi_flash mbedtls mdns esp_adc_cal wifi_provisioning nghttp)
|
||||
set(requires spi_flash mbedtls mdns esp_adc_cal wifi_provisioning nghttp wpa_supplicant)
|
||||
set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support openssl bt esp_ipc esp_hid)
|
||||
|
||||
idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires})
|
||||
@ -233,7 +237,9 @@ function(maybe_add_component component_name)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if(IDF_TARGET MATCHES "esp32" AND CONFIG_ESP_RMAKER_TASK_STACK)
|
||||
maybe_add_component(esp-dsp)
|
||||
|
||||
if(CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK)
|
||||
maybe_add_component(esp_rainmaker)
|
||||
maybe_add_component(qrcode)
|
||||
endif()
|
||||
|
@ -1,7 +0,0 @@
|
||||
BOOT_APP_BIN_ROOT := $(call dequote,$(COMPONENT_PATH))
|
||||
|
||||
ifndef CONFIG_PARTITION_TABLE_CUSTOM
|
||||
PARTITION_TABLE_CSV_PATH = $(call dequote,$(abspath $(BOOT_APP_BIN_ROOT)/$(subst $(quote),,tools/partitions/$(CONFIG_ARDUHAL_PARTITION_SCHEME).csv)))
|
||||
endif
|
||||
|
||||
CPPFLAGS += -DARDUINO=10800 -DESP32=1 -DARDUINO_ARCH_ESP32=1 -DBOARD_HAS_PSRAM
|
23
README.md
23
README.md
@ -1,14 +1,18 @@
|
||||
# Arduino core for the ESP32, ESP32-S2 and ESP32-C3
|
||||
# Arduino core for the ESP32, ESP32-S2, ESP32-S3 and ESP32-C3
|
||||
|
||||
 [](https://docs.espressif.com/projects/arduino-esp32/en/latest/?badge=latest)
|
||||
|
||||
### Need help or have a question? Join the chat at [](https://gitter.im/espressif/arduino-esp32?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
### Need help or have a question? Join the chat at [](https://gitter.im/espressif/arduino-esp32?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) or [open a new Discussion](https://github.com/espressif/arduino-esp32/discussions)
|
||||
|
||||
## Contents
|
||||
|
||||
- [Development Status](#development-status)
|
||||
- [Decoding Exceptions](#decoding-exceptions)
|
||||
- [Issue/Bug report template](#issuebug-report-template)
|
||||
- [Development Status](#development-status)
|
||||
- [Development Planning](#development-planning)
|
||||
- [Documentation](#documentation)
|
||||
- [Supported Chips](#supported-chips)
|
||||
- [Decoding exceptions](#decoding-exceptions)
|
||||
- [Issue/Bug report template](#issuebug-report-template)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
### Development Status
|
||||
|
||||
@ -16,9 +20,15 @@ Latest Stable Release [](https://github.com/espressif/arduino-esp32/releases/) [](https://github.com/espressif/arduino-esp32/releases/) [](https://github.com/espressif/arduino-esp32/releases/)
|
||||
|
||||
### Development Planning
|
||||
|
||||
Our Development is fully tracked on this public **[Roadmap 🎉](https://github.com/orgs/espressif/projects/3)**
|
||||
|
||||
For even more information you can take a look at [Sprint Meeting notes](https://github.com/espressif/arduino-esp32/discussions/categories/sprints-meeting-notes) or join [Monthly Community Meetings 🔔](https://github.com/espressif/arduino-esp32/discussions/categories/monthly-community-meetings)
|
||||
|
||||
### Documentation
|
||||
|
||||
You can use [Arduino-ESP32 Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/) to get all information about this project.
|
||||
You can use the [Arduino-ESP32 Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/) to get all information about this project.
|
||||
|
||||
* [Getting Started](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html)
|
||||
* [Installing (Windows, Linux and macOS)](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html)
|
||||
@ -36,6 +46,7 @@ Visit the [supported chips](https://docs.espressif.com/projects/arduino-esp32/en
|
||||
You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder) to get meaningful call trace.
|
||||
|
||||
### Issue/Bug report template
|
||||
|
||||
Before reporting an issue, make sure you've searched for similar one that was already created. Also make sure to go through all the issues labelled as [Type: For reference](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue+label%3A%22Type%3A+For+reference%22+).
|
||||
|
||||
Finally, if you are sure no one else had the issue, follow the **Issue template** or **Feature request template** while reporting any [new Issue](https://github.com/espressif/arduino-esp32/issues/new/choose).
|
||||
|
3877
boards.txt
3877
boards.txt
File diff suppressed because it is too large
Load Diff
36
component.mk
36
component.mk
@ -1,36 +0,0 @@
|
||||
ARDUINO_ALL_LIBRARIES := $(patsubst $(COMPONENT_PATH)/libraries/%,%,$(wildcard $(COMPONENT_PATH)/libraries/*))
|
||||
|
||||
# Macro returns non-empty if Arduino library $(1) should be included in the build
|
||||
# (either because selective compilation is of, or this library is enabled
|
||||
define ARDUINO_LIBRARY_ENABLED
|
||||
$(if $(CONFIG_ARDUINO_SELECTIVE_COMPILATION),$(CONFIG_ARDUINO_SELECTIVE_$(1)),y)
|
||||
endef
|
||||
|
||||
ARDUINO_ENABLED_LIBRARIES := $(foreach LIBRARY,$(sort $(ARDUINO_ALL_LIBRARIES)),$(if $(call ARDUINO_LIBRARY_ENABLED,$(LIBRARY)),$(LIBRARY)))
|
||||
|
||||
$(info Arduino libraries in build: $(ARDUINO_ENABLED_LIBRARIES))
|
||||
|
||||
# Expand all subdirs under $(1)
|
||||
define EXPAND_SUBDIRS
|
||||
$(sort $(dir $(wildcard $(1)/* $(1)/*/* $(1)/*/*/* $(1)/*/*/*/* $(1)/*/*/*/*/*)))
|
||||
endef
|
||||
|
||||
# Macro returns SRCDIRS for library
|
||||
define ARDUINO_LIBRARY_GET_SRCDIRS
|
||||
$(if $(wildcard $(COMPONENT_PATH)/libraries/$(1)/src/.), \
|
||||
$(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)/src), \
|
||||
$(filter-out $(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)/examples), \
|
||||
$(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)) \
|
||||
) \
|
||||
)
|
||||
endef
|
||||
|
||||
# Make a list of all srcdirs in enabled libraries
|
||||
ARDUINO_LIBRARY_SRCDIRS := $(patsubst $(COMPONENT_PATH)/%,%,$(foreach LIBRARY,$(ARDUINO_ENABLED_LIBRARIES),$(call ARDUINO_LIBRARY_GET_SRCDIRS,$(LIBRARY))))
|
||||
|
||||
#$(info Arduino libraries src dirs: $(ARDUINO_LIBRARY_SRCDIRS))
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := cores/esp32 variants/esp32 $(ARDUINO_LIBRARY_SRCDIRS)
|
||||
COMPONENT_PRIV_INCLUDEDIRS := cores/esp32/libb64
|
||||
COMPONENT_SRCDIRS := cores/esp32/libb64 cores/esp32 variants/esp32 $(ARDUINO_LIBRARY_SRCDIRS)
|
||||
CXXFLAGS += -fno-rtti
|
@ -166,6 +166,7 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
||||
#include "Udp.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "Esp.h"
|
||||
#include "esp32/spiram.h"
|
||||
|
||||
using std::abs;
|
||||
using std::isinf;
|
||||
@ -181,7 +182,10 @@ uint16_t makeWord(uint8_t h, uint8_t l);
|
||||
|
||||
size_t getArduinoLoopTaskStackSize(void);
|
||||
#define SET_LOOP_TASK_STACK_SIZE(sz) size_t getArduinoLoopTaskStackSize() { return sz;}
|
||||
|
||||
|
||||
// allows user to bypass esp_spiram_test()
|
||||
#define BYPASS_SPIRAM_TEST(bypass) bool testSPIRAM(void) { if (bypass) return true; else return esp_spiram_test(); }
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
|
||||
@ -191,6 +195,10 @@ extern "C" void configTime(long gmtOffset_sec, int daylightOffset_sec,
|
||||
extern "C" void configTzTime(const char* tz,
|
||||
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);
|
||||
|
||||
void setToneChannel(uint8_t channel = 0);
|
||||
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
|
||||
void noTone(uint8_t _pin);
|
||||
|
||||
// WMath prototypes
|
||||
long random(long);
|
||||
#endif /* __cplusplus */
|
||||
|
@ -40,6 +40,10 @@ extern "C" {
|
||||
#include "esp32s2/rom/spi_flash.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#define ESP_FLASH_IMAGE_BASE 0x1000
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/spi_flash.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32s3 is located at 0x0000
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/spi_flash.h"
|
||||
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32c3 is located at 0x0000
|
||||
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "USB.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "HWCDC.h"
|
||||
@ -167,19 +167,21 @@ void HWCDC::begin(unsigned long baud)
|
||||
setRxBufferSize(256);//default if not preset
|
||||
setTxBufferSize(256);//default if not preset
|
||||
|
||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
|
||||
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
|
||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
|
||||
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
|
||||
if(!intr_handle && esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, 0, hw_cdc_isr_handler, NULL, &intr_handle) != ESP_OK){
|
||||
isr_log_e("HW USB CDC failed to init interrupts");
|
||||
end();
|
||||
return;
|
||||
}
|
||||
usb_serial_jtag_ll_txfifo_flush();
|
||||
}
|
||||
|
||||
void HWCDC::end()
|
||||
{
|
||||
//Disable tx/rx interrupt.
|
||||
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
|
||||
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
|
||||
esp_intr_free(intr_handle);
|
||||
intr_handle = NULL;
|
||||
if(tx_lock != NULL) {
|
||||
@ -379,10 +381,12 @@ void HWCDC::setDebugOutput(bool en)
|
||||
}
|
||||
}
|
||||
|
||||
#if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC
|
||||
#if ARDUINO_USB_MODE
|
||||
#if ARDUINO_USB_CDC_ON_BOOT//Serial used for USB CDC
|
||||
HWCDC Serial;
|
||||
#else
|
||||
HWCDC USBSerial;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_TINYUSB_CDC_ENABLED */
|
||||
|
@ -14,7 +14,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "esp_event.h"
|
||||
@ -98,10 +98,12 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC
|
||||
#if ARDUINO_USB_MODE
|
||||
#if ARDUINO_USB_CDC_ON_BOOT//Serial used for USB CDC
|
||||
extern HWCDC Serial;
|
||||
#else
|
||||
extern HWCDC USBSerial;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32C3 */
|
||||
|
@ -6,11 +6,13 @@
|
||||
#include "pins_arduino.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "driver/uart.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#ifndef SOC_RX0
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define SOC_RX0 3
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define SOC_RX0 44
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define SOC_RX0 20
|
||||
@ -20,7 +22,7 @@
|
||||
#ifndef SOC_TX0
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define SOC_TX0 1
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define SOC_TX0 43
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define SOC_TX0 21
|
||||
@ -39,6 +41,8 @@ void serialEvent(void) {}
|
||||
#define RX1 18
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define RX1 18
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define RX1 15
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -49,6 +53,8 @@ void serialEvent(void) {}
|
||||
#define TX1 17
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define TX1 19
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define TX1 16
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -60,12 +66,16 @@ void serialEvent1(void) {}
|
||||
#ifndef RX2
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define RX2 16
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define RX2 19
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef TX2
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define TX2 17
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define TX2 20
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -76,8 +86,6 @@ void serialEvent2(void) {}
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||
HardwareSerial Serial0(0);
|
||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
||||
HardwareSerial Serial0(0);
|
||||
#else
|
||||
HardwareSerial Serial(0);
|
||||
#endif
|
||||
@ -92,8 +100,6 @@ void serialEventRun(void)
|
||||
{
|
||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||
if(Serial0.available()) serialEvent();
|
||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
||||
if(Serial0.available()) serialEvent();
|
||||
#else
|
||||
if(Serial.available()) serialEvent();
|
||||
#endif
|
||||
@ -106,8 +112,167 @@ void serialEventRun(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
#define HSERIAL_MUTEX_LOCK() do {} while (xSemaphoreTake(_lock, portMAX_DELAY) != pdPASS)
|
||||
#define HSERIAL_MUTEX_UNLOCK() xSemaphoreGive(_lock)
|
||||
#else
|
||||
#define HSERIAL_MUTEX_LOCK()
|
||||
#define HSERIAL_MUTEX_UNLOCK()
|
||||
#endif
|
||||
|
||||
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL), _rxBufferSize(256) {}
|
||||
HardwareSerial::HardwareSerial(int uart_nr) :
|
||||
_uart_nr(uart_nr),
|
||||
_uart(NULL),
|
||||
_rxBufferSize(256),
|
||||
_txBufferSize(0),
|
||||
_onReceiveCB(NULL),
|
||||
_onReceiveErrorCB(NULL),
|
||||
_onReceiveTimeout(true),
|
||||
_rxTimeout(10),
|
||||
_eventTask(NULL)
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
,_lock(NULL)
|
||||
#endif
|
||||
{
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(_lock == NULL){
|
||||
_lock = xSemaphoreCreateMutex();
|
||||
if(_lock == NULL){
|
||||
log_e("xSemaphoreCreateMutex failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
HardwareSerial::~HardwareSerial()
|
||||
{
|
||||
end();
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(_lock != NULL){
|
||||
vSemaphoreDelete(_lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void HardwareSerial::_createEventTask(void *args)
|
||||
{
|
||||
// Creating UART event Task
|
||||
xTaskCreate(_uartEventTask, "uart_event_task", 2048, this, configMAX_PRIORITIES - 1, &_eventTask);
|
||||
if (_eventTask == NULL) {
|
||||
log_e(" -- UART%d Event Task not Created!", _uart_nr);
|
||||
}
|
||||
}
|
||||
|
||||
void HardwareSerial::_destroyEventTask(void)
|
||||
{
|
||||
if (_eventTask != NULL) {
|
||||
vTaskDelete(_eventTask);
|
||||
_eventTask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void HardwareSerial::onReceiveError(OnReceiveErrorCb function)
|
||||
{
|
||||
HSERIAL_MUTEX_LOCK();
|
||||
// function may be NULL to cancel onReceive() from its respective task
|
||||
_onReceiveErrorCB = function;
|
||||
// this can be called after Serial.begin(), therefore it shall create the event task
|
||||
if (function != NULL && _uart != NULL && _eventTask == NULL) {
|
||||
_createEventTask(this);
|
||||
}
|
||||
HSERIAL_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout)
|
||||
{
|
||||
HSERIAL_MUTEX_LOCK();
|
||||
// function may be NULL to cancel onReceive() from its respective task
|
||||
_onReceiveCB = function;
|
||||
// When Rx timeout is Zero (disabled), there is only one possible option that is callback when FIFO reaches 120 bytes
|
||||
_onReceiveTimeout = _rxTimeout > 0 ? onlyOnTimeout : false;
|
||||
|
||||
// this can be called after Serial.begin(), therefore it shall create the event task
|
||||
if (function != NULL && _uart != NULL && _eventTask == NULL) {
|
||||
_createEventTask(this); // Create event task
|
||||
}
|
||||
HSERIAL_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
// timout is calculates in time to receive UART symbols at the UART baudrate.
|
||||
// the estimation is about 11 bits per symbol (SERIAL_8N1)
|
||||
void HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
|
||||
{
|
||||
HSERIAL_MUTEX_LOCK();
|
||||
|
||||
// Zero disables timeout, thus, onReceive callback will only be called when RX FIFO reaches 120 bytes
|
||||
// Any non-zero value will activate onReceive callback based on UART baudrate with about 11 bits per symbol
|
||||
_rxTimeout = symbols_timeout;
|
||||
if (!symbols_timeout) _onReceiveTimeout = false; // only when RX timeout is disabled, we also must disable this flag
|
||||
|
||||
if(_uart != NULL) uart_set_rx_timeout(_uart_nr, _rxTimeout); // Set new timeout
|
||||
|
||||
HSERIAL_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void HardwareSerial::eventQueueReset()
|
||||
{
|
||||
QueueHandle_t uartEventQueue = NULL;
|
||||
if (_uart == NULL) {
|
||||
return;
|
||||
}
|
||||
uartGetEventQueue(_uart, &uartEventQueue);
|
||||
if (uartEventQueue != NULL) {
|
||||
xQueueReset(uartEventQueue);
|
||||
}
|
||||
}
|
||||
|
||||
void HardwareSerial::_uartEventTask(void *args)
|
||||
{
|
||||
HardwareSerial *uart = (HardwareSerial *)args;
|
||||
uart_event_t event;
|
||||
QueueHandle_t uartEventQueue = NULL;
|
||||
uartGetEventQueue(uart->_uart, &uartEventQueue);
|
||||
if (uartEventQueue != NULL) {
|
||||
for(;;) {
|
||||
//Waiting for UART event.
|
||||
if(xQueueReceive(uartEventQueue, (void * )&event, (portTickType)portMAX_DELAY)) {
|
||||
switch(event.type) {
|
||||
case UART_DATA:
|
||||
if(uart->_onReceiveCB && uart->available() > 0 &&
|
||||
((uart->_onReceiveTimeout && event.timeout_flag) || !uart->_onReceiveTimeout) )
|
||||
uart->_onReceiveCB();
|
||||
break;
|
||||
case UART_FIFO_OVF:
|
||||
log_w("UART%d FIFO Overflow. Consider adding Hardware Flow Control to your Application.", uart->_uart_nr);
|
||||
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_FIFO_OVF_ERROR);
|
||||
break;
|
||||
case UART_BUFFER_FULL:
|
||||
log_w("UART%d Buffer Full. Consider increasing your buffer size of your Application.", uart->_uart_nr);
|
||||
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_BUFFER_FULL_ERROR);
|
||||
break;
|
||||
case UART_BREAK:
|
||||
log_w("UART%d RX break.", uart->_uart_nr);
|
||||
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_BREAK_ERROR);
|
||||
break;
|
||||
case UART_PARITY_ERR:
|
||||
log_w("UART%d parity error.", uart->_uart_nr);
|
||||
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_PARITY_ERROR);
|
||||
break;
|
||||
case UART_FRAME_ERR:
|
||||
log_w("UART%d frame error.", uart->_uart_nr);
|
||||
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_FRAME_ERROR);
|
||||
break;
|
||||
default:
|
||||
log_w("UART%d unknown event type %d.", uart->_uart_nr, event.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -115,29 +280,54 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
|
||||
log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(_lock == NULL){
|
||||
log_e("MUTEX Lock failed. Can't begin.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
HSERIAL_MUTEX_LOCK();
|
||||
// First Time or after end() --> set default Pins
|
||||
if (!uartIsDriverInstalled(_uart)) {
|
||||
switch (_uart_nr) {
|
||||
case UART_NUM_0:
|
||||
if (rxPin < 0 && txPin < 0) {
|
||||
rxPin = SOC_RX0;
|
||||
txPin = SOC_TX0;
|
||||
}
|
||||
break;
|
||||
#if SOC_UART_NUM > 1 // may save some flash bytes...
|
||||
case UART_NUM_1:
|
||||
if (rxPin < 0 && txPin < 0) {
|
||||
rxPin = RX1;
|
||||
txPin = TX1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if SOC_UART_NUM > 2 // may save some flash bytes...
|
||||
case UART_NUM_2:
|
||||
if (rxPin < 0 && txPin < 0) {
|
||||
rxPin = RX2;
|
||||
txPin = TX2;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
log_e("Bad UART Number");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(_uart) {
|
||||
// in this case it is a begin() over a previous begin() - maybe to change baud rate
|
||||
// thus do not disable debug output
|
||||
end(false);
|
||||
}
|
||||
if(_uart_nr == 0 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = SOC_RX0;
|
||||
txPin = SOC_TX0;
|
||||
}
|
||||
#if SOC_UART_NUM > 1
|
||||
if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = RX1;
|
||||
txPin = TX1;
|
||||
}
|
||||
#endif
|
||||
#if SOC_UART_NUM > 2
|
||||
if(_uart_nr == 2 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = RX2;
|
||||
txPin = TX2;
|
||||
}
|
||||
#endif
|
||||
|
||||
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd);
|
||||
// IDF UART driver keeps Pin setting on restarting. Negative Pin number will keep it unmodified.
|
||||
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, _rxBufferSize, _txBufferSize, invert, rxfifo_full_thrhd);
|
||||
if (!baud) {
|
||||
// using baud rate as zero, forces it to try to detect the current baud rate in place
|
||||
uartStartDetectBaudrate(_uart);
|
||||
@ -151,12 +341,24 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
|
||||
|
||||
if(detectedBaudRate) {
|
||||
delay(100); // Give some time...
|
||||
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd);
|
||||
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, _txBufferSize, invert, rxfifo_full_thrhd);
|
||||
} else {
|
||||
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
|
||||
_uart = NULL;
|
||||
}
|
||||
}
|
||||
// create a task to deal with Serial Events when, for example, calling begin() twice to change the baudrate,
|
||||
// or when setting the callback before calling begin()
|
||||
if (_uart != NULL && (_onReceiveCB != NULL || _onReceiveErrorCB != NULL) && _eventTask == NULL) {
|
||||
_createEventTask(this);
|
||||
}
|
||||
|
||||
// Set UART RX timeout
|
||||
if (_uart != NULL) {
|
||||
uart_set_rx_timeout(_uart_nr, _rxTimeout);
|
||||
}
|
||||
|
||||
HSERIAL_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void HardwareSerial::updateBaudRate(unsigned long baud)
|
||||
@ -164,14 +366,21 @@ void HardwareSerial::updateBaudRate(unsigned long baud)
|
||||
uartSetBaudRate(_uart, baud);
|
||||
}
|
||||
|
||||
void HardwareSerial::end(bool turnOffDebug)
|
||||
void HardwareSerial::end(bool fullyTerminate)
|
||||
{
|
||||
if(turnOffDebug && uartGetDebug() == _uart_nr) {
|
||||
uartSetDebug(0);
|
||||
// default Serial.end() will completely disable HardwareSerial,
|
||||
// including any tasks or debug message channel (log_x()) - but not for IDF log messages!
|
||||
if(fullyTerminate) {
|
||||
_onReceiveCB = NULL;
|
||||
_onReceiveErrorCB = NULL;
|
||||
if (uartGetDebug() == _uart_nr) {
|
||||
uartSetDebug(0);
|
||||
}
|
||||
}
|
||||
delay(10);
|
||||
uartEnd(_uart);
|
||||
_uart = 0;
|
||||
_destroyEventTask();
|
||||
}
|
||||
|
||||
void HardwareSerial::setDebugOutput(bool en)
|
||||
@ -267,9 +476,16 @@ void HardwareSerial::setRxInvert(bool invert)
|
||||
uartSetRxInvert(_uart, invert);
|
||||
}
|
||||
|
||||
void HardwareSerial::setPins(uint8_t rxPin, uint8_t txPin)
|
||||
// negative Pin value will keep it unmodified
|
||||
void HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
|
||||
{
|
||||
uartSetPins(_uart, rxPin, txPin);
|
||||
uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin);
|
||||
}
|
||||
|
||||
// Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
|
||||
void HardwareSerial::setHwFlowCtrlMode(uint8_t mode, uint8_t threshold)
|
||||
{
|
||||
uartSetHwFlowCtrlMode(_uart, mode, threshold);
|
||||
}
|
||||
|
||||
size_t HardwareSerial::setRxBufferSize(size_t new_size) {
|
||||
@ -280,10 +496,26 @@ size_t HardwareSerial::setRxBufferSize(size_t new_size) {
|
||||
}
|
||||
|
||||
if (new_size <= SOC_UART_FIFO_LEN) {
|
||||
log_e("RX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN);
|
||||
log_e("RX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN); // ESP32, S2, S3 and C3 means higher than 128
|
||||
return 0;
|
||||
}
|
||||
|
||||
_rxBufferSize = new_size;
|
||||
return _rxBufferSize;
|
||||
}
|
||||
|
||||
size_t HardwareSerial::setTxBufferSize(size_t new_size) {
|
||||
|
||||
if (_uart) {
|
||||
log_e("TX Buffer can't be resized when Serial is already running.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (new_size <= SOC_UART_FIFO_LEN) {
|
||||
log_e("TX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN); // ESP32, S2, S3 and C3 means higher than 128
|
||||
return 0;
|
||||
}
|
||||
|
||||
_txBufferSize = new_size;
|
||||
return _txBufferSize;
|
||||
}
|
||||
|
@ -46,19 +46,61 @@
|
||||
#define HardwareSerial_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <functional>
|
||||
#include "Stream.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "HWCDC.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
typedef enum {
|
||||
UART_BREAK_ERROR,
|
||||
UART_BUFFER_FULL_ERROR,
|
||||
UART_FIFO_OVF_ERROR,
|
||||
UART_FRAME_ERROR,
|
||||
UART_PARITY_ERROR
|
||||
} hardwareSerial_error_t;
|
||||
|
||||
typedef std::function<void(void)> OnReceiveCb;
|
||||
typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb;
|
||||
|
||||
class HardwareSerial: public Stream
|
||||
{
|
||||
public:
|
||||
HardwareSerial(int uart_nr);
|
||||
~HardwareSerial();
|
||||
|
||||
// setRxTimeout sets the timeout after which onReceive callback will be called (after receiving data, it waits for this time of UART rx inactivity to call the callback fnc)
|
||||
// param symbols_timeout defines a timeout threshold in uart symbol periods. Setting 0 symbol timeout disables the callback call by timeout.
|
||||
// Maximum timeout setting is calculacted automatically by IDF. If set above the maximum, it is ignored and an error is printed on Serial0 (check console).
|
||||
// Examples: Maximum for 11 bits symbol is 92 (SERIAL_8N2, SERIAL_8E1, SERIAL_8O1, etc), Maximum for 10 bits symbol is 101 (SERIAL_8N1).
|
||||
// For example symbols_timeout=1 defines a timeout equal to transmission time of one symbol (~11 bit) on current baudrate.
|
||||
// For a baudrate of 9600, SERIAL_8N1 (10 bit symbol) and symbols_timeout = 3, the timeout would be 3 / (9600 / 10) = 3.125 ms
|
||||
void setRxTimeout(uint8_t symbols_timeout);
|
||||
|
||||
// onReceive will setup a callback that will be called whenever an UART interruption occurs (UART_INTR_RXFIFO_FULL or UART_INTR_RXFIFO_TOUT)
|
||||
// UART_INTR_RXFIFO_FULL interrupt triggers at UART_FULL_THRESH_DEFAULT bytes received (defined as 120 bytes by default in IDF)
|
||||
// UART_INTR_RXFIFO_TOUT interrupt triggers at UART_TOUT_THRESH_DEFAULT symbols passed without any reception (defined as 10 symbos by default in IDF)
|
||||
// onlyOnTimeout parameter will define how onReceive will behave:
|
||||
// Default: true -- The callback will only be called when RX Timeout happens.
|
||||
// Whole stream of bytes will be ready for being read on the callback function at once.
|
||||
// This option may lead to Rx Overflow depending on the Rx Buffer Size and number of bytes received in the streaming
|
||||
// false -- The callback will be called when FIFO reaches 120 bytes and also on RX Timeout.
|
||||
// The stream of incommig bytes will be "split" into blocks of 120 bytes on each callback.
|
||||
// This option avoid any sort of Rx Overflow, but leaves the UART packet reassembling work to the Application.
|
||||
void onReceive(OnReceiveCb function, bool onlyOnTimeout = true);
|
||||
|
||||
// onReceive will be called on error events (see hardwareSerial_error_t)
|
||||
void onReceiveError(OnReceiveErrorCb function);
|
||||
|
||||
// eventQueueReset clears all events in the queue (the events that trigger onReceive and onReceiveError) - maybe usefull in some use cases
|
||||
void eventQueueReset();
|
||||
|
||||
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);
|
||||
void end(bool turnOffDebug = true);
|
||||
void end(bool fullyTerminate = true);
|
||||
void updateBaudRate(unsigned long baud);
|
||||
int available(void);
|
||||
int availableForWrite(void);
|
||||
@ -103,13 +145,34 @@ public:
|
||||
void setDebugOutput(bool);
|
||||
|
||||
void setRxInvert(bool);
|
||||
void setPins(uint8_t rxPin, uint8_t txPin);
|
||||
|
||||
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
|
||||
// SetPins shall be called after Serial begin()
|
||||
void setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin = -1, int8_t rtsPin = -1);
|
||||
// Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
|
||||
void setHwFlowCtrlMode(uint8_t mode = HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64); // 64 is half FIFO Length
|
||||
|
||||
size_t setRxBufferSize(size_t new_size);
|
||||
size_t setTxBufferSize(size_t new_size);
|
||||
|
||||
protected:
|
||||
int _uart_nr;
|
||||
uart_t* _uart;
|
||||
size_t _rxBufferSize;
|
||||
size_t _txBufferSize;
|
||||
OnReceiveCb _onReceiveCB;
|
||||
OnReceiveErrorCb _onReceiveErrorCB;
|
||||
// _onReceive and _rxTimeout have be consistent when timeout is disabled
|
||||
bool _onReceiveTimeout;
|
||||
uint8_t _rxTimeout;
|
||||
TaskHandle_t _eventTask;
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
SemaphoreHandle_t _lock;
|
||||
#endif
|
||||
|
||||
void _createEventTask(void *args);
|
||||
void _destroyEventTask(void);
|
||||
static void _uartEventTask(void *args);
|
||||
};
|
||||
|
||||
extern void serialEventRun(void) __attribute__((weak));
|
||||
@ -119,10 +182,10 @@ extern void serialEventRun(void) __attribute__((weak));
|
||||
#define ARDUINO_USB_CDC_ON_BOOT 0
|
||||
#endif
|
||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||
#if !ARDUINO_USB_MODE
|
||||
#include "USB.h"
|
||||
#include "USBCDC.h"
|
||||
extern HardwareSerial Serial0;
|
||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
||||
#endif
|
||||
extern HardwareSerial Serial0;
|
||||
#else
|
||||
extern HardwareSerial Serial;
|
||||
|
@ -120,3 +120,6 @@ bool IPAddress::fromString(const char *address)
|
||||
_address.bytes[3] = acc;
|
||||
return true;
|
||||
}
|
||||
|
||||
// declared one time - as external in IPAddress.h
|
||||
IPAddress INADDR_NONE(0, 0, 0, 0);
|
||||
|
@ -91,6 +91,6 @@ public:
|
||||
friend class DNSClient;
|
||||
};
|
||||
|
||||
const IPAddress INADDR_NONE(0, 0, 0, 0);
|
||||
|
||||
// changed to extern because const declaration creates copies in BSS of INADDR_NONE for each CPP unit that includes it
|
||||
extern IPAddress INADDR_NONE;
|
||||
#endif
|
||||
|
@ -108,6 +108,9 @@ public:
|
||||
size_t println(const Printable&);
|
||||
size_t println(struct tm * timeinfo, const char * format = NULL);
|
||||
size_t println(void);
|
||||
|
||||
virtual void flush() { /* Empty implementation for backward compatibility */ }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -48,7 +48,6 @@ public:
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
Stream():_startMillis(0)
|
||||
{
|
||||
|
131
cores/esp32/Tone.cpp
Normal file
131
cores/esp32/Tone.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include <Arduino.h>
|
||||
#include "esp32-hal-ledc.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
static TaskHandle_t _tone_task = NULL;
|
||||
static QueueHandle_t _tone_queue = NULL;
|
||||
static uint8_t _channel = 0;
|
||||
|
||||
typedef enum{
|
||||
TONE_START,
|
||||
TONE_END,
|
||||
TONE_SET_CHANNEL
|
||||
} tone_cmd_t;
|
||||
|
||||
typedef struct{
|
||||
tone_cmd_t tone_cmd;
|
||||
uint8_t pin;
|
||||
unsigned int frequency;
|
||||
unsigned long duration;
|
||||
uint8_t channel;
|
||||
} tone_msg_t;
|
||||
|
||||
static void tone_task(void*){
|
||||
tone_msg_t tone_msg;
|
||||
while(1){
|
||||
xQueueReceive(_tone_queue, &tone_msg, portMAX_DELAY);
|
||||
switch(tone_msg.tone_cmd){
|
||||
case TONE_START:
|
||||
log_d("Task received from queue TONE_START: _pin=%d, frequency=%u Hz, duration=%u ms", tone_msg.pin, tone_msg.frequency, tone_msg.duration);
|
||||
|
||||
log_d("Setup LED controll on channel %d", _channel);
|
||||
// ledcSetup(_channel, tone_msg.frequency, 11);
|
||||
// ledcAttachPin(tone_msg.pin, _channel);
|
||||
// ledcWrite(_channel, 1024);
|
||||
ledcWriteTone(_channel, tone_msg.frequency);
|
||||
ledcAttachPin(tone_msg.pin, _channel);
|
||||
|
||||
if(tone_msg.duration){
|
||||
delay(tone_msg.duration);
|
||||
ledcDetachPin(tone_msg.pin);
|
||||
ledcWriteTone(_channel, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case TONE_END:
|
||||
log_d("Task received from queue TONE_END: pin=%d", tone_msg.pin);
|
||||
ledcDetachPin(tone_msg.pin);
|
||||
ledcWriteTone(_channel, 0);
|
||||
break;
|
||||
|
||||
case TONE_SET_CHANNEL:
|
||||
log_d("Task received from queue TONE_SET_CHANNEL: channel=%d", tone_msg.channel);
|
||||
_channel = tone_msg.channel;
|
||||
break;
|
||||
|
||||
default: ; // do nothing
|
||||
} // switch
|
||||
} // infinite loop
|
||||
}
|
||||
|
||||
static int tone_init(){
|
||||
if(_tone_queue == NULL){
|
||||
log_v("Creating tone queue");
|
||||
_tone_queue = xQueueCreate(128, sizeof(tone_msg_t));
|
||||
if(_tone_queue == NULL){
|
||||
log_e("Could not create tone queue");
|
||||
return 0; // ERR
|
||||
}
|
||||
log_v("Tone queue created");
|
||||
}
|
||||
|
||||
if(_tone_task == NULL){
|
||||
log_v("Creating tone task");
|
||||
xTaskCreate(
|
||||
tone_task, // Function to implement the task
|
||||
"toneTask", // Name of the task
|
||||
3500, // Stack size in words
|
||||
NULL, // Task input parameter
|
||||
1, // Priority of the task
|
||||
&_tone_task // Task handle.
|
||||
);
|
||||
if(_tone_task == NULL){
|
||||
log_e("Could not create tone task");
|
||||
return 0; // ERR
|
||||
}
|
||||
log_v("Tone task created");
|
||||
}
|
||||
return 1; // OK
|
||||
}
|
||||
|
||||
void setToneChannel(uint8_t channel){
|
||||
log_d("channel=%d", channel);
|
||||
if(tone_init()){
|
||||
tone_msg_t tone_msg = {
|
||||
.tone_cmd = TONE_SET_CHANNEL,
|
||||
.channel = channel
|
||||
};
|
||||
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
void noTone(uint8_t _pin){
|
||||
log_d("noTone was called");
|
||||
if(tone_init()){
|
||||
tone_msg_t tone_msg = {
|
||||
.tone_cmd = TONE_END,
|
||||
.pin = _pin
|
||||
};
|
||||
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
// parameters:
|
||||
// _pin - pin number which will output the signal
|
||||
// frequency - PWM frequency in Hz
|
||||
// duration - time in ms - how long will the signal be outputted.
|
||||
// If not provided, or 0 you must manually call noTone to end output
|
||||
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration){
|
||||
log_d("_pin=%d, frequency=%u Hz, duration=%u ms", _pin, frequency, duration);
|
||||
if(tone_init()){
|
||||
tone_msg_t tone_msg = {
|
||||
.tone_cmd = TONE_START,
|
||||
.pin = _pin,
|
||||
.frequency = frequency,
|
||||
.duration = duration
|
||||
};
|
||||
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
#include "esp32-hal.h"
|
||||
#include "esp32-hal-tinyusb.h"
|
||||
#include "common/tusb_common.h"
|
||||
#include "StreamString.h"
|
||||
|
||||
#ifndef USB_VID
|
||||
#define USB_VID USB_ESPRESSIF_VID
|
||||
@ -33,8 +34,12 @@
|
||||
#define USB_PRODUCT ARDUINO_BOARD
|
||||
#endif
|
||||
#ifndef USB_SERIAL
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
#define USB_SERIAL "__MAC__"
|
||||
#else
|
||||
#define USB_SERIAL "0"
|
||||
#endif
|
||||
#endif
|
||||
#ifndef USB_WEBUSB_ENABLED
|
||||
#define USB_WEBUSB_ENABLED false
|
||||
#endif
|
||||
@ -155,6 +160,15 @@ ESPUSB::~ESPUSB(){
|
||||
|
||||
bool ESPUSB::begin(){
|
||||
if(!_started){
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
if(serial_number == "__MAC__"){
|
||||
StreamString s;
|
||||
uint8_t m[6];
|
||||
esp_efuse_mac_get_default(m);
|
||||
s.printf("%02X:%02X:%02X:%02X:%02X:%02X", m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
serial_number = s;
|
||||
}
|
||||
#endif
|
||||
tinyusb_device_config_t tinyusb_device_config = {
|
||||
.vid = vid,
|
||||
.pid = pid,
|
||||
|
@ -114,16 +114,42 @@ void USBCDC::onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback
|
||||
}
|
||||
|
||||
size_t USBCDC::setRxBufferSize(size_t rx_queue_len){
|
||||
if(rx_queue){
|
||||
if(!rx_queue_len){
|
||||
vQueueDelete(rx_queue);
|
||||
rx_queue = NULL;
|
||||
size_t currentQueueSize = rx_queue ?
|
||||
uxQueueSpacesAvailable(rx_queue) + uxQueueMessagesWaiting(rx_queue) : 0;
|
||||
|
||||
if (rx_queue_len != currentQueueSize) {
|
||||
xQueueHandle new_rx_queue = NULL;
|
||||
if (rx_queue_len) {
|
||||
new_rx_queue = xQueueCreate(rx_queue_len, sizeof(uint8_t));
|
||||
if(!new_rx_queue){
|
||||
log_e("CDC Queue creation failed.");
|
||||
return 0;
|
||||
}
|
||||
if (rx_queue) {
|
||||
size_t copySize = uxQueueMessagesWaiting(rx_queue);
|
||||
if (copySize > 0) {
|
||||
for(size_t i = 0; i < copySize; i++) {
|
||||
uint8_t ch = 0;
|
||||
xQueueReceive(rx_queue, &ch, 0);
|
||||
if (!xQueueSend(new_rx_queue, &ch, 0)) {
|
||||
arduino_usb_cdc_event_data_t p;
|
||||
p.rx_overflow.dropped_bytes = copySize - i;
|
||||
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_OVERFLOW_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
|
||||
log_e("CDC RX Overflow.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
vQueueDelete(rx_queue);
|
||||
}
|
||||
rx_queue = new_rx_queue;
|
||||
return rx_queue_len;
|
||||
} else {
|
||||
if (rx_queue) {
|
||||
vQueueDelete(rx_queue);
|
||||
rx_queue = NULL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
rx_queue = xQueueCreate(rx_queue_len, sizeof(uint8_t));
|
||||
if(!rx_queue){
|
||||
return 0;
|
||||
}
|
||||
return rx_queue_len;
|
||||
}
|
||||
@ -133,7 +159,8 @@ void USBCDC::begin(unsigned long baud)
|
||||
if(tx_lock == NULL) {
|
||||
tx_lock = xSemaphoreCreateMutex();
|
||||
}
|
||||
setRxBufferSize(256);//default if not preset
|
||||
// if rx_queue was set before begin(), keep it
|
||||
if (!rx_queue) setRxBufferSize(256); //default if not preset
|
||||
devices[itf] = this;
|
||||
}
|
||||
|
||||
@ -144,6 +171,7 @@ void USBCDC::end()
|
||||
setRxBufferSize(0);
|
||||
if(tx_lock != NULL) {
|
||||
vSemaphoreDelete(tx_lock);
|
||||
tx_lock = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,16 +272,22 @@ void USBCDC::_onLineCoding(uint32_t _bit_rate, uint8_t _stop_bits, uint8_t _pari
|
||||
}
|
||||
|
||||
void USBCDC::_onRX(){
|
||||
arduino_usb_cdc_event_data_t p;
|
||||
uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE+1];
|
||||
uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE);
|
||||
for(uint32_t i=0; i<count; i++){
|
||||
if(rx_queue == NULL || !xQueueSend(rx_queue, buf+i, 0)){
|
||||
return;
|
||||
if(rx_queue == NULL || !xQueueSend(rx_queue, buf+i, 10)) {
|
||||
p.rx_overflow.dropped_bytes = count - i;
|
||||
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_OVERFLOW_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
|
||||
log_e("CDC RX Overflow.");
|
||||
count = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
arduino_usb_cdc_event_data_t p;
|
||||
p.rx.len = count;
|
||||
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
|
||||
if (count) {
|
||||
p.rx.len = count;
|
||||
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
void USBCDC::_onTX(){
|
||||
@ -412,7 +446,7 @@ USBCDC::operator bool() const
|
||||
return connected;
|
||||
}
|
||||
|
||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||
#if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE //Serial used for USB CDC
|
||||
USBCDC Serial(0);
|
||||
#endif
|
||||
|
||||
|
@ -33,6 +33,7 @@ typedef enum {
|
||||
ARDUINO_USB_CDC_LINE_CODING_EVENT,
|
||||
ARDUINO_USB_CDC_RX_EVENT,
|
||||
ARDUINO_USB_CDC_TX_EVENT,
|
||||
ARDUINO_USB_CDC_RX_OVERFLOW_EVENT,
|
||||
ARDUINO_USB_CDC_MAX_EVENT,
|
||||
} arduino_usb_cdc_event_t;
|
||||
|
||||
@ -50,6 +51,9 @@ typedef union {
|
||||
struct {
|
||||
size_t len;
|
||||
} rx;
|
||||
struct {
|
||||
size_t dropped_bytes;
|
||||
} rx_overflow;
|
||||
} arduino_usb_cdc_event_data_t;
|
||||
|
||||
class USBCDC: public Stream
|
||||
@ -134,7 +138,7 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||
#if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE //Serial used for USB CDC
|
||||
extern USBCDC Serial;
|
||||
#endif
|
||||
|
||||
|
@ -67,14 +67,14 @@ long random(long howsmall, long howbig)
|
||||
}
|
||||
|
||||
long map(long x, long in_min, long in_max, long out_min, long out_max) {
|
||||
const long dividend = out_max - out_min;
|
||||
const long divisor = in_max - in_min;
|
||||
const long delta = x - in_min;
|
||||
if(divisor == 0){
|
||||
log_e("Invalid map input range, min == max");
|
||||
return -1; //AVR returns -1, SAM returns 0
|
||||
const long run = in_max - in_min;
|
||||
if(run == 0){
|
||||
log_e("map(): Invalid input range, min == max");
|
||||
return -1; // AVR returns -1, SAM returns 0
|
||||
}
|
||||
return (delta * dividend + (divisor / 2)) / divisor + out_min;
|
||||
const long rise = out_max - out_min;
|
||||
const long delta = x - in_min;
|
||||
return (delta * rise) / run + out_min;
|
||||
}
|
||||
|
||||
uint16_t makeWord(uint16_t w)
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <Arduino.h>
|
||||
#include "WString.h"
|
||||
#include "stdlib_noniso.h"
|
||||
#include "esp32-hal-log.h"
|
||||
|
||||
/*********************************************/
|
||||
/* Constructors */
|
||||
@ -112,16 +113,28 @@ String::String(unsigned long value, unsigned char base) {
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(float value, unsigned char decimalPlaces) {
|
||||
String::String(float value, unsigned int decimalPlaces) {
|
||||
init();
|
||||
char buf[33];
|
||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||
char *buf = (char*)malloc(decimalPlaces + 42);
|
||||
if (buf) {
|
||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||
free(buf);
|
||||
} else {
|
||||
*this = "nan";
|
||||
log_e("No enought memory for the operation.");
|
||||
}
|
||||
}
|
||||
|
||||
String::String(double value, unsigned char decimalPlaces) {
|
||||
String::String(double value, unsigned int decimalPlaces) {
|
||||
init();
|
||||
char buf[33];
|
||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||
char *buf = (char*)malloc(decimalPlaces + 312);
|
||||
if (buf) {
|
||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||
free(buf);
|
||||
} else {
|
||||
*this = "nan";
|
||||
log_e("No enought memory for the operation.");
|
||||
}
|
||||
}
|
||||
|
||||
String::~String() {
|
||||
@ -761,8 +774,10 @@ void String::replace(const String& find, const String& replace) {
|
||||
}
|
||||
if(size == len())
|
||||
return;
|
||||
if(size > capacity() && !changeBuffer(size))
|
||||
return; // XXX: tell user!
|
||||
if(size > capacity() && !changeBuffer(size)) {
|
||||
log_w("String.Replace() Insufficient space to replace string");
|
||||
return;
|
||||
}
|
||||
int index = len() - 1;
|
||||
while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
||||
readFrom = wbuffer() + index + find.len();
|
||||
|
@ -71,8 +71,8 @@ class String {
|
||||
explicit String(unsigned int, unsigned char base = 10);
|
||||
explicit String(long, unsigned char base = 10);
|
||||
explicit String(unsigned long, unsigned char base = 10);
|
||||
explicit String(float, unsigned char decimalPlaces = 2);
|
||||
explicit String(double, unsigned char decimalPlaces = 2);
|
||||
explicit String(float, unsigned int decimalPlaces = 2);
|
||||
explicit String(double, unsigned int decimalPlaces = 2);
|
||||
~String(void);
|
||||
|
||||
// memory management
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/dac_channel.h"
|
||||
#define DEFAULT_VREF 1100
|
||||
static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL};
|
||||
static uint16_t __analogVRef = 0;
|
||||
@ -35,6 +36,11 @@ static uint8_t __analogVRefPin = 0;
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/dac_channel.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/ets_sys.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#else
|
||||
@ -141,10 +147,10 @@ bool __adcAttachPin(uint8_t pin){
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||
else if(pin == 25){
|
||||
#if SOC_DAC_SUPPORTED
|
||||
else if(pin == DAC_CHANNEL_1_GPIO_NUM){
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);//stop dac1
|
||||
} else if(pin == 26){
|
||||
} else if(pin == DAC_CHANNEL_2_GPIO_NUM){
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);//stop dac2
|
||||
}
|
||||
#endif
|
||||
|
@ -33,6 +33,9 @@
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "freertos/xtensa_timer.h"
|
||||
#include "esp32s2/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "freertos/xtensa_timer.h"
|
||||
#include "esp32s3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#else
|
||||
@ -144,7 +147,7 @@ bool removeApbChangeCallback(void * arg, apb_change_cb_t cb){
|
||||
}
|
||||
|
||||
static uint32_t calculateApb(rtc_cpu_freq_config_t * conf){
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
return APB_CLK_FREQ;
|
||||
#else
|
||||
if(conf->freq_mhz >= 80){
|
||||
@ -228,6 +231,8 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
|
||||
//Update FreeRTOS Tick Divisor
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
|
||||
#else
|
||||
uint32_t fcpu = (conf.freq_mhz >= 80)?(conf.freq_mhz * MHZ):(apb);
|
||||
_xt_tick_divisor = fcpu / XT_TICK_PER_SEC;
|
||||
|
@ -13,167 +13,70 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "pins_arduino.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_attr.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_system.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp32/rom/gpio.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#define GPIO_FUNC 2
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp32s2/rom/gpio.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#define GPIO_FUNC 1
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "esp32c3/rom/gpio.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#define USE_ESP_IDF_GPIO 1
|
||||
// It fixes lack of pin definition for S3 and for any future SoC
|
||||
// this function works for ESP32, ESP32-S2 and ESP32-S3 - including the C3, it will return -1 for any pin
|
||||
#if SOC_TOUCH_SENSOR_NUM > 0
|
||||
#include "soc/touch_sensor_periph.h"
|
||||
|
||||
int8_t digitalPinToTouchChannel(uint8_t pin)
|
||||
{
|
||||
int8_t ret = -1;
|
||||
if (pin < SOC_GPIO_PIN_COUNT) {
|
||||
for (uint8_t i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||
if (touch_sensor_channel_io_map[i] == pin) {
|
||||
ret = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define USE_ESP_IDF_GPIO 1
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "esp_intr.h"
|
||||
// No Touch Sensor available
|
||||
int8_t digitalPinToTouchChannel(uint8_t pin)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26};
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
|
||||
#endif
|
||||
#ifdef SOC_ADC_SUPPORTED
|
||||
#include "soc/adc_periph.h"
|
||||
|
||||
const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT]={
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
{0x44, 11, 11, 1},
|
||||
{0x88, -1, -1, -1},
|
||||
{0x40, 12, 12, 2},
|
||||
{0x84, -1, -1, -1},
|
||||
{0x48, 10, 10, 0},
|
||||
{0x6c, -1, -1, -1},
|
||||
{0x60, -1, -1, -1},
|
||||
{0x64, -1, -1, -1},
|
||||
{0x68, -1, -1, -1},
|
||||
{0x54, -1, -1, -1},
|
||||
{0x58, -1, -1, -1},
|
||||
{0x5c, -1, -1, -1},
|
||||
{0x34, 15, 15, 5},
|
||||
{0x38, 14, 14, 4},
|
||||
{0x30, 16, 16, 6},
|
||||
{0x3c, 13, 13, 3},
|
||||
{0x4c, -1, -1, -1},
|
||||
{0x50, -1, -1, -1},
|
||||
{0x70, -1, -1, -1},
|
||||
{0x74, -1, -1, -1},
|
||||
{0x78, -1, -1, -1},
|
||||
{0x7c, -1, -1, -1},
|
||||
{0x80, -1, -1, -1},
|
||||
{0x8c, -1, -1, -1},
|
||||
{0, -1, -1, -1},
|
||||
{0x24, 6, 18, -1}, //DAC1
|
||||
{0x28, 7, 19, -1}, //DAC2
|
||||
{0x2c, 17, 17, 7},
|
||||
{0, -1, -1, -1},
|
||||
{0, -1, -1, -1},
|
||||
{0, -1, -1, -1},
|
||||
{0, -1, -1, -1},
|
||||
{0x1c, 9, 4, 8},
|
||||
{0x20, 8, 5, 9},
|
||||
{0x14, 4, 6, -1},
|
||||
{0x18, 5, 7, -1},
|
||||
{0x04, 0, 0, -1},
|
||||
{0x08, 1, 1, -1},
|
||||
{0x0c, 2, 2, -1},
|
||||
{0x10, 3, 3, -1}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
{0x04, 0, -1, -1},
|
||||
{0x08, 1, 0, 1},
|
||||
{0x0c, 2, 1, 2},
|
||||
{0x10, 3, 2, 3},
|
||||
{0x14, 4, 3, 4},
|
||||
{0x18, 5, 4, 5},
|
||||
{0x1c, 6, 5, 6},
|
||||
{0x20, 7, 6, 7},
|
||||
{0x24, 8, 7, 8},
|
||||
{0x28, 9, 8, 9},//FSPI_HD
|
||||
{0x2c, 10, 9, 10},//FSPI_CS0 / FSPI_D4
|
||||
{0x30, 11, 10, 11},//FSPI_D / FSPI_D5
|
||||
{0x34, 12, 11, 12},//FSPI_CLK / FSPI_D6
|
||||
{0x38, 13, 12, 13},//FSPI_Q / FSPI_D7
|
||||
{0x3c, 14, 13, 14},//FSPI_WP / FSPI_DQS
|
||||
{0x40, 15, 14, -1},//32K+ / RTS0
|
||||
{0x44, 16, 15, -1},//32K- / CTS0
|
||||
{0x48, 17, 16, -1},//DAC1 / TXD1
|
||||
{0x4c, 18, 17, -1},//DAC2 / RXD1
|
||||
{0x50, 19, 18, -1},//USB D- / RTS1
|
||||
{0x54, 20, 19, -1},//USB D+ / CTS1
|
||||
{0x58, 21, -1, -1},//SDA?
|
||||
{ 0, -1, -1, -1},//UNAVAILABLE
|
||||
{ 0, -1, -1, -1},//UNAVAILABLE
|
||||
{ 0, -1, -1, -1},//UNAVAILABLE
|
||||
{ 0, -1, -1, -1},//UNAVAILABLE
|
||||
{0x6c, -1, -1, -1},//RESERVED SPI_CS1
|
||||
{0x70, -1, -1, -1},//RESERVED SPI_HD
|
||||
{0x74, -1, -1, -1},//RESERVED SPI_WP
|
||||
{0x78, -1, -1, -1},//RESERVED SPI_CS0
|
||||
{0x7c, -1, -1, -1},//RESERVED SPI_CLK
|
||||
{0x80, -1, -1, -1},//RESERVED SPI_Q
|
||||
{0x84, -1, -1, -1},//RESERVED SPI_D
|
||||
{0x88, -1, -1, -1},//FSPI_HD
|
||||
{0x8c, -1, -1, -1},//FSPI_CS0
|
||||
{0x90, -1, -1, -1},//FSPI_D
|
||||
{0x94, -1, -1, -1},//FSPI_CLK
|
||||
{0x98, -1, -1, -1},//FSPI_Q
|
||||
{0x9c, -1, -1, -1},//FSPI_WP
|
||||
{0xa0, -1, -1, -1},//MTCK
|
||||
{0xa4, -1, -1, -1},//MTDO
|
||||
{0xa8, -1, -1, -1},//MTDI
|
||||
{0xac, -1, -1, -1},//MTMS
|
||||
{0xb0, -1, -1, -1},//TXD0
|
||||
{0xb4, -1, -1, -1},//RXD0
|
||||
{0xb8, -1, -1, -1},//SCL?
|
||||
{0xbc, -1, -1, -1},//INPUT ONLY
|
||||
{0, -1, -1, -1}
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
{0x04, -1, 0, -1}, // ADC1_CH0
|
||||
{0x08, -1, 1, -1}, // ADC1_CH1
|
||||
{0x0c, -1, 2, -1}, // ADC1_CH2 | FSPIQ
|
||||
{0x10, -1, 3, -1}, // ADC1_CH3
|
||||
{0x14, -1, 4, -1}, // MTMS | ADC1_CH4 | FSPIHD
|
||||
{0x18, -1, 5, -1}, // MTDI | ADC2_CH0 | FSPIWP
|
||||
{0x1c, -1, -1, -1}, // MTCK | FSPICLK
|
||||
{0x20, -1, -1, -1}, // MTDO | FSPID
|
||||
{0x24, -1, -1, -1}, //
|
||||
{0x28, -1, -1, -1}, //
|
||||
{0x2c, -1, -1, -1}, // FSPICSO
|
||||
{0x30, -1, -1, -1}, //
|
||||
{0x34, -1, -1, -1}, // SPIHD
|
||||
{0x38, -1, -1, -1}, // SPIWP
|
||||
{0x3c, -1, -1, -1}, // SPICSO
|
||||
{0x40, -1, -1, -1}, // SPICLK
|
||||
{0x44, -1, -1, -1}, // SPID
|
||||
{0x48, -1, -1, -1}, // SPIQ
|
||||
{0x4c, -1, -1, -1}, // USB-
|
||||
{0x50, -1, -1, -1}, // USB+
|
||||
{0x54, -1, -1, -1}, // U0RXD
|
||||
{0x58, -1, -1, -1}, // U0TXD
|
||||
int8_t digitalPinToAnalogChannel(uint8_t pin)
|
||||
{
|
||||
uint8_t channel = 0;
|
||||
if (pin < SOC_GPIO_PIN_COUNT) {
|
||||
for (uint8_t i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
|
||||
for (uint8_t j = 0; j < SOC_ADC_MAX_CHANNEL_NUM; j++) {
|
||||
if (adc_channel_io_map[i][j] == pin) {
|
||||
return channel;
|
||||
}
|
||||
channel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t analogChannelToDigitalPin(uint8_t channel)
|
||||
{
|
||||
if (channel >= (SOC_ADC_PERIPH_NUM * SOC_ADC_MAX_CHANNEL_NUM)) {
|
||||
return -1;
|
||||
}
|
||||
uint8_t adc_unit = (channel / SOC_ADC_MAX_CHANNEL_NUM);
|
||||
uint8_t adc_chan = (channel % SOC_ADC_MAX_CHANNEL_NUM);
|
||||
return adc_channel_io_map[adc_unit][adc_chan];
|
||||
}
|
||||
#else
|
||||
// No Analog channels availible
|
||||
int8_t analogChannelToDigitalPin(uint8_t channel)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
typedef void (*voidFuncPtrArg)(void*);
|
||||
@ -188,8 +91,8 @@ static InterruptHandle_t __pinInterruptHandlers[SOC_GPIO_PIN_COUNT] = {0,};
|
||||
|
||||
extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
|
||||
{
|
||||
#if USE_ESP_IDF_GPIO
|
||||
if (!GPIO_IS_VALID_GPIO(pin)) {
|
||||
log_e("Invalid pin selected");
|
||||
return;
|
||||
}
|
||||
gpio_config_t conf = {
|
||||
@ -211,157 +114,23 @@ extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
|
||||
conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
||||
}
|
||||
}
|
||||
gpio_config(&conf);
|
||||
|
||||
if(mode == SPECIAL){
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pin], (uint32_t)(((pin)==RX||(pin)==TX)?0:1));
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pin], (uint32_t)(((pin)==RX||(pin)==TX)?0:2));
|
||||
#endif
|
||||
} else if(mode == ANALOG){
|
||||
#if !CONFIG_IDF_TARGET_ESP32C3
|
||||
//adc_gpio_init(ADC_UNIT_1, ADC_CHANNEL_0);
|
||||
#endif
|
||||
} else if(mode >= 0x20 && mode < ANALOG) {//function
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pin], mode >> 5);
|
||||
}
|
||||
#else
|
||||
if(!digitalPinIsValid(pin)) {
|
||||
if(gpio_config(&conf) != ESP_OK)
|
||||
{
|
||||
log_e("GPIO config failed");
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t rtc_io = esp32_gpioMux[pin].rtc;
|
||||
uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
|
||||
if(mode == ANALOG) {
|
||||
if(!rtc_reg) {
|
||||
return;//not rtc pin
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
|
||||
#endif
|
||||
SET_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, (rtc_io_desc[rtc_io].mux));
|
||||
SET_PERI_REG_BITS(rtc_io_desc[rtc_io].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0, rtc_io_desc[rtc_io].func);
|
||||
|
||||
RTCIO.pin[rtc_io].pad_driver = 0;//OD = 1
|
||||
RTCIO.enable_w1tc.w1tc = (1U << rtc_io);
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].ie);
|
||||
|
||||
if (rtc_io_desc[rtc_io].pullup) {
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pullup);
|
||||
}
|
||||
if (rtc_io_desc[rtc_io].pulldown) {
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pulldown);
|
||||
}
|
||||
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = ((uint32_t)GPIO_FUNC << MCU_SEL_S) | ((uint32_t)2 << FUN_DRV_S) | FUN_IE;
|
||||
return;
|
||||
}
|
||||
|
||||
//RTC pins PULL settings
|
||||
if(rtc_reg) {
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
|
||||
if(mode & PULLUP) {
|
||||
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[rtc_io].pullup) & ~(rtc_io_desc[rtc_io].pulldown);
|
||||
} else if(mode & PULLDOWN) {
|
||||
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[rtc_io].pulldown) & ~(rtc_io_desc[rtc_io].pullup);
|
||||
} else {
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pinFunction = 0, pinControl = 0;
|
||||
|
||||
if(mode & INPUT) {
|
||||
if(pin < 32) {
|
||||
GPIO.enable_w1tc = ((uint32_t)1 << pin);
|
||||
} else {
|
||||
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
}
|
||||
} else if(mode & OUTPUT) {
|
||||
if(pin >= NUM_OUPUT_PINS){
|
||||
return;
|
||||
} else if(pin < 32) {
|
||||
GPIO.enable_w1ts = ((uint32_t)1 << pin);
|
||||
} else {
|
||||
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
}
|
||||
}
|
||||
|
||||
if(mode & PULLUP) {
|
||||
pinFunction |= FUN_PU;
|
||||
} else if(mode & PULLDOWN) {
|
||||
pinFunction |= FUN_PD;
|
||||
}
|
||||
|
||||
pinFunction |= ((uint32_t)2 << FUN_DRV_S);//what are the drivers?
|
||||
pinFunction |= FUN_IE;//input enable but required for output as well?
|
||||
|
||||
if(mode & (INPUT | OUTPUT)) {
|
||||
pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
|
||||
} else if(mode == SPECIAL) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
pinFunction |= ((uint32_t)(((pin)==RX||(pin)==TX)?0:1) << MCU_SEL_S);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
pinFunction |= ((uint32_t)(((pin)==RX||(pin)==TX)?0:2) << MCU_SEL_S);
|
||||
#endif
|
||||
} else {
|
||||
pinFunction |= ((uint32_t)(mode >> 5) << MCU_SEL_S);
|
||||
}
|
||||
|
||||
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
|
||||
|
||||
if(mode & OPEN_DRAIN) {
|
||||
pinControl = (1 << GPIO_PIN0_PAD_DRIVER_S);
|
||||
}
|
||||
|
||||
GPIO.pin[pin].val = pinControl;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val)
|
||||
{
|
||||
#if USE_ESP_IDF_GPIO
|
||||
gpio_set_level((gpio_num_t)pin, val);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
if (val) {
|
||||
GPIO.out_w1ts.out_w1ts = (1 << pin);
|
||||
} else {
|
||||
GPIO.out_w1tc.out_w1tc = (1 << pin);
|
||||
}
|
||||
#else
|
||||
if(val) {
|
||||
if(pin < 32) {
|
||||
GPIO.out_w1ts = ((uint32_t)1 << pin);
|
||||
} else if(pin < NUM_OUPUT_PINS) {
|
||||
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
}
|
||||
} else {
|
||||
if(pin < 32) {
|
||||
GPIO.out_w1tc = ((uint32_t)1 << pin);
|
||||
} else if(pin < NUM_OUPUT_PINS) {
|
||||
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin)
|
||||
{
|
||||
#if USE_ESP_IDF_GPIO
|
||||
return gpio_get_level((gpio_num_t)pin);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
return (GPIO.in.data >> pin) & 0x1;
|
||||
#else
|
||||
if(pin < 32) {
|
||||
return (GPIO.in >> pin) & 0x1;
|
||||
} else if(pin < GPIO_PIN_COUNT) {
|
||||
return (GPIO.in1.val >> (pin - 32)) & 0x1;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_ESP_IDF_GPIO
|
||||
static void ARDUINO_ISR_ATTR __onPinInterrupt(void * arg) {
|
||||
InterruptHandle_t * isr = (InterruptHandle_t*)arg;
|
||||
if(isr->fn) {
|
||||
@ -372,49 +141,6 @@ static void ARDUINO_ISR_ATTR __onPinInterrupt(void * arg) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static intr_handle_t gpio_intr_handle = NULL;
|
||||
|
||||
static void ARDUINO_ISR_ATTR __onPinInterrupt()
|
||||
{
|
||||
uint32_t gpio_intr_status_l=0;
|
||||
uint32_t gpio_intr_status_h=0;
|
||||
|
||||
gpio_intr_status_l = GPIO.status;
|
||||
gpio_intr_status_h = GPIO.status1.val;
|
||||
GPIO.status_w1tc = gpio_intr_status_l;//Clear intr for gpio0-gpio31
|
||||
GPIO.status1_w1tc.val = gpio_intr_status_h;//Clear intr for gpio32-39
|
||||
|
||||
uint8_t pin=0;
|
||||
if(gpio_intr_status_l) {
|
||||
do {
|
||||
if(gpio_intr_status_l & ((uint32_t)1 << pin)) {
|
||||
if(__pinInterruptHandlers[pin].fn) {
|
||||
if(__pinInterruptHandlers[pin].arg){
|
||||
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
|
||||
} else {
|
||||
__pinInterruptHandlers[pin].fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(++pin<32);
|
||||
}
|
||||
if(gpio_intr_status_h) {
|
||||
pin=32;
|
||||
do {
|
||||
if(gpio_intr_status_h & ((uint32_t)1 << (pin - 32))) {
|
||||
if(__pinInterruptHandlers[pin].fn) {
|
||||
if(__pinInterruptHandlers[pin].arg){
|
||||
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
|
||||
} else {
|
||||
__pinInterruptHandlers[pin].fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(++pin<GPIO_PIN_COUNT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void cleanupFunctional(void* arg);
|
||||
|
||||
@ -423,13 +149,8 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc,
|
||||
static bool interrupt_initialized = false;
|
||||
|
||||
if(!interrupt_initialized) {
|
||||
#if USE_ESP_IDF_GPIO
|
||||
esp_err_t err = gpio_install_isr_service((int)ARDUINO_ISR_FLAG);
|
||||
interrupt_initialized = (err == ESP_OK) || (err == ESP_ERR_INVALID_STATE);
|
||||
#else
|
||||
interrupt_initialized = true;
|
||||
esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, __onPinInterrupt, NULL, &gpio_intr_handle);
|
||||
#endif
|
||||
}
|
||||
if(!interrupt_initialized) {
|
||||
log_e("GPIO ISR Service Failed To Start");
|
||||
@ -445,27 +166,18 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc,
|
||||
__pinInterruptHandlers[pin].arg = arg;
|
||||
__pinInterruptHandlers[pin].functional = functional;
|
||||
|
||||
#if USE_ESP_IDF_GPIO
|
||||
gpio_set_intr_type((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
|
||||
if(intr_type & 0x8){
|
||||
gpio_wakeup_enable((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
|
||||
}
|
||||
gpio_isr_handler_add((gpio_num_t)pin, __onPinInterrupt, &__pinInterruptHandlers[pin]);
|
||||
gpio_intr_enable((gpio_num_t)pin);
|
||||
#else
|
||||
esp_intr_disable(gpio_intr_handle);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU
|
||||
#endif
|
||||
GPIO.pin[pin].int_ena = 1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
} else { //PRO_CPU
|
||||
GPIO.pin[pin].int_ena = 4;
|
||||
}
|
||||
#endif
|
||||
GPIO.pin[pin].int_type = intr_type;
|
||||
esp_intr_enable(gpio_intr_handle);
|
||||
#endif
|
||||
|
||||
|
||||
//FIX interrupts on peripherals outputs (eg. LEDC,...)
|
||||
//Enable input in GPIO register
|
||||
gpio_hal_context_t gpiohal;
|
||||
gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
|
||||
gpio_hal_input_enable(&gpiohal, pin);
|
||||
}
|
||||
|
||||
extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type)
|
||||
@ -479,13 +191,9 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
|
||||
|
||||
extern void __detachInterrupt(uint8_t pin)
|
||||
{
|
||||
#if USE_ESP_IDF_GPIO
|
||||
gpio_intr_disable((gpio_num_t)pin);
|
||||
gpio_isr_handler_remove((gpio_num_t)pin);
|
||||
gpio_isr_handler_remove((gpio_num_t)pin); //remove handle and disable isr for pin
|
||||
gpio_wakeup_disable((gpio_num_t)pin);
|
||||
#else
|
||||
esp_intr_disable(gpio_intr_handle);
|
||||
#endif
|
||||
|
||||
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg)
|
||||
{
|
||||
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
||||
@ -494,13 +202,7 @@ extern void __detachInterrupt(uint8_t pin)
|
||||
__pinInterruptHandlers[pin].arg = NULL;
|
||||
__pinInterruptHandlers[pin].functional = false;
|
||||
|
||||
#if USE_ESP_IDF_GPIO
|
||||
gpio_set_intr_type((gpio_num_t)pin, GPIO_INTR_DISABLE);
|
||||
#else
|
||||
GPIO.pin[pin].int_ena = 0;
|
||||
GPIO.pin[pin].int_type = 0;
|
||||
esp_intr_enable(gpio_intr_handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,20 +42,15 @@ extern "C" {
|
||||
|
||||
//GPIO FUNCTIONS
|
||||
#define INPUT 0x01
|
||||
#define OUTPUT 0x02
|
||||
// Changed OUTPUT from 0x02 to behave the same as Arduino pinMode(pin,OUTPUT)
|
||||
// where you can read the state of pin even when it is set as OUTPUT
|
||||
#define OUTPUT 0x03
|
||||
#define PULLUP 0x04
|
||||
#define INPUT_PULLUP 0x05
|
||||
#define PULLDOWN 0x08
|
||||
#define INPUT_PULLDOWN 0x09
|
||||
#define OPEN_DRAIN 0x10
|
||||
#define OUTPUT_OPEN_DRAIN 0x12
|
||||
#define SPECIAL 0xF0
|
||||
#define FUNCTION_1 0x00
|
||||
#define FUNCTION_2 0x20
|
||||
#define FUNCTION_3 0x40
|
||||
#define FUNCTION_4 0x60
|
||||
#define FUNCTION_5 0x80
|
||||
#define FUNCTION_6 0xA0
|
||||
#define ANALOG 0xC0
|
||||
|
||||
//Interrupt Modes
|
||||
@ -68,22 +63,11 @@ extern "C" {
|
||||
#define ONLOW_WE 0x0C
|
||||
#define ONHIGH_WE 0x0D
|
||||
|
||||
typedef struct {
|
||||
uint8_t reg; /*!< GPIO register offset from DR_REG_IO_MUX_BASE */
|
||||
int8_t rtc; /*!< RTC GPIO number (-1 if not RTC GPIO pin) */
|
||||
int8_t adc; /*!< ADC Channel number (-1 if not ADC pin) */
|
||||
int8_t touch; /*!< Touch Channel number (-1 if not Touch pin) */
|
||||
} esp32_gpioMux_t;
|
||||
#define digitalPinIsValid(pin) GPIO_IS_VALID_GPIO(pin)
|
||||
#define digitalPinCanOutput(pin) GPIO_IS_VALID_OUTPUT_GPIO(pin)
|
||||
|
||||
extern const esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT];
|
||||
extern const int8_t esp32_adc2gpio[20];
|
||||
|
||||
#define digitalPinIsValid(pin) ((pin) < SOC_GPIO_PIN_COUNT && esp32_gpioMux[(pin)].reg)
|
||||
#define digitalPinCanOutput(pin) ((pin) < NUM_OUPUT_PINS && esp32_gpioMux[(pin)].reg)
|
||||
#define digitalPinToRtcPin(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].rtc:-1)
|
||||
#define digitalPinToAnalogChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].adc:-1)
|
||||
#define digitalPinToTouchChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].touch:-1)
|
||||
#define digitalPinToDacChannel(pin) (((pin) == PIN_DAC1)?0:((pin) == PIN_DAC2)?1:-1)
|
||||
#define digitalPinToRtcPin(pin) ((RTC_GPIO_IS_VALID_GPIO(pin))?rtc_io_number_get(pin):-1)
|
||||
#define digitalPinToDacChannel(pin) (((pin) == DAC_CHANNEL_1_GPIO_NUM)?0:((pin) == DAC_CHANNEL_2_GPIO_NUM)?1:-1)
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode);
|
||||
void digitalWrite(uint8_t pin, uint8_t val);
|
||||
@ -93,6 +77,10 @@ void attachInterrupt(uint8_t pin, void (*)(void), int mode);
|
||||
void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode);
|
||||
void detachInterrupt(uint8_t pin);
|
||||
|
||||
int8_t digitalPinToTouchChannel(uint8_t pin);
|
||||
int8_t digitalPinToAnalogChannel(uint8_t pin);
|
||||
int8_t analogChannelToDigitalPin(uint8_t channel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -127,7 +127,7 @@ typedef enum {
|
||||
|
||||
static inline i2c_stretch_cause_t i2c_ll_stretch_cause(i2c_dev_t *hw)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
return hw->sr.stretch_cause;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
return hw->status_reg.stretch_cause;
|
||||
@ -164,7 +164,7 @@ static inline void i2c_ll_stretch_clr(i2c_dev_t *hw)
|
||||
|
||||
static inline bool i2c_ll_slave_addressed(i2c_dev_t *hw)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
return hw->sr.slave_addressed;
|
||||
#else
|
||||
return hw->status_reg.slave_addressed;
|
||||
@ -173,7 +173,7 @@ static inline bool i2c_ll_slave_addressed(i2c_dev_t *hw)
|
||||
|
||||
static inline bool i2c_ll_slave_rw(i2c_dev_t *hw)//not exposed by hal_ll
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
return hw->sr.slave_rw;
|
||||
#else
|
||||
return hw->status_reg.slave_rw;
|
||||
@ -360,10 +360,12 @@ esp_err_t i2cSlaveDeinit(uint8_t num){
|
||||
}
|
||||
|
||||
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(!i2c->lock){
|
||||
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
#endif
|
||||
I2C_SLAVE_MUTEX_LOCK();
|
||||
i2c_slave_free_resources(i2c);
|
||||
I2C_SLAVE_MUTEX_UNLOCK();
|
||||
@ -377,10 +379,12 @@ size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t tim
|
||||
}
|
||||
size_t to_queue = 0, to_fifo = 0;
|
||||
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(!i2c->lock){
|
||||
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
#endif
|
||||
if(!i2c->tx_queue){
|
||||
return 0;
|
||||
}
|
||||
@ -715,10 +719,12 @@ static void i2c_slave_isr_handler(void* arg)
|
||||
}
|
||||
if(slave_rw){ // READ
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//SEND TX Event
|
||||
i2c_slave_queue_event_t event;
|
||||
event.event = I2C_SLAVE_EVT_TX;
|
||||
pxHigherPriorityTaskWoken |= i2c_slave_send_event(i2c, &event);
|
||||
if(i2c->dev->status_reg.scl_main_state_last == 6){
|
||||
//SEND TX Event
|
||||
i2c_slave_queue_event_t event;
|
||||
event.event = I2C_SLAVE_EVT_TX;
|
||||
pxHigherPriorityTaskWoken |= i2c_slave_send_event(i2c, &event);
|
||||
}
|
||||
#else
|
||||
//reset TX data
|
||||
i2c_ll_txfifo_rst(i2c->dev);
|
||||
|
@ -317,6 +317,8 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency){
|
||||
hal.dev = I2C_LL_GET_HW(i2c_num);
|
||||
i2c_hal_set_bus_timing(&(hal), frequency, src_clk);
|
||||
bus[i2c_num].frequency = frequency;
|
||||
//Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2
|
||||
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -54,12 +54,13 @@
|
||||
|
||||
uint8_t channels_resolution[LEDC_CHANNELS] = {0};
|
||||
|
||||
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
|
||||
uint32_t ledcSetup(uint8_t chan, uint32_t freq, uint8_t bit_num)
|
||||
{
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
log_e("No more LEDC channels available! You can have maximum %u", LEDC_CHANNELS);
|
||||
if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
|
||||
log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
@ -69,9 +70,12 @@ double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
ledc_timer_config(&ledc_timer);
|
||||
if(ledc_timer_config(&ledc_timer) != ESP_OK)
|
||||
{
|
||||
log_e("ledc setup failed!");
|
||||
return 0;
|
||||
}
|
||||
channels_resolution[chan] = bit_num;
|
||||
|
||||
return ledc_get_freq(group,timer);
|
||||
}
|
||||
|
||||
@ -95,14 +99,14 @@ void ledcWrite(uint8_t chan, uint32_t duty)
|
||||
|
||||
uint32_t ledcRead(uint8_t chan)
|
||||
{
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return 0;
|
||||
}
|
||||
uint8_t group=(chan/8), channel=(chan%8);
|
||||
return ledc_get_duty(group,channel);
|
||||
}
|
||||
|
||||
double ledcReadFreq(uint8_t chan)
|
||||
uint32_t ledcReadFreq(uint8_t chan)
|
||||
{
|
||||
if(!ledcRead(chan)){
|
||||
return 0;
|
||||
@ -111,7 +115,7 @@ double ledcReadFreq(uint8_t chan)
|
||||
return ledc_get_freq(group,timer);
|
||||
}
|
||||
|
||||
double ledcWriteTone(uint8_t chan, double freq)
|
||||
uint32_t ledcWriteTone(uint8_t chan, uint32_t freq)
|
||||
{
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return 0;
|
||||
@ -130,15 +134,20 @@ double ledcWriteTone(uint8_t chan, double freq)
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
ledc_timer_config(&ledc_timer);
|
||||
|
||||
if(ledc_timer_config(&ledc_timer) != ESP_OK)
|
||||
{
|
||||
log_e("ledcSetup failed!");
|
||||
return 0;
|
||||
}
|
||||
channels_resolution[chan] = 10;
|
||||
|
||||
double res_freq = ledc_get_freq(group,timer);
|
||||
uint32_t res_freq = ledc_get_freq(group,timer);
|
||||
ledcWrite(chan, 0x1FF);
|
||||
return res_freq;
|
||||
}
|
||||
|
||||
double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
|
||||
uint32_t ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
|
||||
const uint16_t noteFrequencyBase[12] = {
|
||||
// C C# D Eb E F F# G G# A Bb B
|
||||
4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902
|
||||
@ -147,13 +156,13 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
|
||||
if(octave > 8 || note >= NOTE_MAX){
|
||||
return 0;
|
||||
}
|
||||
double noteFreq = (double)noteFrequencyBase[note] / (double)(1 << (8-octave));
|
||||
uint32_t noteFreq = (uint32_t)noteFrequencyBase[note] / (uint32_t)(1 << (8-octave));
|
||||
return ledcWriteTone(chan, noteFreq);
|
||||
}
|
||||
|
||||
void ledcAttachPin(uint8_t pin, uint8_t chan)
|
||||
{
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return;
|
||||
}
|
||||
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
|
||||
@ -175,9 +184,10 @@ void ledcDetachPin(uint8_t pin)
|
||||
pinMatrixOutDetach(pin, false, false);
|
||||
}
|
||||
|
||||
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
|
||||
uint32_t ledcChangeFrequency(uint8_t chan, uint32_t freq, uint8_t bit_num)
|
||||
{
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
|
||||
log_e("LEDC channel not available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
|
||||
return 0;
|
||||
}
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
@ -189,9 +199,13 @@ double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
ledc_timer_config(&ledc_timer);
|
||||
channels_resolution[chan] = bit_num;
|
||||
|
||||
if(ledc_timer_config(&ledc_timer) != ESP_OK)
|
||||
{
|
||||
log_e("ledcChangeFrequency failed!");
|
||||
return 0;
|
||||
}
|
||||
channels_resolution[chan] = bit_num;
|
||||
return ledc_get_freq(group,timer);
|
||||
}
|
||||
|
||||
|
@ -27,15 +27,15 @@ typedef enum {
|
||||
} note_t;
|
||||
|
||||
//channel 0-15 resolution 1-16bits freq limits depend on resolution
|
||||
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits);
|
||||
uint32_t ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
|
||||
void ledcWrite(uint8_t channel, uint32_t duty);
|
||||
double ledcWriteTone(uint8_t channel, double freq);
|
||||
double ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
|
||||
uint32_t ledcWriteTone(uint8_t channel, uint32_t freq);
|
||||
uint32_t ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
|
||||
uint32_t ledcRead(uint8_t channel);
|
||||
double ledcReadFreq(uint8_t channel);
|
||||
uint32_t ledcReadFreq(uint8_t channel);
|
||||
void ledcAttachPin(uint8_t pin, uint8_t channel);
|
||||
void ledcDetachPin(uint8_t pin);
|
||||
double ledcChangeFrequency(uint8_t channel, double freq, uint8_t resolution_bits);
|
||||
uint32_t ledcChangeFrequency(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -38,9 +38,11 @@ extern "C"
|
||||
#else
|
||||
#define ARDUHAL_LOG_LEVEL CORE_DEBUG_LEVEL
|
||||
#ifdef USE_ESP_IDF_LOG
|
||||
#ifndef LOG_LOCAL_LEVEL
|
||||
#define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARDUHAL_LOG_COLORS
|
||||
#define CONFIG_ARDUHAL_LOG_COLORS 0
|
||||
@ -158,7 +160,7 @@ void log_print_buf(const uint8_t *b, size_t len);
|
||||
#define isr_log_e(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define log_buf_e(b,l) do{ARDUHAL_LOG_COLOR_PRINT(E);log_print_buf(b,l);ARDUHAL_LOG_COLOR_PRINT_END;}while(0)
|
||||
#else
|
||||
#define log_e(format, ...) do {log_to_esp(TAG, ESP_LOG_ERROR, format, ##__VA_ARGS__);}while(0)
|
||||
#define log_e(format, ...) do {ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, TAG, format, ##__VA_ARGS__);}while(0)
|
||||
#define isr_log_e(format, ...) do {ets_printf(LOG_FORMAT(E, format), esp_log_timestamp(), TAG, ##__VA_ARGS__);}while(0)
|
||||
#define log_buf_e(b,l) do {ESP_LOG_BUFFER_HEXDUMP(TAG, b, l, ESP_LOG_ERROR);}while(0)
|
||||
#endif
|
||||
@ -187,9 +189,9 @@ void log_print_buf(const uint8_t *b, size_t len);
|
||||
#include "esp_log.h"
|
||||
|
||||
#ifdef USE_ESP_IDF_LOG
|
||||
#ifndef TAG
|
||||
#define TAG "ARDUINO"
|
||||
#endif
|
||||
//#ifndef TAG
|
||||
//#define TAG "ARDUINO"
|
||||
//#endif
|
||||
//#define log_n(format, ...) myLog(ESP_LOG_NONE, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#ifdef CONFIG_ARDUHAL_ESP_LOG
|
||||
@ -204,16 +206,16 @@ void log_print_buf(const uint8_t *b, size_t len);
|
||||
#undef ESP_EARLY_LOGD
|
||||
#undef ESP_EARLY_LOGV
|
||||
|
||||
#define ESP_LOGE(tag, ...) log_e(__VA_ARGS__)
|
||||
#define ESP_LOGW(tag, ...) log_w(__VA_ARGS__)
|
||||
#define ESP_LOGI(tag, ...) log_i(__VA_ARGS__)
|
||||
#define ESP_LOGD(tag, ...) log_d(__VA_ARGS__)
|
||||
#define ESP_LOGV(tag, ...) log_v(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGE(tag, ...) isr_log_e(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGW(tag, ...) isr_log_w(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGI(tag, ...) isr_log_i(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGD(tag, ...) isr_log_d(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGV(tag, ...) isr_log_v(__VA_ARGS__)
|
||||
#define ESP_LOGE(tag, format, ...) log_e("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_LOGW(tag, format, ...) log_w("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_LOGI(tag, format, ...) log_i("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_LOGD(tag, format, ...) log_d("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_LOGV(tag, format, ...) log_v("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGE(tag, format, ...) isr_log_e("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGW(tag, format, ...) isr_log_w("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGI(tag, format, ...) isr_log_i("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGD(tag, format, ...) isr_log_d("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGV(tag, format, ...) isr_log_v("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "esp32/rom/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/gpio.h"
|
||||
#else
|
||||
|
@ -41,6 +41,9 @@
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/rtc.h"
|
||||
#include "driver/temp_sensor.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/rtc.h"
|
||||
#include "driver/temp_sensor.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#include "driver/temp_sensor.h"
|
||||
@ -232,7 +235,7 @@ void initArduino()
|
||||
#endif
|
||||
esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL);
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if(err == ESP_ERR_NVS_NO_FREE_PAGES){
|
||||
if(err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND){
|
||||
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
|
||||
if (partition != NULL) {
|
||||
err = esp_partition_erase_range(partition, 0, partition->size);
|
||||
@ -241,6 +244,8 @@ void initArduino()
|
||||
} else {
|
||||
log_e("Failed to format the broken NVS partition!");
|
||||
}
|
||||
} else {
|
||||
log_e("Could not find NVS partition");
|
||||
}
|
||||
}
|
||||
if(err) {
|
||||
|
@ -25,6 +25,9 @@
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/spiram.h"
|
||||
#include "esp32s2/rom/cache.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/spiram.h"
|
||||
#include "esp32s3/rom/cache.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
@ -35,6 +38,13 @@
|
||||
static volatile bool spiramDetected = false;
|
||||
static volatile bool spiramFailed = false;
|
||||
|
||||
//allows user to bypass SPI RAM test routine
|
||||
__attribute__((weak)) bool testSPIRAM(void)
|
||||
{
|
||||
return esp_spiram_test();
|
||||
}
|
||||
|
||||
|
||||
bool psramInit(){
|
||||
if (spiramDetected) {
|
||||
return true;
|
||||
@ -60,13 +70,16 @@ bool psramInit(){
|
||||
spiramFailed = true;
|
||||
log_w("PSRAM init failed!");
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
pinMatrixOutDetach(16, false, false);
|
||||
pinMatrixOutDetach(17, false, false);
|
||||
if (pkg_ver != EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||
pinMatrixOutDetach(16, false, false);
|
||||
pinMatrixOutDetach(17, false, false);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
esp_spiram_init_cache();
|
||||
if (!esp_spiram_test()) {
|
||||
//testSPIRAM() allows user to bypass SPI RAM test routine
|
||||
if (!testSPIRAM()) {
|
||||
spiramFailed = true;
|
||||
log_e("PSRAM test failed!");
|
||||
return false;
|
||||
@ -76,12 +89,12 @@ bool psramInit(){
|
||||
log_e("PSRAM could not be added to the heap!");
|
||||
return false;
|
||||
}
|
||||
#if CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL && !CONFIG_ARDUINO_ISR_IRAM
|
||||
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_USE_MALLOC && !CONFIG_ARDUINO_ISR_IRAM
|
||||
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
||||
#endif
|
||||
#endif /* CONFIG_SPIRAM_BOOT_INIT */
|
||||
log_i("PSRAM enabled");
|
||||
spiramDetected = true;
|
||||
log_d("PSRAM enabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ struct rmt_obj_s
|
||||
void * arg;
|
||||
TaskHandle_t rxTaskHandle;
|
||||
bool rx_completed;
|
||||
bool tx_not_rx;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -109,15 +110,15 @@ static xSemaphoreHandle g_rmt_objlocks[MAX_CHANNELS] = {
|
||||
};
|
||||
|
||||
static rmt_obj_t g_rmt_objects[MAX_CHANNELS] = {
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
|
||||
#if MAX_CHANNELS > 4
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
|
||||
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -248,6 +249,26 @@ static bool _rmtCreateRxTask(rmt_obj_t* rmt)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper function to test if an RMT channel is correctly assigned to TX or RX, issuing an error message if necessary
|
||||
// Also test RMT pointer for NULL and returns false in case it is NULL
|
||||
// return true when it is correctly assigned, false otherwise
|
||||
static bool _rmtCheckTXnotRX(rmt_obj_t* rmt, bool tx_not_rx)
|
||||
{
|
||||
if (!rmt) { // also returns false on NULL
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rmt->tx_not_rx == tx_not_rx) { // matches expected RX/TX channel
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tx_not_rx) { // expected TX channel
|
||||
log_e("Can't write on a RX RMT Channel");
|
||||
} else{ // expected RX channel
|
||||
log_e("Can't read on a TX RMT Channel");
|
||||
}
|
||||
return false; // missmatched
|
||||
}
|
||||
|
||||
/**
|
||||
* Public method definitions
|
||||
@ -255,7 +276,7 @@ static bool _rmtCreateRxTask(rmt_obj_t* rmt)
|
||||
|
||||
bool rmtSetCarrier(rmt_obj_t* rmt, bool carrier_en, bool carrier_level, uint32_t low, uint32_t high)
|
||||
{
|
||||
if (!rmt || low > 0xFFFF || high > 0xFFFF) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_TX_MODE) || low > 0xFFFF || high > 0xFFFF) {
|
||||
return false;
|
||||
}
|
||||
size_t channel = rmt->channel;
|
||||
@ -268,7 +289,7 @@ bool rmtSetCarrier(rmt_obj_t* rmt, bool carrier_en, bool carrier_level, uint32_t
|
||||
|
||||
bool rmtSetFilter(rmt_obj_t* rmt, bool filter_en, uint32_t filter_level)
|
||||
{
|
||||
if (!rmt || filter_level > 0xFF) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE) || filter_level > 0xFF) {
|
||||
return false;
|
||||
}
|
||||
size_t channel = rmt->channel;
|
||||
@ -281,7 +302,7 @@ bool rmtSetFilter(rmt_obj_t* rmt, bool filter_en, uint32_t filter_level)
|
||||
|
||||
bool rmtSetRxThreshold(rmt_obj_t* rmt, uint32_t value)
|
||||
{
|
||||
if (!rmt || value > 0xFFFF) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE) || value > 0xFFFF) {
|
||||
return false;
|
||||
}
|
||||
size_t channel = rmt->channel;
|
||||
@ -306,14 +327,17 @@ bool rmtDeinit(rmt_obj_t *rmt)
|
||||
|
||||
RMT_MUTEX_LOCK(rmt->channel);
|
||||
// force stopping rmt processing
|
||||
rmt_rx_stop(rmt->channel);
|
||||
rmt_tx_stop(rmt->channel);
|
||||
if (rmt->tx_not_rx) {
|
||||
rmt_tx_stop(rmt->channel);
|
||||
} else {
|
||||
rmt_rx_stop(rmt->channel);
|
||||
if(rmt->rxTaskHandle){
|
||||
vTaskDelete(rmt->rxTaskHandle);
|
||||
rmt->rxTaskHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(rmt->rxTaskHandle){
|
||||
vTaskDelete(rmt->rxTaskHandle);
|
||||
rmt->rxTaskHandle = NULL;
|
||||
}
|
||||
rmt_driver_uninstall(rmt->channel);
|
||||
rmt_driver_uninstall(rmt->channel);
|
||||
|
||||
size_t from = rmt->channel;
|
||||
size_t to = rmt->buffers + rmt->channel;
|
||||
@ -330,6 +354,7 @@ bool rmtDeinit(rmt_obj_t *rmt)
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(g_rmt_objlocks[from] != NULL) {
|
||||
vSemaphoreDelete(g_rmt_objlocks[from]);
|
||||
g_rmt_objlocks[from] = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -338,10 +363,9 @@ bool rmtDeinit(rmt_obj_t *rmt)
|
||||
|
||||
bool rmtLoop(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
|
||||
{
|
||||
if (!rmt) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_TX_MODE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int channel = rmt->channel;
|
||||
RMT_MUTEX_LOCK(channel);
|
||||
rmt_tx_stop(channel);
|
||||
@ -353,10 +377,9 @@ bool rmtLoop(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
|
||||
|
||||
bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
|
||||
{
|
||||
if (!rmt) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_TX_MODE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int channel = rmt->channel;
|
||||
RMT_MUTEX_LOCK(channel);
|
||||
rmt_tx_stop(channel);
|
||||
@ -368,10 +391,9 @@ bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
|
||||
|
||||
bool rmtWriteBlocking(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
|
||||
{
|
||||
if (!rmt) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_TX_MODE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int channel = rmt->channel;
|
||||
RMT_MUTEX_LOCK(channel);
|
||||
rmt_tx_stop(channel);
|
||||
@ -383,10 +405,9 @@ bool rmtWriteBlocking(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
|
||||
|
||||
bool rmtReadData(rmt_obj_t* rmt, uint32_t* data, size_t size)
|
||||
{
|
||||
if (!rmt) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rmtReadAsync(rmt, (rmt_data_t*) data, size, NULL, false, 0);
|
||||
return true;
|
||||
}
|
||||
@ -394,7 +415,7 @@ bool rmtReadData(rmt_obj_t* rmt, uint32_t* data, size_t size)
|
||||
|
||||
bool rmtBeginReceive(rmt_obj_t* rmt)
|
||||
{
|
||||
if (!rmt) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE)) {
|
||||
return false;
|
||||
}
|
||||
int channel = rmt->channel;
|
||||
@ -418,7 +439,7 @@ bool rmtReceiveCompleted(rmt_obj_t* rmt)
|
||||
|
||||
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb, void * arg)
|
||||
{
|
||||
if (!rmt || !cb) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE)) {
|
||||
return false;
|
||||
}
|
||||
int channel = rmt->channel;
|
||||
@ -449,15 +470,19 @@ bool rmtEnd(rmt_obj_t* rmt)
|
||||
int channel = rmt->channel;
|
||||
|
||||
RMT_MUTEX_LOCK(channel);
|
||||
rmt_rx_stop(channel);
|
||||
rmt->rx_completed = true;
|
||||
if (rmt->tx_not_rx) {
|
||||
rmt_tx_stop(channel);
|
||||
} else {
|
||||
rmt_rx_stop(channel);
|
||||
rmt->rx_completed = true;
|
||||
}
|
||||
RMT_MUTEX_UNLOCK(channel);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rmtReadAsync(rmt_obj_t* rmt, rmt_data_t* data, size_t size, void* eventFlag, bool waitForData, uint32_t timeout)
|
||||
{
|
||||
if (!rmt) {
|
||||
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE)) {
|
||||
return false;
|
||||
}
|
||||
int channel = rmt->channel;
|
||||
@ -568,6 +593,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
|
||||
rmt->data_size = 0;
|
||||
rmt->rx_completed = false;
|
||||
rmt->events = NULL;
|
||||
rmt->tx_not_rx = tx_not_rx;
|
||||
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(g_rmt_objlocks[channel] == NULL) {
|
||||
|
@ -37,6 +37,11 @@
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp32s2/rom/gpio.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp32s3/rom/ets_sys.h"
|
||||
#include "esp32s3/rom/gpio.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "esp32c3/rom/gpio.h"
|
||||
@ -71,10 +76,20 @@ struct spi_struct_t {
|
||||
#define SPI_FSPI_SS_IDX(n) ((n==0)?FSPICS0_OUT_IDX:((n==1)?FSPICS1_OUT_IDX:((n==2)?FSPICS2_OUT_IDX:FSPICS0_OUT_IDX)))
|
||||
#define SPI_SS_IDX(p, n) ((p==0)?SPI_SPI_SS_IDX(n):((p==1)?SPI_SPI_SS_IDX(n):((p==2)?SPI_HSPI_SS_IDX(n):0)))
|
||||
|
||||
#define SPI_INTR_SOURCE(u) ((u==0)?ETS_SPI1_INTR_SOURCE:((u==1)?ETS_SPI2_INTR_SOURCE:((u==2)?ETS_SPI3_INTR_SOURCE:0)))
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
// ESP32S3
|
||||
#define SPI_COUNT (2)
|
||||
|
||||
#define SPI_CLK_IDX(p) ((p==0)?FSPICLK_OUT_IDX:((p==1)?SPI3_CLK_OUT_IDX:0))
|
||||
#define SPI_MISO_IDX(p) ((p==0)?FSPIQ_OUT_IDX:((p==1)?SPI3_Q_OUT_IDX:0))
|
||||
#define SPI_MOSI_IDX(p) ((p==0)?FSPID_IN_IDX:((p==1)?SPI3_D_IN_IDX:0))
|
||||
|
||||
#define SPI_HSPI_SS_IDX(n) ((n==0)?SPI3_CS0_OUT_IDX:((n==1)?SPI3_CS1_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))
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
// ESP32S2
|
||||
// ESP32C3
|
||||
#define SPI_COUNT (1)
|
||||
|
||||
#define SPI_CLK_IDX(p) FSPICLK_OUT_IDX
|
||||
@ -84,8 +99,6 @@ struct spi_struct_t {
|
||||
#define SPI_SPI_SS_IDX(n) ((n==0)?FSPICS0_OUT_IDX:((n==1)?FSPICS1_OUT_IDX:((n==2)?FSPICS2_OUT_IDX:FSPICS0_OUT_IDX)))
|
||||
#define SPI_SS_IDX(p, n) SPI_SPI_SS_IDX(n)
|
||||
|
||||
#define SPI_INTR_SOURCE(u) ETS_SPI2_INTR_SOURCE
|
||||
|
||||
#else
|
||||
// ESP32
|
||||
#define SPI_COUNT (4)
|
||||
@ -99,8 +112,6 @@ struct spi_struct_t {
|
||||
#define SPI_VSPI_SS_IDX(n) ((n==0)?VSPICS0_OUT_IDX:((n==1)?VSPICS1_OUT_IDX:((n==2)?VSPICS2_OUT_IDX:VSPICS0_OUT_IDX)))
|
||||
#define SPI_SS_IDX(p, n) ((p==0)?SPI_SPI_SS_IDX(n):((p==1)?SPI_SPI_SS_IDX(n):((p==2)?SPI_HSPI_SS_IDX(n):((p==3)?SPI_VSPI_SS_IDX(n):0))))
|
||||
|
||||
#define SPI_INTR_SOURCE(u) ((u==0)?ETS_SPI0_INTR_SOURCE:((u==1)?ETS_SPI1_INTR_SOURCE:((u==2)?ETS_SPI2_INTR_SOURCE:((p==3)?ETS_SPI3_INTR_SOURCE:0))))
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
@ -112,6 +123,11 @@ static spi_t _spi_bus_array[] = {
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0},
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1},
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0},
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1}
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0}
|
||||
#else
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0},
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1},
|
||||
@ -128,8 +144,11 @@ static spi_t _spi_bus_array[] = {
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0},
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1},
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0},
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 1}
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
{(volatile spi_dev_t *)(&GPSPI2), NULL, FSPI}
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0}
|
||||
#else
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0},
|
||||
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1},
|
||||
@ -152,6 +171,13 @@ void spiAttachSCK(spi_t * spi, int8_t sck)
|
||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
sck = 12;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S3!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi->num == HSPI) {
|
||||
sck = 14;
|
||||
@ -182,6 +208,13 @@ void spiAttachMISO(spi_t * spi, int8_t miso)
|
||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
miso = 13;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S3!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi->num == HSPI) {
|
||||
miso = 12;
|
||||
@ -207,13 +240,20 @@ void spiAttachMOSI(spi_t * spi, int8_t mosi)
|
||||
return;
|
||||
}
|
||||
if(mosi < 0) {
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
mosi = 35;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
mosi = 11;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S3!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi->num == HSPI) {
|
||||
mosi = 13;
|
||||
@ -237,13 +277,20 @@ void spiDetachSCK(spi_t * spi, int8_t sck)
|
||||
return;
|
||||
}
|
||||
if(sck < 0) {
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
sck = 36;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
sck = 12;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S3!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi->num == HSPI) {
|
||||
sck = 14;
|
||||
@ -267,13 +314,20 @@ void spiDetachMISO(spi_t * spi, int8_t miso)
|
||||
return;
|
||||
}
|
||||
if(miso < 0) {
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
miso = 37;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
miso = 13;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S3!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi->num == HSPI) {
|
||||
miso = 12;
|
||||
@ -297,13 +351,20 @@ void spiDetachMOSI(spi_t * spi, int8_t mosi)
|
||||
return;
|
||||
}
|
||||
if(mosi < 0) {
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
mosi = 35;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
mosi = 11;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S3!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi->num == HSPI) {
|
||||
mosi = 13;
|
||||
@ -338,6 +399,13 @@ void spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss)
|
||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
ss = 10;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S3!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi->num == HSPI) {
|
||||
ss = 15;
|
||||
@ -369,6 +437,13 @@ void spiDetachSS(spi_t * spi, int8_t ss)
|
||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi->num == FSPI) {
|
||||
ss = 10;
|
||||
} else {
|
||||
log_e("HSPI Does not have default pins on ESP32S3!");
|
||||
return;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi->num == HSPI) {
|
||||
ss = 15;
|
||||
@ -392,7 +467,7 @@ void spiEnableSSPins(spi_t * spi, uint8_t cs_mask)
|
||||
return;
|
||||
}
|
||||
SPI_MUTEX_LOCK();
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.val &= ~(cs_mask & SPI_CS_MASK_ALL);
|
||||
#else
|
||||
spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL);
|
||||
@ -406,7 +481,7 @@ void spiDisableSSPins(spi_t * spi, uint8_t cs_mask)
|
||||
return;
|
||||
}
|
||||
SPI_MUTEX_LOCK();
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.val |= (cs_mask & SPI_CS_MASK_ALL);
|
||||
#else
|
||||
spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL);
|
||||
@ -442,7 +517,7 @@ void spiSSSet(spi_t * spi)
|
||||
return;
|
||||
}
|
||||
SPI_MUTEX_LOCK();
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.cs_keep_active = 1;
|
||||
#else
|
||||
spi->dev->pin.cs_keep_active = 1;
|
||||
@ -456,7 +531,7 @@ void spiSSClear(spi_t * spi)
|
||||
return;
|
||||
}
|
||||
SPI_MUTEX_LOCK();
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.cs_keep_active = 0;
|
||||
#else
|
||||
spi->dev->pin.cs_keep_active = 0;
|
||||
@ -487,7 +562,7 @@ uint8_t spiGetDataMode(spi_t * spi)
|
||||
if(!spi) {
|
||||
return 0;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
bool idleEdge = spi->dev->misc.ck_idle_edge;
|
||||
#else
|
||||
bool idleEdge = spi->dev->pin.ck_idle_edge;
|
||||
@ -513,7 +588,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
|
||||
SPI_MUTEX_LOCK();
|
||||
switch (dataMode) {
|
||||
case SPI_MODE1:
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.ck_idle_edge = 0;
|
||||
#else
|
||||
spi->dev->pin.ck_idle_edge = 0;
|
||||
@ -521,7 +596,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
|
||||
spi->dev->user.ck_out_edge = 1;
|
||||
break;
|
||||
case SPI_MODE2:
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.ck_idle_edge = 1;
|
||||
#else
|
||||
spi->dev->pin.ck_idle_edge = 1;
|
||||
@ -529,7 +604,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
|
||||
spi->dev->user.ck_out_edge = 1;
|
||||
break;
|
||||
case SPI_MODE3:
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.ck_idle_edge = 1;
|
||||
#else
|
||||
spi->dev->pin.ck_idle_edge = 1;
|
||||
@ -538,7 +613,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
|
||||
break;
|
||||
case SPI_MODE0:
|
||||
default:
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.ck_idle_edge = 0;
|
||||
#else
|
||||
spi->dev->pin.ck_idle_edge = 0;
|
||||
@ -587,11 +662,11 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb
|
||||
|
||||
static void spiInitBus(spi_t * spi)
|
||||
{
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->slave.trans_done = 0;
|
||||
#endif
|
||||
spi->dev->slave.val = 0;
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.val = 0;
|
||||
#else
|
||||
spi->dev->pin.val = 0;
|
||||
@ -599,7 +674,7 @@ static void spiInitBus(spi_t * spi)
|
||||
spi->dev->user.val = 0;
|
||||
spi->dev->user1.val = 0;
|
||||
spi->dev->ctrl.val = 0;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->ctrl1.val = 0;
|
||||
spi->dev->ctrl2.val = 0;
|
||||
#else
|
||||
@ -652,6 +727,14 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST);
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
if(spi_num == FSPI) {
|
||||
periph_module_reset( PERIPH_SPI2_MODULE );
|
||||
periph_module_enable( PERIPH_SPI2_MODULE );
|
||||
} else if(spi_num == HSPI) {
|
||||
periph_module_reset( PERIPH_SPI3_MODULE );
|
||||
periph_module_enable( PERIPH_SPI3_MODULE );
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
if(spi_num == HSPI) {
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN);
|
||||
@ -670,7 +753,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
|
||||
|
||||
SPI_MUTEX_LOCK();
|
||||
spiInitBus(spi);
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->clk_gate.clk_en = 1;
|
||||
spi->dev->clk_gate.mst_clk_sel = 1;
|
||||
spi->dev->clk_gate.mst_clk_active = 1;
|
||||
@ -707,7 +790,7 @@ void spiWaitReady(spi_t * spi)
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#define usr_mosi_dbitlen usr_mosi_bit_len
|
||||
#define usr_miso_dbitlen usr_miso_bit_len
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define usr_mosi_dbitlen ms_data_bitlen
|
||||
#define usr_miso_dbitlen ms_data_bitlen
|
||||
#define mosi_dlen ms_dlen
|
||||
@ -725,13 +808,13 @@ void spiWrite(spi_t * spi, const uint32_t *data, uint8_t len)
|
||||
}
|
||||
SPI_MUTEX_LOCK();
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
for(i=0; i<len; i++) {
|
||||
spi->dev->data_buf[i] = data[i];
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -755,7 +838,7 @@ void spiTransfer(spi_t * spi, uint32_t *data, uint8_t len)
|
||||
for(i=0; i<len; i++) {
|
||||
spi->dev->data_buf[i] = data[i];
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -774,11 +857,11 @@ void spiWriteByte(spi_t * spi, uint8_t data)
|
||||
}
|
||||
SPI_MUTEX_LOCK();
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -796,7 +879,7 @@ uint8_t spiTransferByte(spi_t * spi, uint8_t data)
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -827,11 +910,11 @@ void spiWriteWord(spi_t * spi, uint16_t data)
|
||||
}
|
||||
SPI_MUTEX_LOCK();
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -852,7 +935,7 @@ uint16_t spiTransferWord(spi_t * spi, uint16_t data)
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -876,11 +959,11 @@ void spiWriteLong(spi_t * spi, uint32_t data)
|
||||
}
|
||||
SPI_MUTEX_LOCK();
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -901,7 +984,7 @@ uint32_t spiTransferLong(spi_t * spi, uint32_t data)
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -944,7 +1027,7 @@ static void __spiTransferBytes(spi_t * spi, const uint8_t * data, uint8_t * out,
|
||||
spi->dev->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1012,7 +1095,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
|
||||
spi->dev->clock.val = clockDiv;
|
||||
switch (dataMode) {
|
||||
case SPI_MODE1:
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.ck_idle_edge = 0;
|
||||
#else
|
||||
spi->dev->pin.ck_idle_edge = 0;
|
||||
@ -1020,7 +1103,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
|
||||
spi->dev->user.ck_out_edge = 1;
|
||||
break;
|
||||
case SPI_MODE2:
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.ck_idle_edge = 1;
|
||||
#else
|
||||
spi->dev->pin.ck_idle_edge = 1;
|
||||
@ -1028,7 +1111,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
|
||||
spi->dev->user.ck_out_edge = 1;
|
||||
break;
|
||||
case SPI_MODE3:
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.ck_idle_edge = 1;
|
||||
#else
|
||||
spi->dev->pin.ck_idle_edge = 1;
|
||||
@ -1037,7 +1120,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
|
||||
break;
|
||||
case SPI_MODE0:
|
||||
default:
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||
spi->dev->misc.ck_idle_edge = 0;
|
||||
#else
|
||||
spi->dev->pin.ck_idle_edge = 0;
|
||||
@ -1076,11 +1159,11 @@ void ARDUINO_ISR_ATTR spiWriteByteNL(spi_t * spi, uint8_t data)
|
||||
return;
|
||||
}
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1096,7 +1179,7 @@ uint8_t spiTransferByteNL(spi_t * spi, uint8_t data)
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1115,11 +1198,11 @@ void ARDUINO_ISR_ATTR spiWriteShortNL(spi_t * spi, uint16_t data)
|
||||
MSB_16_SET(data, data);
|
||||
}
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1138,7 +1221,7 @@ uint16_t spiTransferShortNL(spi_t * spi, uint16_t data)
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1160,11 +1243,11 @@ void ARDUINO_ISR_ATTR spiWriteLongNL(spi_t * spi, uint32_t data)
|
||||
MSB_32_SET(data, data);
|
||||
}
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1183,7 +1266,7 @@ uint32_t spiTransferLongNL(spi_t * spi, uint32_t data)
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1212,13 +1295,13 @@ void spiWriteNL(spi_t * spi, const void * data_in, uint32_t len){
|
||||
c_longs = (longs > 16)?16:longs;
|
||||
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
for (int i=0; i<c_longs; i++) {
|
||||
spi->dev->data_buf[i] = data[i];
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1258,7 +1341,7 @@ void spiTransferBytesNL(spi_t * spi, const void * data_in, uint8_t * data_out, u
|
||||
spi->dev->data_buf[i] = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1317,7 +1400,7 @@ void spiTransferBitsNL(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1);
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1);
|
||||
spi->dev->data_buf[0] = data;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1353,7 +1436,7 @@ void ARDUINO_ISR_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, uint32
|
||||
l_bytes = (c_len & 3);
|
||||
|
||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||
#endif
|
||||
for (int i=0; i<c_longs; i++) {
|
||||
@ -1371,7 +1454,7 @@ void ARDUINO_ISR_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, uint32
|
||||
spi->dev->data_buf[i] = data[i];
|
||||
}
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
spi->dev->cmd.update = 1;
|
||||
while (spi->dev->cmd.update);
|
||||
#endif
|
||||
@ -1397,7 +1480,7 @@ typedef union {
|
||||
uint32_t clkcnt_l: 6; /*it must be equal to spi_clkcnt_N.*/
|
||||
uint32_t clkcnt_h: 6; /*it must be floor((spi_clkcnt_N+1)/2-1).*/
|
||||
uint32_t clkcnt_n: 6; /*it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
uint32_t clkdiv_pre: 4; /*it is pre-divider of spi_clk.*/
|
||||
uint32_t reserved: 9; /*reserved*/
|
||||
#else
|
||||
@ -1444,7 +1527,7 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
|
||||
|
||||
while(calPreVari++ <= 1) {
|
||||
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
if(calPre > 0xF) {
|
||||
reg.clkdiv_pre = 0xF;
|
||||
#else
|
||||
@ -1475,4 +1558,3 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
|
||||
}
|
||||
return bestReg.value;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ extern "C" {
|
||||
|
||||
#define SPI_HAS_TRANSACTION
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define FSPI 0
|
||||
#define HSPI 1
|
||||
#else
|
||||
|
@ -44,8 +44,6 @@ static void setTimeZone(long offset, int daylight)
|
||||
/*
|
||||
* configTime
|
||||
* Source: https://github.com/esp8266/Arduino/blob/master/cores/esp8266/time.c
|
||||
* Note: Bundled Arduino lwip supports only ONE ntp server, 2nd and 3rd options are silently ignored
|
||||
* see CONFIG_LWIP_DHCP_MAX_NTP_SERVERS define in ./tools/sdk/esp32/sdkconfig
|
||||
* */
|
||||
void configTime(long gmtOffset_sec, int daylightOffset_sec, const char* server1, const char* server2, const char* server3)
|
||||
{
|
||||
@ -65,8 +63,6 @@ void configTime(long gmtOffset_sec, int daylightOffset_sec, const char* server1,
|
||||
/*
|
||||
* configTzTime
|
||||
* sntp setup using TZ environment variable
|
||||
* Note: Bundled Arduino lwip supports only ONE ntp server, 2nd and 3rd options are silently ignored
|
||||
* see CONFIG_LWIP_DHCP_MAX_NTP_SERVERS define in ./tools/sdk/esp32/sdkconfig
|
||||
* */
|
||||
void configTzTime(const char* tz, const char* server1, const char* server2, const char* server3)
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ bool timerGetAutoReload(hw_timer_t *timer);
|
||||
|
||||
void timerAlarmEnable(hw_timer_t *timer);
|
||||
void timerAlarmDisable(hw_timer_t *timer);
|
||||
void timerAlarmWrite(hw_timer_t *timer, uint64_t interruptAt, bool autoreload);
|
||||
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload);
|
||||
|
||||
bool timerAlarmEnabled(hw_timer_t *timer);
|
||||
uint64_t timerAlarmRead(hw_timer_t *timer);
|
||||
|
@ -34,9 +34,16 @@
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#include "esp32-hal-tinyusb.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/usb/usb_persist.h"
|
||||
#include "esp32s2/rom/usb/usb_dc.h"
|
||||
#include "esp32s2/rom/usb/chip_usb_dw_wrapper.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "hal/usb_serial_jtag_ll.h"
|
||||
#include "esp32s3/rom/usb/usb_persist.h"
|
||||
#include "esp32s3/rom/usb/usb_dc.h"
|
||||
#include "esp32s3/rom/usb/chip_usb_dw_wrapper.h"
|
||||
#endif
|
||||
|
||||
typedef enum{
|
||||
TINYUSB_USBDEV_0,
|
||||
@ -370,6 +377,120 @@ __attribute__ ((weak)) int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_
|
||||
static bool usb_persist_enabled = false;
|
||||
static restart_type_t usb_persist_mode = RESTART_NO_PERSIST;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
|
||||
static void hw_cdc_reset_handler(void *arg) {
|
||||
portBASE_TYPE xTaskWoken = 0;
|
||||
uint32_t usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask();
|
||||
usb_serial_jtag_ll_clr_intsts_mask(usbjtag_intr_status);
|
||||
|
||||
if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_BUS_RESET) {
|
||||
xSemaphoreGiveFromISR((xSemaphoreHandle)arg, &xTaskWoken);
|
||||
}
|
||||
|
||||
if (xTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_switch_to_cdc_jtag(){
|
||||
// Disable USB-OTG
|
||||
periph_module_reset(PERIPH_USB_MODULE);
|
||||
//periph_module_enable(PERIPH_USB_MODULE);
|
||||
periph_module_disable(PERIPH_USB_MODULE);
|
||||
|
||||
// Switch to hardware CDC+JTAG
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_USB_CONF_REG, (RTC_CNTL_SW_HW_USB_PHY_SEL|RTC_CNTL_SW_USB_PHY_SEL|RTC_CNTL_USB_PAD_ENABLE));
|
||||
|
||||
// Do not use external PHY
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PHY_SEL);
|
||||
|
||||
// Release GPIO pins from CDC+JTAG
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
|
||||
|
||||
// Force the host to re-enumerate (BUS_RESET)
|
||||
pinMode(USBPHY_DM_NUM, OUTPUT_OPEN_DRAIN);
|
||||
pinMode(USBPHY_DP_NUM, OUTPUT_OPEN_DRAIN);
|
||||
digitalWrite(USBPHY_DM_NUM, LOW);
|
||||
digitalWrite(USBPHY_DP_NUM, LOW);
|
||||
|
||||
// Initialize CDC+JTAG ISR to listen for BUS_RESET
|
||||
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
|
||||
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
|
||||
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_BUS_RESET);
|
||||
intr_handle_t intr_handle = NULL;
|
||||
xSemaphoreHandle reset_sem = xSemaphoreCreateBinary();
|
||||
if(reset_sem){
|
||||
if(esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, 0, hw_cdc_reset_handler, reset_sem, &intr_handle) != ESP_OK){
|
||||
vSemaphoreDelete(reset_sem);
|
||||
reset_sem = NULL;
|
||||
log_e("HW USB CDC failed to init interrupts");
|
||||
}
|
||||
} else {
|
||||
log_e("reset_sem init failed");
|
||||
}
|
||||
|
||||
// Connect GPIOs to integrated CDC+JTAG
|
||||
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
|
||||
|
||||
// Wait for BUS_RESET to give us back the semaphore
|
||||
if(reset_sem){
|
||||
if(xSemaphoreTake(reset_sem, 1000 / portTICK_PERIOD_MS) != pdPASS){
|
||||
log_e("reset_sem timeout");
|
||||
}
|
||||
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
|
||||
esp_intr_free(intr_handle);
|
||||
vSemaphoreDelete(reset_sem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void IRAM_ATTR usb_persist_shutdown_handler(void)
|
||||
{
|
||||
if(usb_persist_mode != RESTART_NO_PERSIST){
|
||||
if (usb_persist_enabled) {
|
||||
usb_dc_prepare_persist();
|
||||
}
|
||||
if (usb_persist_mode == RESTART_BOOTLOADER) {
|
||||
//USB CDC Download
|
||||
if (usb_persist_enabled) {
|
||||
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
} else {
|
||||
periph_module_reset(PERIPH_USB_MODULE);
|
||||
periph_module_enable(PERIPH_USB_MODULE);
|
||||
#endif
|
||||
}
|
||||
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
|
||||
} else if (usb_persist_mode == RESTART_BOOTLOADER_DFU) {
|
||||
//DFU Download
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
// Reset USB Core
|
||||
USB0.grstctl |= USB_CSFTRST;
|
||||
while ((USB0.grstctl & USB_CSFTRST) == USB_CSFTRST){}
|
||||
#endif
|
||||
chip_usb_set_persist_flags(USBDC_BOOT_DFU);
|
||||
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
|
||||
} else if (usb_persist_enabled) {
|
||||
//USB Persist reboot
|
||||
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usb_persist_restart(restart_type_t mode)
|
||||
{
|
||||
if (mode < RESTART_TYPE_MAX && esp_register_shutdown_handler(usb_persist_shutdown_handler) == ESP_OK) {
|
||||
usb_persist_mode = mode;
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
if (mode == RESTART_BOOTLOADER) {
|
||||
usb_switch_to_cdc_jtag();
|
||||
}
|
||||
#endif
|
||||
esp_restart();
|
||||
}
|
||||
}
|
||||
|
||||
static bool tinyusb_reserve_in_endpoint(uint8_t endpoint){
|
||||
if(endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0){
|
||||
return false;
|
||||
@ -515,35 +636,6 @@ static void tinyusb_apply_device_config(tinyusb_device_config_t *config){
|
||||
tinyusb_device_descriptor.bDeviceProtocol = config->usb_protocol;
|
||||
}
|
||||
|
||||
static void IRAM_ATTR usb_persist_shutdown_handler(void)
|
||||
{
|
||||
if(usb_persist_mode != RESTART_NO_PERSIST){
|
||||
if (usb_persist_enabled) {
|
||||
usb_dc_prepare_persist();
|
||||
}
|
||||
if (usb_persist_mode == RESTART_BOOTLOADER) {
|
||||
//USB CDC Download
|
||||
if (usb_persist_enabled) {
|
||||
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
|
||||
} else {
|
||||
periph_module_reset(PERIPH_USB_MODULE);
|
||||
periph_module_enable(PERIPH_USB_MODULE);
|
||||
}
|
||||
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
|
||||
} else if (usb_persist_mode == RESTART_BOOTLOADER_DFU) {
|
||||
//DFU Download
|
||||
// Reset USB Core
|
||||
USB0.grstctl |= USB_CSFTRST;
|
||||
while ((USB0.grstctl & USB_CSFTRST) == USB_CSFTRST){}
|
||||
chip_usb_set_persist_flags(USBDC_BOOT_DFU);
|
||||
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
|
||||
} else if (usb_persist_enabled) {
|
||||
//USB Persist reboot
|
||||
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// USB Device Driver task
|
||||
// This top level thread processes all usb events and invokes callbacks
|
||||
static void usb_device_task(void *param) {
|
||||
@ -607,11 +699,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
|
||||
periph_module_enable(PERIPH_USB_MODULE);
|
||||
}
|
||||
|
||||
if (esp_register_shutdown_handler(usb_persist_shutdown_handler) != ESP_OK) {
|
||||
tinyusb_is_initialized = false;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
tinyusb_config_t tusb_cfg = {
|
||||
.external_phy = false // In the most cases you need to use a `false` value
|
||||
};
|
||||
@ -624,14 +711,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
|
||||
return err;
|
||||
}
|
||||
|
||||
void usb_persist_restart(restart_type_t mode)
|
||||
{
|
||||
if (mode < RESTART_TYPE_MAX) {
|
||||
usb_persist_mode = mode;
|
||||
esp_restart();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t tinyusb_add_string_descriptor(const char * str){
|
||||
if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){
|
||||
return 0;
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#if CONFIG_TINYUSB_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -105,4 +104,3 @@ uint8_t tinyusb_get_free_out_endpoint(void);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_TINYUSB_ENABLED */
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32S2 */
|
||||
|
@ -12,219 +12,268 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-touch.h"
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_attr.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#if SOC_TOUCH_SENSOR_NUM > 0
|
||||
|
||||
#include "driver/touch_sensor.h"
|
||||
#include "esp32-hal-touch.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_intr.h"
|
||||
#endif
|
||||
/*
|
||||
Internal Private Touch Data Structure and Functions
|
||||
*/
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
static uint16_t __touchSleepCycles = 0x1000;
|
||||
static uint16_t __touchMeasureCycles = 0x1000;
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
static uint16_t __touchSleepCycles = TOUCH_PAD_SLEEP_CYCLE_DEFAULT;
|
||||
static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT;
|
||||
#endif
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
static voidFuncPtr __touchInterruptHandlers[10] = {0,};
|
||||
static intr_handle_t touch_intr_handle = NULL;
|
||||
typedef void (*voidArgFuncPtr)(void *);
|
||||
|
||||
void ARDUINO_ISR_ATTR __touchISR(void * arg)
|
||||
typedef struct {
|
||||
voidFuncPtr fn;
|
||||
bool callWithArgs;
|
||||
void* arg;
|
||||
#if SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
|
||||
bool lastStatusIsPressed;
|
||||
#endif
|
||||
} TouchInterruptHandle_t;
|
||||
|
||||
static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = {0,};
|
||||
|
||||
static void ARDUINO_ISR_ATTR __touchISR(void * arg)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t pad_intr = READ_PERI_REG(SENS_SAR_TOUCH_CTRL2_REG) & 0x3ff;
|
||||
uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG);
|
||||
uint8_t i = 0;
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
uint32_t pad_intr = touch_pad_get_status();
|
||||
//clear interrupt
|
||||
WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, rtc_intr);
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR);
|
||||
|
||||
if (rtc_intr & RTC_CNTL_TOUCH_INT_ST) {
|
||||
for (i = 0; i < 10; ++i) {
|
||||
if ((pad_intr >> i) & 0x01) {
|
||||
if(__touchInterruptHandlers[i]){
|
||||
__touchInterruptHandlers[i]();
|
||||
touch_pad_clear_status();
|
||||
// call Pad ISR User callback
|
||||
for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||
if ((pad_intr >> i) & 0x01) {
|
||||
if(__touchInterruptHandlers[i].fn){
|
||||
// keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)"
|
||||
if (__touchInterruptHandlers[i].callWithArgs) {
|
||||
((voidArgFuncPtr)__touchInterruptHandlers[i].fn)(__touchInterruptHandlers[i].arg);
|
||||
} else {
|
||||
__touchInterruptHandlers[i].fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
touch_pad_intr_mask_t evt = touch_pad_read_intr_status_mask();
|
||||
uint8_t pad_num = touch_pad_get_current_meas_channel();
|
||||
if (evt & TOUCH_PAD_INTR_MASK_ACTIVE) {
|
||||
// touch has been pressed / touched
|
||||
__touchInterruptHandlers[pad_num].lastStatusIsPressed = true;
|
||||
}
|
||||
if (evt & TOUCH_PAD_INTR_MASK_INACTIVE) {
|
||||
// touch has been released / untouched
|
||||
__touchInterruptHandlers[pad_num].lastStatusIsPressed = false;
|
||||
}
|
||||
if(__touchInterruptHandlers[pad_num].fn){
|
||||
// keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)"
|
||||
if (__touchInterruptHandlers[pad_num].callWithArgs) {
|
||||
((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg);
|
||||
} else {
|
||||
__touchInterruptHandlers[pad_num].fn();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void __touchSetCycles(uint16_t measure, uint16_t sleep)
|
||||
|
||||
|
||||
static void __touchSetCycles(uint16_t measure, uint16_t sleep)
|
||||
{
|
||||
__touchSleepCycles = sleep;
|
||||
__touchMeasureCycles = measure;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//Touch pad SleepCycle Time
|
||||
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_SLEEP_CYCLES, __touchSleepCycles, SENS_TOUCH_SLEEP_CYCLES_S);
|
||||
//Touch Pad Measure Time
|
||||
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_MEAS_DELAY, __touchMeasureCycles, SENS_TOUCH_MEAS_DELAY_S);
|
||||
#else
|
||||
touch_pad_set_meas_time(sleep, measure);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __touchInit()
|
||||
|
||||
|
||||
static void __touchInit()
|
||||
{
|
||||
static bool initialized = false;
|
||||
if(initialized){
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS, 1, RTC_IO_TOUCH_XPD_BIAS_S);
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR);
|
||||
//clear touch enable
|
||||
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, 0x0);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_TOUCH_SLP_TIMER_EN);
|
||||
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles);
|
||||
esp_intr_alloc(ETS_RTC_CORE_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, __touchISR, NULL, &touch_intr_handle);
|
||||
#else
|
||||
touch_pad_init();
|
||||
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V5);
|
||||
touch_pad_set_idle_channel_connect(TOUCH_PAD_CONN_GND);
|
||||
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles);
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
err = touch_pad_init();
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
// the next two lines will drive the touch reading values -- both will return ESP_OK
|
||||
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V);
|
||||
touch_pad_set_meas_time(__touchMeasureCycles, __touchSleepCycles);
|
||||
// Touch Sensor Timer initiated
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK
|
||||
err = touch_pad_filter_start(10);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
// keep ISR activated - it can run all together (ISR + touchRead())
|
||||
err = touch_pad_isr_register(__touchISR, NULL);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
touch_pad_intr_enable(); // returns ESP_OK
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
err = touch_pad_init();
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
// the next lines will drive the touch reading values -- all os them return ESP_OK
|
||||
touch_pad_set_meas_time(__touchSleepCycles, __touchMeasureCycles);
|
||||
touch_pad_set_voltage(TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD);
|
||||
touch_pad_set_idle_channel_connect(TOUCH_PAD_IDLE_CH_CONNECT_DEFAULT);
|
||||
touch_pad_denoise_t denoise = {
|
||||
.grade = TOUCH_PAD_DENOISE_BIT4,
|
||||
.cap_level = TOUCH_PAD_DENOISE_CAP_L4,
|
||||
};
|
||||
touch_pad_denoise_set_config(&denoise);
|
||||
touch_pad_denoise_enable();
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
||||
touch_pad_fsm_start();
|
||||
// Touch Sensor Timer initiated
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK
|
||||
touch_pad_fsm_start(); // returns ESP_OK
|
||||
//ISR setup moved to __touchChannelInit
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
return;
|
||||
err:
|
||||
log_e(" Touch sensor initialization error.");
|
||||
initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t __touchRead(uint8_t pin)
|
||||
static void __touchChannelInit(int pad)
|
||||
{
|
||||
static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = { false };
|
||||
if(channels_initialized[pad]){
|
||||
return;
|
||||
}
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
// Initial no Threshold and setup
|
||||
__touchInterruptHandlers[pad].fn = NULL;
|
||||
touch_pad_config(pad, SOC_TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
// Initial no Threshold and setup
|
||||
__touchInterruptHandlers[pad].fn = NULL;
|
||||
touch_pad_config(pad); // returns ESP_OK
|
||||
// keep ISR activated - it can run all together (ISR + touchRead())
|
||||
esp_err_t err = touch_pad_isr_register(__touchISR, NULL, TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE);
|
||||
if (err != ESP_OK) {
|
||||
log_e(" Touch sensor initialization error.");
|
||||
return;
|
||||
}
|
||||
touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); // returns ESP_OK
|
||||
#endif
|
||||
|
||||
channels_initialized[pad] = true;
|
||||
delay(20); //delay needed before reading from touch channel after config
|
||||
}
|
||||
|
||||
static touch_value_t __touchRead(uint8_t pin)
|
||||
{
|
||||
int8_t pad = digitalPinToTouchChannel(pin);
|
||||
if(pad < 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
pinMode(pin, ANALOG);
|
||||
|
||||
__touchInit();
|
||||
__touchChannelInit(pad);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
|
||||
//Disable Intr & enable touch pad
|
||||
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG,
|
||||
(v0 & ~((1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | (1 << (pad + SENS_TOUCH_PAD_OUTEN1_S))))
|
||||
| (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
|
||||
touch_value_t touch_value;
|
||||
touch_pad_read_raw_data(pad, &touch_value);
|
||||
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
|
||||
|
||||
uint32_t rtc_tio_reg = RTC_IO_TOUCH_PAD0_REG + pad * 4;
|
||||
WRITE_PERI_REG(rtc_tio_reg, (READ_PERI_REG(rtc_tio_reg)
|
||||
& ~(RTC_IO_TOUCH_PAD0_DAC_M))
|
||||
| (7 << RTC_IO_TOUCH_PAD0_DAC_S)//Touch Set Slope
|
||||
| RTC_IO_TOUCH_PAD0_TIE_OPT_M //Enable Tie,Init Level
|
||||
| RTC_IO_TOUCH_PAD0_START_M //Enable Touch Pad IO
|
||||
| RTC_IO_TOUCH_PAD0_XPD_M); //Enable Touch Pad Power on
|
||||
|
||||
//force oneTime test start
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
|
||||
|
||||
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_XPD_WAIT, 10, SENS_TOUCH_XPD_WAIT_S);
|
||||
|
||||
while (GET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_DONE) == 0) {};
|
||||
|
||||
uint16_t touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (pad / 2) * 4) >> ((pad & 1) ? SENS_TOUCH_MEAS_OUT1_S : SENS_TOUCH_MEAS_OUT0_S);
|
||||
|
||||
//clear touch force ,select the Touch mode is Timer
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
|
||||
|
||||
//restore previous value
|
||||
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0);
|
||||
return touch_value;
|
||||
#else
|
||||
static uint32_t chan_mask = 0;
|
||||
uint32_t value = 0;
|
||||
if((chan_mask & (1 << pad)) == 0){
|
||||
if(touch_pad_set_thresh((touch_pad_t)pad, TOUCH_PAD_THRESHOLD_MAX) != ESP_OK){
|
||||
log_e("touch_pad_set_thresh failed");
|
||||
} else if(touch_pad_config((touch_pad_t)pad) != ESP_OK){
|
||||
log_e("touch_pad_config failed");
|
||||
} else {
|
||||
chan_mask |= (1 << pad);
|
||||
}
|
||||
}
|
||||
if((chan_mask & (1 << pad)) != 0) {
|
||||
if(touch_pad_read_raw_data((touch_pad_t)pad, &value) != ESP_OK){
|
||||
log_e("touch_pad_read_raw_data failed");
|
||||
}
|
||||
}
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold)
|
||||
static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Args, touch_value_t threshold, bool callWithArgs)
|
||||
{
|
||||
int8_t pad = digitalPinToTouchChannel(pin);
|
||||
if(pad < 0){
|
||||
return;
|
||||
}
|
||||
|
||||
pinMode(pin, ANALOG);
|
||||
|
||||
__touchInit();
|
||||
|
||||
__touchInterruptHandlers[pad] = userFunc;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//clear touch force ,select the Touch mode is Timer
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
|
||||
|
||||
//interrupt when touch value < threshold
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL);
|
||||
//Intr will give ,when SET0 < threshold
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_1EN);
|
||||
//Enable Rtc Touch Module Intr,the Interrupt need Rtc out Enable
|
||||
SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_TOUCH_INT_ENA);
|
||||
|
||||
//set threshold
|
||||
uint8_t shift = (pad & 1) ? SENS_TOUCH_OUT_TH1_S : SENS_TOUCH_OUT_TH0_S;
|
||||
SET_PERI_REG_BITS((SENS_SAR_TOUCH_THRES1_REG + (pad / 2) * 4), SENS_TOUCH_OUT_TH0, threshold, shift);
|
||||
|
||||
uint32_t rtc_tio_reg = RTC_IO_TOUCH_PAD0_REG + pad * 4;
|
||||
WRITE_PERI_REG(rtc_tio_reg, (READ_PERI_REG(rtc_tio_reg)
|
||||
& ~(RTC_IO_TOUCH_PAD0_DAC_M))
|
||||
| (7 << RTC_IO_TOUCH_PAD0_DAC_S)//Touch Set Slope
|
||||
| RTC_IO_TOUCH_PAD0_TIE_OPT_M //Enable Tie,Init Level
|
||||
| RTC_IO_TOUCH_PAD0_START_M //Enable Touch Pad IO
|
||||
| RTC_IO_TOUCH_PAD0_XPD_M); //Enable Touch Pad Power on
|
||||
|
||||
//Enable Digital rtc control :work mode and out mode
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG,
|
||||
(1 << (pad + SENS_TOUCH_PAD_WORKEN_S)) | \
|
||||
(1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | \
|
||||
(1 << (pad + SENS_TOUCH_PAD_OUTEN1_S)));
|
||||
#else
|
||||
if (userFunc == NULL) {
|
||||
// dettach ISR User Call
|
||||
__touchInterruptHandlers[pad].fn = NULL;
|
||||
threshold = SOC_TOUCH_PAD_THRESHOLD_MAX; // deactivate the ISR with SOC_TOUCH_PAD_THRESHOLD_MAX
|
||||
} else {
|
||||
// attach ISR User Call
|
||||
__touchInit();
|
||||
#if SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
__touchChannelInit(pad);
|
||||
#endif
|
||||
__touchInterruptHandlers[pad].fn = userFunc;
|
||||
__touchInterruptHandlers[pad].callWithArgs = callWithArgs;
|
||||
__touchInterruptHandlers[pad].arg = Args;
|
||||
}
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
touch_pad_config(pad, threshold);
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
touch_pad_set_thresh(pad, threshold);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern uint16_t touchRead(uint8_t pin) __attribute__ ((weak, alias("__touchRead")));
|
||||
extern void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold) __attribute__ ((weak, alias("__touchAttachInterrupt")));
|
||||
extern void touchSetCycles(uint16_t measure, uint16_t sleep) __attribute__ ((weak, alias("__touchSetCycles")));
|
||||
// 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 dettach touch ISR
|
||||
static void __touchDettachInterrupt(uint8_t pin)
|
||||
{
|
||||
__touchConfigInterrupt(pin, NULL, NULL, 0, false); // userFunc as NULL acts as dettaching
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
External Public Touch API Functions
|
||||
*/
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
|
||||
void touchInterruptSetThresholdDirection(bool mustbeLower) {
|
||||
if (mustbeLower) {
|
||||
touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW);
|
||||
} else {
|
||||
touch_pad_set_trigger_mode(TOUCH_TRIGGER_ABOVE);
|
||||
}
|
||||
}
|
||||
#elif SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
|
||||
// returns true if touch pad has been and continues pressed and false otherwise
|
||||
bool touchInterruptGetLastStatus(uint8_t pin) {
|
||||
int8_t pad = digitalPinToTouchChannel(pin);
|
||||
if(pad < 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
return __touchInterruptHandlers[pad].lastStatusIsPressed;
|
||||
}
|
||||
#endif
|
||||
|
||||
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")));
|
||||
extern void touchSetCycles(uint16_t, uint16_t) __attribute__ ((weak, alias("__touchSetCycles")));
|
||||
|
||||
#endif // #if SOC_TOUCH_SENSOR_NUM > 0
|
||||
|
@ -24,8 +24,21 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#if SOC_TOUCH_SENSOR_NUM > 0
|
||||
|
||||
#if !defined(SOC_TOUCH_VERSION_1) && !defined(SOC_TOUCH_VERSION_2)
|
||||
#error Touch IDF driver Not supported!
|
||||
#endif
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
typedef uint16_t touch_value_t;
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2 ESP32S3
|
||||
typedef uint32_t touch_value_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set cycles that measurement operation takes
|
||||
* The result from touchRead, threshold and detection
|
||||
@ -40,17 +53,44 @@ void touchSetCycles(uint16_t measure, uint16_t sleep);
|
||||
* You can use this method to chose a good threshold value
|
||||
* to use as value for touchAttachInterrupt
|
||||
* */
|
||||
uint16_t touchRead(uint8_t pin);
|
||||
touch_value_t touchRead(uint8_t pin);
|
||||
|
||||
/*
|
||||
* Set function to be called if touch pad value falls
|
||||
* below the given threshold. Use touchRead to determine
|
||||
* a proper threshold between touched and untouched state
|
||||
* Set function to be called if touch pad value falls (ESP32)
|
||||
* below the given threshold / rises (ESP32-S2/S3) by given increment (threshold).
|
||||
* Use touchRead to determine a proper threshold between touched and untouched state
|
||||
* */
|
||||
void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold);
|
||||
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);
|
||||
|
||||
/*
|
||||
* Specific functions to ESP32
|
||||
* Tells the driver if it shall activate the ISR if the sensor is Lower or Higher than the Threshold
|
||||
* Default if Lower.
|
||||
**/
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
|
||||
void touchInterruptSetThresholdDirection(bool mustbeLower);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Specific functions to ESP32-S2 and ESP32-S3
|
||||
* 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
|
||||
**/
|
||||
|
||||
#if SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
|
||||
// returns true if touch pad has been and continues pressed and false otherwise
|
||||
bool touchInterruptGetLastStatus(uint8_t pin);
|
||||
#endif
|
||||
|
||||
#endif // SOC_TOUCH_SENSOR_NUM > 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */
|
||||
|
@ -34,7 +34,7 @@ struct uart_struct_t {
|
||||
uint8_t num;
|
||||
bool has_peek;
|
||||
uint8_t peek_byte;
|
||||
|
||||
QueueHandle_t uart_event_queue; // export it by some uartGetEventQueue() function
|
||||
};
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
@ -43,12 +43,12 @@ struct uart_struct_t {
|
||||
#define UART_MUTEX_UNLOCK()
|
||||
|
||||
static uart_t _uart_bus_array[] = {
|
||||
{0, false, 0},
|
||||
{0, false, 0, NULL},
|
||||
#if SOC_UART_NUM > 1
|
||||
{1, false, 0},
|
||||
{1, false, 0, NULL},
|
||||
#endif
|
||||
#if SOC_UART_NUM > 2
|
||||
{2, false, 0},
|
||||
{2, false, 0, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -58,12 +58,12 @@ static uart_t _uart_bus_array[] = {
|
||||
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
|
||||
|
||||
static uart_t _uart_bus_array[] = {
|
||||
{NULL, 0, false, 0},
|
||||
{NULL, 0, false, 0, NULL},
|
||||
#if SOC_UART_NUM > 1
|
||||
{NULL, 1, false, 0},
|
||||
{NULL, 1, false, 0, NULL},
|
||||
#endif
|
||||
#if SOC_UART_NUM > 2
|
||||
{NULL, 2, false, 0},
|
||||
{NULL, 2, false, 0, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -82,10 +82,22 @@ uint32_t _get_effective_baudrate(uint32_t baudrate)
|
||||
}
|
||||
}
|
||||
|
||||
// Routines that take care of UART events will be in the HardwareSerial Class code
|
||||
void uartGetEventQueue(uart_t* uart, QueueHandle_t *q)
|
||||
{
|
||||
// passing back NULL for the Queue pointer when UART is not initialized yet
|
||||
*q = NULL;
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
*q = uart->uart_event_queue;
|
||||
return;
|
||||
}
|
||||
|
||||
bool uartIsDriverInstalled(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uart_is_driver_installed(uart->num)) {
|
||||
@ -94,28 +106,36 @@ bool uartIsDriverInstalled(uart_t* uart)
|
||||
return false;
|
||||
}
|
||||
|
||||
void uartSetPins(uart_t* uart, uint8_t rxPin, uint8_t txPin)
|
||||
// Valid pin UART_PIN_NO_CHANGE is defined to (-1)
|
||||
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
|
||||
void uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
|
||||
{
|
||||
if(uart == NULL || rxPin >= SOC_GPIO_PIN_COUNT || txPin >= SOC_GPIO_PIN_COUNT) {
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
ESP_ERROR_CHECK(uart_set_pin(uart->num, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
// IDF uart_set_pin() will issue necessary Error Message and take care of all GPIO Number validation.
|
||||
uart_set_pin(uart->num, txPin, rxPin, ctsPin, rtsPin);
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
//
|
||||
void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold) {
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
// IDF will issue corresponding error message when mode or threshold are wrong and prevent crashing
|
||||
// IDF will check (mode > HW_FLOWCTRL_CTS_RTS || threshold >= SOC_UART_FIFO_LEN)
|
||||
uart_set_hw_flow_ctrl(uart->num, (uart_hw_flowcontrol_t) mode, threshold);
|
||||
}
|
||||
|
||||
|
||||
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted, uint8_t rxfifo_full_thrhd)
|
||||
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t rx_buffer_size, uint16_t tx_buffer_size, bool inverted, uint8_t rxfifo_full_thrhd)
|
||||
{
|
||||
if(uart_nr >= SOC_UART_NUM) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(rxPin == -1 && txPin == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uart_t* uart = &_uart_bus_array[uart_nr];
|
||||
|
||||
if (uart_is_driver_installed(uart_nr)) {
|
||||
@ -143,7 +163,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
uart_config.source_clk = UART_SCLK_APB;
|
||||
|
||||
|
||||
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 0, NULL, 0));
|
||||
ESP_ERROR_CHECK(uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0));
|
||||
ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config));
|
||||
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
|
||||
@ -153,9 +173,6 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
ESP_ERROR_CHECK(uart_set_line_inverse(uart_nr, UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV));
|
||||
}
|
||||
|
||||
// Set RS485 half duplex mode on UART. This shall force flush to wait up to sending all bits out
|
||||
ESP_ERROR_CHECK(uart_set_mode(uart_nr, UART_MODE_RS485_HALF_DUPLEX));
|
||||
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
uartFlush(uart);
|
||||
@ -306,7 +323,7 @@ void uartFlushTxOnly(uart_t* uart, bool txOnly)
|
||||
}
|
||||
|
||||
UART_MUTEX_LOCK();
|
||||
ESP_ERROR_CHECK(uart_wait_tx_done(uart->num, portMAX_DELAY));
|
||||
while(!uart_ll_is_tx_idle(UART_LL_GET_HW(uart->num)));
|
||||
|
||||
if ( !txOnly ) {
|
||||
ESP_ERROR_CHECK(uart_flush_input(uart->num));
|
||||
@ -404,11 +421,12 @@ int log_printf(const char *format, ...)
|
||||
va_list copy;
|
||||
va_start(arg, format);
|
||||
va_copy(copy, arg);
|
||||
len = vsnprintf(NULL, 0, format, arg);
|
||||
len = vsnprintf(NULL, 0, format, copy);
|
||||
va_end(copy);
|
||||
if(len >= sizeof(loc_buf)){
|
||||
temp = (char*)malloc(len+1);
|
||||
if(temp == NULL) {
|
||||
va_end(arg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -470,6 +488,7 @@ void log_print_buf(const uint8_t *b, size_t len){
|
||||
*/
|
||||
unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
|
||||
{
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32S3
|
||||
if(uart == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@ -487,6 +506,9 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -531,7 +553,7 @@ void uartStartDetectBaudrate(uart_t *uart) {
|
||||
//hw->rx_filt.glitch_filt_en = 1;
|
||||
//hw->conf0.autobaud_en = 0;
|
||||
//hw->conf0.autobaud_en = 1;
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#else
|
||||
hw->auto_baud.glitch_filt = 0x08;
|
||||
hw->auto_baud.en = 0;
|
||||
@ -568,6 +590,7 @@ uartDetectBaudrate(uart_t *uart)
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
//hw->conf0.autobaud_en = 0;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#else
|
||||
hw->auto_baud.en = 0;
|
||||
#endif
|
||||
|
@ -22,6 +22,8 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#define SERIAL_5N1 0x8000010
|
||||
#define SERIAL_6N1 0x8000014
|
||||
@ -48,12 +50,23 @@ extern "C" {
|
||||
#define SERIAL_7O2 0x800003b
|
||||
#define SERIAL_8O2 0x800003f
|
||||
|
||||
// These are Hardware Flow Contol possible usage
|
||||
// equivalent to UDF enum uart_hw_flowcontrol_t from
|
||||
// https://github.com/espressif/esp-idf/blob/master/components/hal/include/hal/uart_types.h#L75-L81
|
||||
#define HW_FLOWCTRL_DISABLE 0x0 // disable HW Flow Control
|
||||
#define HW_FLOWCTRL_RTS 0x1 // use only RTS PIN for HW Flow Control
|
||||
#define HW_FLOWCTRL_CTS 0x2 // use only CTS PIN for HW Flow Control
|
||||
#define HW_FLOWCTRL_CTS_RTS 0x3 // use both CTS and RTS PIN for HW Flow Control
|
||||
|
||||
struct uart_struct_t;
|
||||
typedef struct uart_struct_t uart_t;
|
||||
|
||||
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted, uint8_t rxfifo_full_thrhd);
|
||||
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t rx_buffer_size, uint16_t tx_buffer_size, bool inverted, uint8_t rxfifo_full_thrhd);
|
||||
void uartEnd(uart_t* uart);
|
||||
|
||||
// This is used to retrieve the Event Queue pointer from a UART IDF Driver in order to allow user to deal with its events
|
||||
void uartGetEventQueue(uart_t* uart, QueueHandle_t *q);
|
||||
|
||||
uint32_t uartAvailable(uart_t* uart);
|
||||
uint32_t uartAvailableForWrite(uart_t* uart);
|
||||
uint8_t uartRead(uart_t* uart);
|
||||
@ -74,7 +87,12 @@ void uartSetDebug(uart_t* uart);
|
||||
int uartGetDebug();
|
||||
|
||||
bool uartIsDriverInstalled(uart_t* uart);
|
||||
void uartSetPins(uart_t* uart, uint8_t rxPin, uint8_t txPin);
|
||||
|
||||
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
|
||||
void uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin);
|
||||
|
||||
// Enables or disables HW Flow Control function -- needs also to set CTS and/or RTS pins
|
||||
void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold);
|
||||
|
||||
void uartStartDetectBaudrate(uart_t *uart);
|
||||
unsigned long uartDetectBaudrate(uart_t *uart);
|
||||
|
@ -95,6 +95,9 @@ void analogWrite(uint8_t pin, int value);
|
||||
//returns chip temperature in Celsius
|
||||
float temperatureRead();
|
||||
|
||||
//allows user to bypass SPI RAM test routine
|
||||
bool testSPIRAM(void);
|
||||
|
||||
#if CONFIG_AUTOSTART_ARDUINO
|
||||
//enable/disable WDT for Arduino's setup and loop functions
|
||||
void enableLoopWDT();
|
||||
|
@ -23,7 +23,7 @@ extern "C" {
|
||||
/** Minor version number (x.X.x) */
|
||||
#define ESP_ARDUINO_VERSION_MINOR 0
|
||||
/** Patch version number (x.x.X) */
|
||||
#define ESP_ARDUINO_VERSION_PATCH 0
|
||||
#define ESP_ARDUINO_VERSION_PATCH 3
|
||||
|
||||
/**
|
||||
* Macro to convert ARDUINO version number into an integer
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "freertos/task.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "Arduino.h"
|
||||
#if (ARDUINO_USB_CDC_ON_BOOT|ARDUINO_USB_MSC_ON_BOOT|ARDUINO_USB_DFU_ON_BOOT)
|
||||
#if (ARDUINO_USB_CDC_ON_BOOT|ARDUINO_USB_MSC_ON_BOOT|ARDUINO_USB_DFU_ON_BOOT) && !ARDUINO_USB_MODE
|
||||
#include "USB.h"
|
||||
#if ARDUINO_USB_MSC_ON_BOOT
|
||||
#include "FirmwareMSC.h"
|
||||
@ -54,16 +54,16 @@ void loopTask(void *pvParameters)
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
#if ARDUINO_USB_CDC_ON_BOOT
|
||||
#if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE
|
||||
Serial.begin();
|
||||
#endif
|
||||
#if ARDUINO_USB_MSC_ON_BOOT
|
||||
#if ARDUINO_USB_MSC_ON_BOOT && !ARDUINO_USB_MODE
|
||||
MSC_Update.begin();
|
||||
#endif
|
||||
#if ARDUINO_USB_DFU_ON_BOOT
|
||||
#if ARDUINO_USB_DFU_ON_BOOT && !ARDUINO_USB_MODE
|
||||
USB.enableDFU();
|
||||
#endif
|
||||
#if ARDUINO_USB_ON_BOOT
|
||||
#if ARDUINO_USB_ON_BOOT && !ARDUINO_USB_MODE
|
||||
USB.begin();
|
||||
#endif
|
||||
loopTaskWDTEnabled = false;
|
||||
|
@ -88,7 +88,7 @@ char* ultoa(unsigned long value, char* result, int base) {
|
||||
return result;
|
||||
}
|
||||
|
||||
char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
|
||||
char * dtostrf(double number, signed int width, unsigned int prec, char *s) {
|
||||
bool negative = false;
|
||||
|
||||
if (isnan(number)) {
|
||||
@ -117,7 +117,7 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
|
||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||
// I optimized out most of the divisions
|
||||
double rounding = 2.0;
|
||||
for (uint8_t i = 0; i < prec; ++i)
|
||||
for (uint32_t i = 0; i < prec; ++i)
|
||||
rounding *= 10.0;
|
||||
rounding = 1.0 / rounding;
|
||||
|
||||
|
@ -39,7 +39,7 @@ char* utoa (unsigned int val, char *s, int radix);
|
||||
|
||||
char* ultoa (unsigned long val, char *s, int radix);
|
||||
|
||||
char* dtostrf (double val, signed char width, unsigned char prec, char *s);
|
||||
char* dtostrf (double val, signed int width, unsigned int prec, char *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
@ -1,47 +0,0 @@
|
||||
Make your question, not a Statement, inclusive. Include all pertinent information:
|
||||
|
||||
What you are trying to do
|
||||
Describe your system (Hardware, computer, O/S, core version, environment)
|
||||
Describe what is failing
|
||||
Show the shortest possible code that will duplicate the error
|
||||
Show the EXACT error message (it doesn't work is not enough)
|
||||
Then if someone is interested and knowledgeable you might get a answer. All of this work on your part shows us that you have worked to solve YOUR problem. The more complete your issue posting is, the more likely someone will volunteer their time to help you.
|
||||
|
||||
If you have a Guru Meditation Error or Backtrace, ***please decode it***:
|
||||
[ExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder)
|
||||
|
||||
----------------------------- Remove above -----------------------------
|
||||
|
||||
|
||||
### Hardware:
|
||||
|||||||
|
||||
|:---|---|---|---|---|---|
|
||||
|<B>Board</B>|ESP32 Dev Module|node32|ttgo_lora|ESP32-S2-Saola|Custom w/ ESP32-S2-WROVER 16MB|
|
||||
|<B>Version/Date</B>|1.0.4|2.0.0|0badbeef|11/jul/2017|today's master|
|
||||
|<B>IDE name</B>|Arduino IDE|Atom + Platform.io|IDF component|VSCode|
|
||||
|<B>Flash Frequency</B>|40Mhz|80Mhz|
|
||||
|<B>PSRAM enabled</B>|yes|no|
|
||||
|<B>Upload Speed</B>|115200|
|
||||
|<B>Computer OS</B>|Windows 10|Mac OSX|Ubuntu|
|
||||
|
||||
### Description:
|
||||
Describe your problem here
|
||||
|
||||
|
||||
### Sketch: (leave the backquotes for [code formatting](https://help.github.com/articles/creating-and-highlighting-code-blocks/))
|
||||
```cpp
|
||||
|
||||
//Change the code below by your sketch
|
||||
#include <Arduino.h>
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
```
|
||||
|
||||
### Debug Messages:
|
||||
```
|
||||
Enable Core debug level: Debug on tools menu of Arduino IDE, then put the serial output here
|
||||
```
|
@ -3,3 +3,4 @@
|
||||
#
|
||||
# matplotlib is currently required only by the script generate_chart.py
|
||||
sphinx-copybutton==0.3.0
|
||||
sphinx-tabs==3.2.0
|
BIN
docs/source/_static/logo_arduino.png
Normal file
BIN
docs/source/_static/logo_arduino.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
docs/source/_static/logo_pio.png
Normal file
BIN
docs/source/_static/logo_pio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
docs/source/_static/usb_msc_drive.png
Normal file
BIN
docs/source/_static/usb_msc_drive.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
208
docs/source/api/adc.rst
Normal file
208
docs/source/api/adc.rst
Normal file
@ -0,0 +1,208 @@
|
||||
###
|
||||
ADC
|
||||
###
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
ADC (analog to digital converter) is a very common peripheral used to convert an analog signal such as voltage
|
||||
to a digital form so that it can be read and processed by a microcontroller.
|
||||
|
||||
ADCs are very useful in control and monitoring applications since most sensors
|
||||
(e.g., temperature, pressure, force) produce analogue output voltages.
|
||||
|
||||
.. note:: Each SoC or module has a different number of ADC's with a different number of channels and pins availible. Refer to datasheet of each board for more info.
|
||||
|
||||
Arduino-ESP32 ADC API
|
||||
---------------------
|
||||
|
||||
ADC common API
|
||||
**************
|
||||
|
||||
analogRead
|
||||
^^^^^^^^^^
|
||||
|
||||
This function is used to get the ADC raw value for a given pin/ADC channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint16_t analogRead(uint8_t pin);
|
||||
|
||||
* ``pin`` GPIO pin to read analog value
|
||||
|
||||
This function will return analog raw value.
|
||||
|
||||
analogReadMillivolts
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to get ADC value for a given pin/ADC channel in millivolts.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint32_t analogReadMilliVolts(uint8_t pin);
|
||||
|
||||
* ``pin`` GPIO pin to read analog value
|
||||
|
||||
This function will return analog value in millivolts.
|
||||
|
||||
analogReadResolution
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to set the resolution of ``analogRead`` return value. Default is 12 bits (range from 0 to 4096)
|
||||
for all chips except ESP32S3 where default is 13 bits (range from 0 to 8192).
|
||||
When different resolution is set, the values read will be shifted to match the given resolution.
|
||||
|
||||
Range is 1 - 16 .The default value will be used, if this function is not used.
|
||||
|
||||
.. note:: For the ESP32, the resolution is between 9 to12 and it will change the ADC hardware resolution. Else value will be shifted.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void analogReadResolution(uint8_t bits);
|
||||
|
||||
* ``bits`` sets analog read resolution
|
||||
|
||||
analogSetClockDiv
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to set the divider for the ADC clock.
|
||||
|
||||
Range is 1 - 255. Default value is 1.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void analogSetClockDiv(uint8_t clockDiv);
|
||||
|
||||
* ``clockDiv`` sets the divider for ADC clock.
|
||||
|
||||
analogSetAttenuation
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to set the attenuation for all channels.
|
||||
|
||||
Input voltages can be attenuated before being input to the ADCs.
|
||||
There are 4 available attenuation options, the higher the attenuation is, the higher the measurable input voltage could be.
|
||||
|
||||
The measurable input voltage differs for each chip, see table below for detailed information.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. tab:: ESP32
|
||||
|
||||
===================== ===========================================
|
||||
Attenuation Measurable input voltage range
|
||||
===================== ===========================================
|
||||
``ADC_ATTEN_DB_0`` 100 mV ~ 950 mV
|
||||
``ADC_ATTEN_DB_2_5`` 100 mV ~ 1250 mV
|
||||
``ADC_ATTEN_DB_6`` 150 mV ~ 1750 mV
|
||||
``ADC_ATTEN_DB_11`` 150 mV ~ 2450 mV
|
||||
===================== ===========================================
|
||||
|
||||
.. tab:: ESP32-S2
|
||||
|
||||
===================== ===========================================
|
||||
Attenuation Measurable input voltage range
|
||||
===================== ===========================================
|
||||
``ADC_ATTEN_DB_0`` 0 mV ~ 750 mV
|
||||
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1050 mV
|
||||
``ADC_ATTEN_DB_6`` 0 mV ~ 1300 mV
|
||||
``ADC_ATTEN_DB_11`` 0 mV ~ 2500 mV
|
||||
===================== ===========================================
|
||||
|
||||
.. tab:: ESP32-C3
|
||||
|
||||
===================== ===========================================
|
||||
Attenuation Measurable input voltage range
|
||||
===================== ===========================================
|
||||
``ADC_ATTEN_DB_0`` 0 mV ~ 750 mV
|
||||
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1050 mV
|
||||
``ADC_ATTEN_DB_6`` 0 mV ~ 1300 mV
|
||||
``ADC_ATTEN_DB_11`` 0 mV ~ 2500 mV
|
||||
===================== ===========================================
|
||||
|
||||
.. tab:: ESP32-S3
|
||||
|
||||
===================== ===========================================
|
||||
Attenuation Measurable input voltage range
|
||||
===================== ===========================================
|
||||
``ADC_ATTEN_DB_0`` 0 mV ~ 950 mV
|
||||
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1250 mV
|
||||
``ADC_ATTEN_DB_6`` 0 mV ~ 1750 mV
|
||||
``ADC_ATTEN_DB_11`` 0 mV ~ 3100 mV
|
||||
===================== ===========================================
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void analogSetAttenuation(adc_attenuation_t attenuation);
|
||||
|
||||
* ``attenuation`` sets the attenuation.
|
||||
|
||||
analogSetPinAttenuation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to set the attenuation for a specific pin/ADC channel. For more information refer to `analogSetAttenuation`_.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation);
|
||||
|
||||
* ``pin`` selects specific pin for attenuation settings.
|
||||
* ``attenuation`` sets the attenuation.
|
||||
|
||||
adcAttachPin
|
||||
^^^^^^^^^^^^
|
||||
|
||||
This function is used to attach the pin to ADC (it will also clear any other analog mode that could be on)
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool adcAttachPin(uint8_t pin);
|
||||
|
||||
This function will return ``true`` if configuration is successful. Else returns ``false``.
|
||||
|
||||
ADC API specific for ESP32 chip
|
||||
*******************************
|
||||
|
||||
analogSetWidth
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to set the hardware sample bits and read resolution.
|
||||
Default is 12bit (0 - 4095).
|
||||
Range is 9 - 12.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void analogSetWidth(uint8_t bits);
|
||||
|
||||
analogSetVRefPin
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to set pin to use for ADC calibration if the esp is not already calibrated (pins 25, 26 or 27).
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void analogSetVRefPin(uint8_t pin);
|
||||
|
||||
* ``pin`` GPIO pin to set VRefPin for ADC calibration
|
||||
|
||||
hallRead
|
||||
^^^^^^^^
|
||||
|
||||
This function is used to get the ADC value of the HALL sensor conneted to pins 36(SVP) and 39(SVN).
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int hallRead();
|
||||
|
||||
This function will return the hall sensor value.
|
||||
|
||||
|
||||
Example Applications
|
||||
********************
|
||||
|
||||
Here is an example of how to use the ADC.
|
||||
|
||||
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogRead/AnalogRead.ino
|
||||
:language: arduino
|
||||
|
||||
Or you can run Arduino example 01.Basics -> AnalogReadSerial.
|
47
docs/source/api/dac.rst
Normal file
47
docs/source/api/dac.rst
Normal file
@ -0,0 +1,47 @@
|
||||
###
|
||||
DAC
|
||||
###
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
DAC (digital to analog converter) is a very common peripheral used to convert a digital signal to an
|
||||
analog form.
|
||||
|
||||
ESP32 and ESP32-S2 have two 8-bit DAC channels. The DAC driver allows these channels to be set to arbitrary voltages.
|
||||
|
||||
DACs can be used for generating a specific (and dynamic) reference voltage for external sensors,
|
||||
controlling transistors, etc.
|
||||
|
||||
========= ========= =========
|
||||
ESP32 SoC DAC_1 pin DAC_2 pin
|
||||
========= ========= =========
|
||||
ESP32 GPIO 25 GPIO 26
|
||||
ESP32-S2 GPIO 17 GPIO 18
|
||||
========= ========= =========
|
||||
|
||||
Arduino-ESP32 DAC API
|
||||
---------------------
|
||||
|
||||
dacWrite
|
||||
********
|
||||
|
||||
This function is used to set the DAC value for a given pin/DAC channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void dacWrite(uint8_t pin, uint8_t value);
|
||||
|
||||
* ``pin`` GPIO pin.
|
||||
* ``value`` to be set. Range is 0 - 255 (equals 0V - 3.3V).
|
||||
|
||||
dacDisable
|
||||
**********
|
||||
|
||||
This function is used to disable DAC output on a given pin/DAC channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void dacDisable(uint8_t pin);
|
||||
|
||||
* ``pin`` GPIO pin.
|
@ -381,4 +381,4 @@ Here is an example of how to use the I2C in Slave Mode.
|
||||
.. literalinclude:: ../../../libraries/Wire/examples/WireSlave/WireSlave.ino
|
||||
:language: arduino
|
||||
|
||||
.. _Arduino Wire Library: https://www.arduino.cc/en/reference/wire
|
||||
.. _Arduino Wire Library: https://www.arduino.cc/en/reference/wire
|
||||
|
566
docs/source/api/i2s.rst
Normal file
566
docs/source/api/i2s.rst
Normal file
@ -0,0 +1,566 @@
|
||||
###
|
||||
I2S
|
||||
###
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
I2S - Inter-IC Sound, correctly written I²S pronounced "eye-squared-ess", alternative notation is IIS. I²S is an electrical serial bus interface standard used for connecting digital audio devices together.
|
||||
|
||||
It is used to communicate PCM (Pulse-Code Modulation) audio data between integrated circuits in an electronic device. The I²S bus separates clock and serial data signals, resulting in simpler receivers than those required for asynchronous communications systems that need to recover the clock from the data stream.
|
||||
|
||||
Despite the similar name, I²S is unrelated and incompatible with the bidirectional I²C (IIC) bus.
|
||||
|
||||
The I²S bus consists of at least three lines:
|
||||
|
||||
.. note:: All lines can be attached to almost any pin and this change can occur even during operation.
|
||||
|
||||
* **Bit clock line**
|
||||
|
||||
* Officially "continuous serial clock (SCK)". Typically written "bit clock (BCLK)".
|
||||
* In this library function parameter ``sckPin`` or constant ``PIN_I2S_SCK``.
|
||||
|
||||
* **Word clock line**
|
||||
|
||||
* Officially "word select (WS)". Typically called "left-right clock (LRCLK)" or "frame sync (FS)".
|
||||
* 0 = Left channel, 1 = Right channel
|
||||
* In this library function parameter ``fsPin`` or constant ``PIN_I2S_FS``.
|
||||
|
||||
* **Data line**
|
||||
|
||||
* Officially "serial data (SD)", but can be called SDATA, SDIN, SDOUT, DACDAT, ADCDAT, etc.
|
||||
* Unlike Arduino I2S with single data pin switching between input and output, in ESP core driver use separate data line for input and output.
|
||||
* For backward compatibility, the shared data pin is ``sdPin`` or constant ``PIN_I2S_SD`` when using simplex mode.
|
||||
|
||||
* When using in duplex mode, there are two data lines:
|
||||
|
||||
* Output data line is called ``outSdPin`` for function parameter, or constant ``PIN_I2S_SD_OUT``
|
||||
* Input data line is called ``inSdPin`` for function parameter, or constant ``PIN_I2S_SD_IN``
|
||||
|
||||
I2S Modes
|
||||
---------
|
||||
|
||||
The I2S can be set up in three groups of modes:
|
||||
|
||||
* Master (default) or Slave.
|
||||
* Simplex (default) or Duplex.
|
||||
* Operation modes (Philips standard, ADC/DAC, PDM)
|
||||
|
||||
* Most of them are dual-channel, some can be single channel
|
||||
|
||||
.. note:: Officially supported operation mode is only ``I2S_PHILIPS_MODE``. Other modes are implemented, but we cannot guarantee flawless execution and behavior.
|
||||
|
||||
Master / Slave Mode
|
||||
*******************
|
||||
|
||||
In **Master mode** (default) the device is generating clock signal ``sckPin`` and word select signal on ``fsPin``.
|
||||
|
||||
In **Slave mode** the device listens on attached pins for the clock signal and word select - i.e. unless externally driven the pins will remain LOW.
|
||||
|
||||
How to enter either mode is described in the function section.
|
||||
|
||||
Operation Modes
|
||||
***************
|
||||
|
||||
Setting the operation mode is done with function ``begin`` (see API section)
|
||||
|
||||
* ``I2S_PHILIPS_MODE``
|
||||
* Currently the only official* ``PIN_I2S_SCK``
|
||||
* ``PIN_I2S_FS``
|
||||
* ``PIN_I2S_SD``
|
||||
* ``PIN_I2S_SD_OUT`` only need to send one channel data but the data will be copied for another channel automatically, then both channels will transmit same data.
|
||||
|
||||
* ``ADC_DAC_MODE``
|
||||
The output will be an analog signal on pins ``25`` (L or R?) and ``26`` (L or R?).
|
||||
Input will be received on pin ``_inSdPin``.
|
||||
The data are sampled in 12 bits and stored in a 16 bits, with the 4 most significant bits set to zero.
|
||||
|
||||
* ``PDM_STEREO_MODE``
|
||||
Pulse-density-modulation is similar to PWM, but instead, the pulses have constant width. The signal is modulated with the number of ones or zeroes in sequence.
|
||||
|
||||
* ``PDM_MONO_MODE``
|
||||
Single-channel version of PDM mode described above.
|
||||
|
||||
Simplex / Duplex Mode
|
||||
*********************
|
||||
|
||||
The **Simplex** mode is the default after driver initialization. Simplex mode uses the shared data pin ``sdPin`` or constant ``PIN_I2S_SD`` for both output and input, but can only read or write. This is the same behavior as in original Arduino library.
|
||||
|
||||
The **Duplex** mode uses two separate data pins:
|
||||
|
||||
* Output pin ``outSdPin`` for function parameter, or constant ``PIN_I2S_SD_OUT``
|
||||
* Input pin ``inSdPin`` for function parameter, or constant ``PIN_I2S_SD_IN``
|
||||
|
||||
In this mode, the driver is able to read and write simultaneously on each line and is suitable for applications like walkie-talkie or phone.
|
||||
|
||||
Switching between these modes is performed simply by calling setDuplex() or setSimplex() (see APi section for details and more functions).
|
||||
|
||||
Arduino-ESP32 I2S API
|
||||
---------------------
|
||||
|
||||
The ESP32 I2S library is based on the Arduino I2S Library and implements a few more APIs, described in this `documentation <https://www.arduino.cc/en/Reference/I2S>`_.
|
||||
|
||||
Initialization and deinitialization
|
||||
***********************************
|
||||
|
||||
Before initialization, choose which pins you want to use. In DAC mode you can use only pins `25` and `26` for the output.
|
||||
|
||||
begin (Master Mode)
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Before usage choose which pins you want to use. In DAC mode you can use only pins 25 and 26 as output.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int begin(int mode, int sampleRate, int bitsPerSample)
|
||||
|
||||
Parameters:
|
||||
|
||||
* [in] ``mode`` one of above mentioned operation mode, for example ``I2S_PHILIPS_MODE``.
|
||||
|
||||
* [in] ``sampleRate`` is the sampling rate in Hz. Currently officially supported value is only 16000 - other than this value will print warning, but continue to operate, however the resulting audio quality may suffer and the app may crash.
|
||||
|
||||
* [in] ``bitsPerSample`` is the number of bits in a channel sample.
|
||||
|
||||
Currently, the supported value is only 16 - other than this value will print a warning, but continues to operate, however, the resulting audio quality may suffer and the application may crash.
|
||||
|
||||
For ``ADC_DAC_MODE`` the only possible value will remain 16.
|
||||
|
||||
This function will return ``true`` on success or ``fail`` in case of failure.
|
||||
|
||||
When failed, an error message will be printed if subscribed.
|
||||
|
||||
begin (Slave Mode)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Performs initialization before use - creates buffers, task handling underlying driver messages, configuring and starting the driver operation.
|
||||
|
||||
This version initializes I2S in SLAVE mode (see previous entry for MASTER mode).
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int begin(int mode, int bitsPerSample)
|
||||
|
||||
Parameters:
|
||||
|
||||
* [in] ``mode`` one of above mentioned modes for example ``I2S_PHILIPS_MODE``.
|
||||
|
||||
* [in] ``bitsPerSample`` is the umber of bits in a channel sample. Currently, the only supported value is only 16 - other than this value will print warning, but continue to operate, however the resulting audio quality may suffer and the app may crash.
|
||||
|
||||
For ``ADC_DAC_MODE`` the only possible value will remain 16.
|
||||
|
||||
This function will return ``true`` on success or ``fail`` in case of failure.
|
||||
|
||||
When failed, an error message will be printed if subscribed.
|
||||
|
||||
end
|
||||
^^^
|
||||
|
||||
Performs safe deinitialization - free buffers, destroy task, end driver operation, etc.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void end()
|
||||
|
||||
Pin setup
|
||||
*********
|
||||
|
||||
Pins can be changed in two ways- 1st constants, 2nd functions.
|
||||
|
||||
.. note:: Shared data pin can be equal to any other data pin, but must not be equal to clock pin nor frame sync pin! Input and Output pins must not be equal, but one of them can be equal to shared data pin!
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
sckPin != fsPin != outSdPin != inSdPin
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
sckPin != fsPin != sdPin
|
||||
|
||||
By default, the pin numbers are defined in constants in the header file. You can redefine any of those constants before including ``I2S.h``. This way the driver will use these new default values and you will not need to specify pins in your code. The constants and their default values are:
|
||||
|
||||
* ``PIN_I2S_SCK`` 14
|
||||
* ``PIN_I2S_FS`` 25
|
||||
* ``PIN_I2S_SD`` 26
|
||||
* ``PIN_I2S_SD_OUT`` 26
|
||||
* ``PIN_I2S_SD_IN`` 35
|
||||
|
||||
The second option to change pins is using the following functions. These functions can be called on either on initialized or uninitialized object.
|
||||
|
||||
If called on the initialized object (after calling ``begin``) the pins will change during operation.
|
||||
If called on the uninitialized object (before calling ``begin``, or after calling ``end``) the new pin setup will be used on next initialization.
|
||||
|
||||
setSckPin
|
||||
^^^^^^^^^
|
||||
|
||||
Set and apply clock pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setSckPin(int sckPin)
|
||||
|
||||
This function will return ``true`` on success or ``fail`` in case of failure.
|
||||
|
||||
setFsPin
|
||||
^^^^^^^^
|
||||
|
||||
Set and apply frame sync pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setFsPin(int fsPin)
|
||||
|
||||
This function will return ``true`` on success or ``fail`` in case of failure.
|
||||
|
||||
setDataPin
|
||||
^^^^^^^^^^
|
||||
|
||||
Set and apply shared data pin used in simplex mode.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setDataPin(int sdPin)
|
||||
|
||||
This function will return ``true`` on success or ``fail`` in case of failure.
|
||||
|
||||
setDataInPin
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Set and apply data input pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setDataInPin(int inSdPin)
|
||||
|
||||
This function will return ``true`` on success or ``fail`` in case of failure.
|
||||
|
||||
setDataOutPin
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Set and apply data output pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setDataOutPin(int outSdPin)
|
||||
|
||||
This function will return ``true`` on success or ``fail`` in case of failure.
|
||||
|
||||
setAllPins
|
||||
^^^^^^^^^^
|
||||
|
||||
Set all pins using given values in parameters. This is simply a wrapper of four functions mentioned above.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setAllPins(int sckPin, int fsPin, int sdPin, int outSdPin, int inSdPin)
|
||||
|
||||
Set all pins to default i.e. take values from constants mentioned above. This simply calls the the function with the following constants.
|
||||
|
||||
* ``PIN_I2S_SCK`` 14
|
||||
* ``PIN_I2S_FS`` 25
|
||||
* ``PIN_I2S_SD`` 26
|
||||
* ``PIN_I2S_SD_OUT`` 26
|
||||
* ``PIN_I2S_SD_IN`` 35
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setAllPins()
|
||||
|
||||
getSckPin
|
||||
^^^^^^^^^
|
||||
|
||||
Get the current value of the clock pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int getSckPin()
|
||||
|
||||
getFsPin
|
||||
^^^^^^^^
|
||||
|
||||
Get the current value of frame sync pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int getFsPin()
|
||||
|
||||
getDataPin
|
||||
^^^^^^^^^^
|
||||
|
||||
Get the current value of shared data pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int getDataPin()
|
||||
|
||||
getDataInPin
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Get the current value of data input pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int getDataInPin()
|
||||
|
||||
getDataOutPin
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Get the current value of data output pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int getDataOutPin()
|
||||
|
||||
onTransmit
|
||||
^^^^^^^^^^
|
||||
|
||||
Register the function to be called on each successful transmit event.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onTransmit(void(*)(void))
|
||||
|
||||
onReceive
|
||||
^^^^^^^^^
|
||||
|
||||
Register the function to be called on each successful receives event.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onReceive(void(*)(void))
|
||||
|
||||
setBufferSize
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Set the size of buffer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setBufferSize(int bufferSize)
|
||||
|
||||
This function can be called on both the initialized or uninitialized driver.
|
||||
|
||||
If called on initialized, it will change internal values for buffer size and re-initialize driver with new value.
|
||||
If called on uninitialized, it will only change the internal values which will be used for next initialization.
|
||||
|
||||
Parameter ``bufferSize`` must be in range from 8 to 1024 and the unit is sample words. The default value is 128.
|
||||
|
||||
Example: 16 bit sample, dual channel, buffer size for input:
|
||||
|
||||
``128 = 2B sample * 2 channels * 128 buffer size * buffer count (default 2) = 1024B``
|
||||
|
||||
And more ```1024B`` for output buffer in total of ``2kB`` used.
|
||||
|
||||
This function always assumes dual-channel, keeping the same size even for MONO modes.
|
||||
|
||||
This function will return ``true`` on success or ``fail`` in case of failure.
|
||||
|
||||
When failed, an error message will be printed.
|
||||
|
||||
getBufferSize
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Get current buffer sizes in sample words (see description for ``setBufferSize``).
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int getBufferSize()
|
||||
|
||||
Duplex vs Simplex
|
||||
*****************
|
||||
|
||||
Original Arduino I2S library supports only *simplex* mode (only transmit or only receive at a time). For compatibility, we kept this behavior, but ESP natively supports *duplex* mode (receive and transmit simultaneously on separate pins).
|
||||
By default this library is initialized in simplex mode as it would in Arduino, switching input and output on ``sdPin`` (constant ``PIN_I2S_SD`` default pin 26).
|
||||
|
||||
setDuplex
|
||||
^^^^^^^^^
|
||||
|
||||
Switch to duplex mode and use separate pins:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setDuplex()
|
||||
|
||||
input: inSdPin (constant PIN_I2S_SD_IN, default 35)
|
||||
output: outSdPin (constant PIN_I2S_SD, default 26)
|
||||
|
||||
setSimplex
|
||||
^^^^^^^^^^
|
||||
|
||||
(Default mode)
|
||||
|
||||
Switch to simplex mode using shared data pin sdPin (constant PIN_I2S_SD, default 26).
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int setSimplex()
|
||||
|
||||
isDuplex
|
||||
^^^^^^^^
|
||||
|
||||
Returns 1 if current mode is duplex, 0 if current mode is simplex (default).
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int isDuplex()
|
||||
|
||||
Data stream
|
||||
***********
|
||||
|
||||
available
|
||||
^^^^^^^^^
|
||||
|
||||
Returns number of **bytes** ready to read.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int available()
|
||||
|
||||
read
|
||||
^^^^
|
||||
|
||||
Read ``size`` bytes from internal buffer if possible.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int read(void* buffer, size_t size)
|
||||
|
||||
This function is non-blocking, i.e. if the requested number of bytes is not available, it will return as much as possible without waiting.
|
||||
|
||||
Hint: use ``available()`` before calling this function.
|
||||
|
||||
Parameters:
|
||||
|
||||
[out] ``void* buffer`` buffer into which will be copied data read from internal buffer. WARNING: this buffer must be allocated before use!
|
||||
|
||||
[in] ``size_t size`` number of bytes required to be read.
|
||||
|
||||
Returns number of successfully bytes read. Returns ``false``` in case of reading error.
|
||||
|
||||
Read one sample.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int read()
|
||||
|
||||
peek
|
||||
^^^^
|
||||
|
||||
Read one sample from the internal buffer and returns it.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int peek()
|
||||
|
||||
Repeated peeks will be returned in the same sample until ``read`` is called.
|
||||
|
||||
flush
|
||||
^^^^^
|
||||
|
||||
Force write internal buffer to driver.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void flush()
|
||||
|
||||
write
|
||||
^^^^^
|
||||
|
||||
Write a single byte.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t write(uint8_t)
|
||||
|
||||
Single-sample writes are blocking - waiting until there is free space in the internal buffer to be written into.
|
||||
|
||||
Returns number of successfully written bytes, in this case, 1. Returns 0 on error.
|
||||
|
||||
Write single sample.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t write(int32_t)
|
||||
|
||||
Single-sample writes are blocking - waiting until there is free space in the internal buffer to be written into.
|
||||
|
||||
Returns number of successfully written bytes. Returns 0 on error.
|
||||
|
||||
Expected return number is ``bitsPerSample/8``.
|
||||
|
||||
Write buffer of supplied size;
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t write(const void *buffer, size_t size)
|
||||
|
||||
Parameters:
|
||||
|
||||
[in] ``const void *buffer`` buffer to be written
|
||||
[in] ``size_t size`` size of buffer in bytes
|
||||
|
||||
Returns number of successfully written bytes. Returns 0 in case of error.
|
||||
The expected return number is equal to ``size``.
|
||||
|
||||
write
|
||||
^^^^^
|
||||
|
||||
This is a wrapper of the previous function performing typecast from `uint8_t*`` to ``void*``.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t write(const uint8_t *buffer, size_t size)
|
||||
|
||||
availableForWrite
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Returns number of bytes available for write.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int availableForWrite()
|
||||
|
||||
write_blocking
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Core function implementing blocking write, i.e. waits until all requested data are written.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t write_blocking(const void *buffer, size_t size)
|
||||
|
||||
WARNING: If too many bytes are requested, this can cause WatchDog Trigger Reset!
|
||||
|
||||
Returns number of successfully written bytes. Returns 0 on error.
|
||||
|
||||
write_nonblocking
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Core function implementing non-blocking write, i.e. writes as much as possible and exits.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t write_nonblocking(const void *buffer, size_t size)
|
||||
|
||||
Returns number of successfully written bytes. Returns 0 on error.
|
||||
|
||||
Sample code
|
||||
-----------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <I2S.h>
|
||||
const int buff_size = 128;
|
||||
int available, read;
|
||||
uint8_t buffer[buff_size];
|
||||
|
||||
I2S.begin(I2S_PHILIPS_MODE, 16000, 16);
|
||||
I2S.read(); // Switch the driver in simplex mode to receive
|
||||
available = I2S.available();
|
||||
if(available < buff_size){
|
||||
read = I2S.read(buffer, available);
|
||||
}else{
|
||||
read = I2S.read(buffer, buff_size);
|
||||
}
|
||||
I2S.write(buffer, read);
|
||||
I2S.end();
|
183
docs/source/api/ledc.rst
Normal file
183
docs/source/api/ledc.rst
Normal file
@ -0,0 +1,183 @@
|
||||
##################
|
||||
LED Control (LEDC)
|
||||
##################
|
||||
|
||||
About
|
||||
-----
|
||||
The LED control (LEDC) peripheral is primarly designed to control the intensity of LEDs,
|
||||
although it can also be used to generate PWM signals for other purposes.
|
||||
|
||||
ESP32 SoCs has from 6 to 16 channels (variates on socs, see table below) which can generate independent waveforms, that can be used for example to drive RGB LED devices.
|
||||
|
||||
========= =======================
|
||||
ESP32 SoC Number of LEDC channels
|
||||
========= =======================
|
||||
ESP32 16
|
||||
ESP32-S2 8
|
||||
ESP32-C3 6
|
||||
ESP32-S3 8
|
||||
========= =======================
|
||||
|
||||
Arduino-ESP32 LEDC API
|
||||
----------------------
|
||||
|
||||
ledcSetup
|
||||
*********
|
||||
|
||||
This function is used to setup the LEDC channel frequency and resolution.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits);
|
||||
|
||||
* ``channel`` select LEDC channel to config.
|
||||
* ``freq`` select frequency of pwm.
|
||||
* ``resolution_bits`` select resolution for ledc channel.
|
||||
|
||||
* range is 1-14 bits (1-20 bits for ESP32).
|
||||
|
||||
This function will return ``frequency`` configured for LEDC channel.
|
||||
If ``0`` is returned, error occurs and ledc channel was not configured.
|
||||
|
||||
ledcWrite
|
||||
*********
|
||||
|
||||
This function is used to set duty for the LEDC channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void ledcWrite(uint8_t chan, uint32_t duty);
|
||||
|
||||
* ``chan`` select the LEDC channel for writing duty.
|
||||
* ``duty`` select duty to be set for selected channel.
|
||||
|
||||
ledcRead
|
||||
********
|
||||
|
||||
This function is used to get configured duty for the LEDC channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint32_t ledcRead(uint8_t chan);
|
||||
|
||||
* ``chan`` select LEDC channel to read the configured duty.
|
||||
|
||||
This function will return ``duty`` set for selected LEDC channel.
|
||||
|
||||
ledcReadFreq
|
||||
************
|
||||
|
||||
This function is used to get configured frequency for the LEDC channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double ledcReadFreq(uint8_t chan);
|
||||
|
||||
* ``chan`` select the LEDC channel to read the configured frequency.
|
||||
|
||||
This function will return ``frequency`` configured for selected LEDC channel.
|
||||
|
||||
ledcWriteTone
|
||||
*************
|
||||
|
||||
This function is used to setup the LEDC channel to 50 % PWM tone on selected frequency.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double ledcWriteTone(uint8_t chan, double freq);
|
||||
|
||||
* ``chan`` select LEDC channel.
|
||||
* ``freq`` select frequency of pwm signal.
|
||||
|
||||
This function will return ``frequency`` set for channel.
|
||||
If ``0`` is returned, error occurs and ledc cahnnel was not configured.
|
||||
|
||||
ledcWriteNote
|
||||
*************
|
||||
|
||||
This function is used to setup the LEDC channel to specific note.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave);
|
||||
|
||||
* ``chan`` select LEDC channel.
|
||||
* ``note`` select note to be set.
|
||||
|
||||
======= ======= ======= ======= ======= ======
|
||||
NOTE_C NOTE_Cs NOTE_D NOTE_Eb NOTE_E NOTE_F
|
||||
NOTE_Fs NOTE_G NOTE_Gs NOTE_A NOTE_Bb NOTE_B
|
||||
======= ======= ======= ======= ======= ======
|
||||
|
||||
* ``octave`` select octave for note.
|
||||
|
||||
This function will return ``frequency`` configured for the LEDC channel according to note and octave inputs.
|
||||
If ``0`` is returned, error occurs and the LEDC channel was not configured.
|
||||
|
||||
ledcAttachPin
|
||||
*************
|
||||
|
||||
This function is used to attach the pin to the LEDC channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void ledcAttachPin(uint8_t pin, uint8_t chan);
|
||||
|
||||
* ``pin`` select GPIO pin.
|
||||
* ``chan`` select LEDC channel.
|
||||
|
||||
ledcDetachPin
|
||||
*************
|
||||
|
||||
This function is used to detach the pin from LEDC.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void ledcDetachPin(uint8_t pin);
|
||||
|
||||
* ``pin`` select GPIO pin.
|
||||
|
||||
ledcChangeFrequency
|
||||
*******************
|
||||
|
||||
This function is used to set frequency for the LEDC channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num);
|
||||
|
||||
* ``channel`` select LEDC channel.
|
||||
* ``freq`` select frequency of pwm.
|
||||
* ``bit_num`` select resolution for LEDC channel.
|
||||
|
||||
* range is 1-14 bits (1-20 bits for ESP32).
|
||||
|
||||
This function will return ``frequency`` configured for the LEDC channel.
|
||||
If ``0`` is returned, error occurs and the LEDC channel frequency was not set.
|
||||
|
||||
analogWrite
|
||||
***********
|
||||
|
||||
This function is used to write an analog value (PWM wave) on the pin.
|
||||
It is compatible with Arduinos analogWrite function.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void analogWrite(uint8_t pin, int value);
|
||||
|
||||
* ``pin`` select the GPIO pin.
|
||||
* ``value`` select the duty cycle of pwm.
|
||||
* range is from 0 (always off) to 255 (always on).
|
||||
|
||||
Example Applications
|
||||
********************
|
||||
|
||||
LEDC software fade example:
|
||||
|
||||
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogOut/LEDCSoftwareFade/LEDCSoftwareFade.ino
|
||||
:language: arduino
|
||||
|
||||
LEDC Write RGB example:
|
||||
|
||||
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogOut/ledcWrite_RGB/ledcWrite_RGB.ino
|
||||
:language: arduino
|
701
docs/source/api/preferences.rst
Normal file
701
docs/source/api/preferences.rst
Normal file
@ -0,0 +1,701 @@
|
||||
###########
|
||||
Preferences
|
||||
###########
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
The Preferences library is unique to arduino-esp32. It should be considered as the replacement for the Arduino EEPROM library.
|
||||
|
||||
It uses a portion of the on-board non-volatile memory (NVS) of the ESP32 to store data. This data is retained across restarts and loss of power events to the system.
|
||||
|
||||
Preferences works best for storing many small values, rather than a few large values. If large amounts of data are to be stored, consider using a file system library such as LitteFS.
|
||||
|
||||
The Preferences library is usable by all ESP32 variants.
|
||||
|
||||
|
||||
Header File
|
||||
-----------
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
#include <Preferences.h>
|
||||
..
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Library methods are provided to:
|
||||
- create a namespace;
|
||||
- open and close a namespace;
|
||||
- store and retrieve data within a namespace for supported data types;
|
||||
- determine if a key value has been initialized;
|
||||
- delete a ``key-value`` pair;
|
||||
- delete all ``key-value`` pairs in a namespace;
|
||||
- determine data types stored against a key;
|
||||
- determine the number of key entries in the namespace.
|
||||
|
||||
Preferences directly supports the following data types:
|
||||
|
||||
.. table:: **Table 1 — Preferences Data Types**
|
||||
:align: center
|
||||
|
||||
+-------------------+-------------------+---------------+
|
||||
| Preferences Type | Data Type | Size (bytes) |
|
||||
+===================+===================+===============+
|
||||
| Bool | bool | 1 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Char | int8_t | 1 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| UChar | uint8_t | 1 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Short | int16_t | 2 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| UShort | uint16_t | 2 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Int | int32_t | 4 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| UInt | uint32_t | 4 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Long | int32_t | 4 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| ULong | uint32_t | 4 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Long64 | int64_t | 8 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| ULong64 | uint64_t | 8 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Float | float_t | 8 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Double | double_t | 8 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| | const char* | variable |
|
||||
| String +-------------------+ |
|
||||
| | String | |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Bytes | uint8_t | variable |
|
||||
+-------------------+-------------------+---------------+
|
||||
|
||||
String values can be stored and retrieved either as an Arduino String or as a null terminated ``char`` array (c-string).
|
||||
|
||||
Bytes type is used for storing and retrieving an arbitrary number of bytes in a namespace.
|
||||
|
||||
|
||||
Arduino-esp32 Preferences API
|
||||
-----------------------------
|
||||
|
||||
``begin``
|
||||
**********
|
||||
|
||||
Open non-volatile storage with a given namespace name from an NVS partition.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool begin(const char * name, bool readOnly=false, const char* partition_label=NULL)
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``name`` (Required)
|
||||
- Namespace name. Maximum length is 15 characters.
|
||||
|
||||
* ``readOnly`` (Optional)
|
||||
- ``false`` will open the namespace in read-write mode.
|
||||
- ``true`` will open the namespace in read-only mode.
|
||||
- if omitted, the namespace is opened in read-write mode.
|
||||
|
||||
* ``partition_label`` (Optional)
|
||||
- name of the NVS partition in which to open the namespace.
|
||||
- if omitted, the namespace is opened in the "``nvs``" partition.
|
||||
|
||||
**Returns**
|
||||
* ``true`` if the namespace was opened successfully; ``false`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* If the namespace does not exist within the partition, it is first created.
|
||||
* Attempting to write a key value to a namespace open in read-only mode will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``end``
|
||||
*********
|
||||
|
||||
Close the currently opened namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void end()
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* None
|
||||
|
||||
**Returns**
|
||||
* Nothing
|
||||
|
||||
**Note**
|
||||
* After closing a namespace, methods used to access it will fail.
|
||||
|
||||
|
||||
``clear``
|
||||
**********
|
||||
|
||||
Delete all keys and values from the currently opened namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool clear()
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* None
|
||||
|
||||
**Returns**
|
||||
* ``true`` if all keys and values were deleted; ``false`` otherwise.
|
||||
|
||||
**Note**
|
||||
* the namespace name still exists afterward.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``remove``
|
||||
*************
|
||||
|
||||
Delete a key-value pair from the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool remove(const char * key)
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
- the name of the key to be deleted.
|
||||
|
||||
**Returns**
|
||||
* ``true`` if key-value pair was deleted; ``false`` otherwise.
|
||||
|
||||
**Note**
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``putChar, putUChar``
|
||||
**********************
|
||||
|
||||
Store a value against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t putChar(const char* key, int8_t value)
|
||||
size_t putUChar(const char* key, uint8_t value)
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
- if the key does not exist in the currently opened namespace it is first created.
|
||||
|
||||
* ``value`` (Required)
|
||||
- must match the data type of the method.
|
||||
|
||||
**Returns**
|
||||
* ``1`` (the number of bytes stored for these data types) if the call is successful; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* Attempting to store a value without a namespace being open in read-write mode will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``putShort, putUShort``
|
||||
************************
|
||||
|
||||
Store a value against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t putShort(const char* key, int16_t value)
|
||||
size_t putUShort(const char* key, uint16_t value)
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
- if the key does not exist in the currently opened namespace it is first created.
|
||||
|
||||
* ``value`` (Required)
|
||||
- must match the data type of the method.
|
||||
|
||||
**Returns**
|
||||
* ``2`` (the number of bytes stored for these data types) if the call is successful; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* Attempting to store a value without a namespace being open in read-write mode will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
|
||||
``putInt, putUInt``
|
||||
********************
|
||||
``putLong, putULong``
|
||||
**********************
|
||||
|
||||
Store a value against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t putInt(const char* key, int32_t value)
|
||||
size_t putUInt(const char* key, uint32_t value)
|
||||
size_t putLong(const char* key, int32_t value)
|
||||
size_t putULong(const char* key, uint32_t value)
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
- if the key does not exist in the currently opened namespace it is first created.
|
||||
|
||||
* ``value`` (Required)
|
||||
- must match the data type of the method.
|
||||
|
||||
**Returns**
|
||||
* ``4`` (the number of bytes stored for these data types) if the call is successful; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* Attempting to store a value without a namespace being open in read-write mode will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``putLong64, putULong64``
|
||||
*************************
|
||||
``putFloat, putDouble``
|
||||
***********************
|
||||
|
||||
Store a value against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t putLong64(const char* key, int64_t value)
|
||||
size_t putULong64(const char* key, uint64_t value)
|
||||
size_t putFloat(const char* key, float_t value)
|
||||
size_t putDouble(const char* key, double_t value)
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
- if the key does not exist in the currently opened namespace it is first created.
|
||||
|
||||
* ``value`` (Required)
|
||||
- must match the data type of the method.
|
||||
|
||||
**Returns**
|
||||
* ``8`` (the number of bytes stored for these data types) if the call is successful; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* Attempting to store a value without a namespace being open in read-write mode will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``putBool``
|
||||
***********
|
||||
|
||||
Store a value against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t putBool(const char* key, bool value)
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
- if the key does not exist in the currently opened namespace it is first created.
|
||||
|
||||
* ``value`` (Required)
|
||||
- must match the data type of the method.
|
||||
|
||||
**Returns**
|
||||
* ``true`` if successful; ``false`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* Attempting to store a value without a namespace being open in read-write mode will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``putString``
|
||||
**************
|
||||
|
||||
Store a variable length value against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t putString(const char* key, const char* value);
|
||||
size_t putString(const char* key, String value);
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
- if the key does not exist in the currently opened namespace it is first created.
|
||||
|
||||
* ``value`` (Required)
|
||||
- if ``const char*``, a null-terminated (c-string) character array.
|
||||
- if ``String``, a valid Arduino String type.
|
||||
|
||||
**Returns**
|
||||
* if successful: the number of bytes stored; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* Attempting to store a value without a namespace being open in read-write mode will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``putBytes``
|
||||
************
|
||||
|
||||
Store a variable number of bytes against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t putBytes(const char* key, const void* value, size_t len);
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
- if the key does not exist in the currently opened namespace it is first created.
|
||||
|
||||
* ``value`` (Required)
|
||||
- pointer to an array or buffer containing the bytes to be stored.
|
||||
|
||||
* ``len`` (Required)
|
||||
- the number of bytes from ``value`` to be stored.
|
||||
|
||||
**Returns**
|
||||
* if successful: the number of bytes stored; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* Attempting to store a value without a namespace being open in read-write mode will fail.
|
||||
* This method operates on the bytes used by the underlying data type, not the number of elements of a given data type. The data type of ``value`` is not retained by the Preferences library afterward.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``getChar, getUChar``
|
||||
*********************
|
||||
|
||||
Retrieve a value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int8_t getChar(const char* key, int8_t defaultValue = 0)
|
||||
uint8_t getUChar(const char* key, uint8_t defaultValue = 0)
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
|
||||
* ``defaultValue`` (Optional)
|
||||
- must match the data type of the method if provided.
|
||||
|
||||
**Returns**
|
||||
* the value stored against ``key`` if the call is successful.
|
||||
* ``defaultValue``, if it is provided; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* Attempting to retrieve a key without a namespace being available will fail.
|
||||
* Attempting to retrieve value from a non existant key will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``getShort, getUShort``
|
||||
****************************
|
||||
|
||||
Retrieve a value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int16_t getShort(const char* key, int16_t defaultValue = 0)
|
||||
uint16_t getUShort(const char* key, uint16_t defaultValue = 0)
|
||||
..
|
||||
|
||||
Except for the data type returned, behaves exactly like ``getChar``.
|
||||
|
||||
|
||||
|
||||
``getInt, getUInt``
|
||||
*******************
|
||||
|
||||
Retrieve a value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int32_t getInt(const char* key, int32_t defaultValue = 0)
|
||||
uint32_t getUInt(const char* key, uint32_t defaultValue = 0)
|
||||
|
||||
..
|
||||
|
||||
Except for the data type returned, behaves exactly like ``getChar``.
|
||||
|
||||
|
||||
``getLong, getULong``
|
||||
*********************
|
||||
|
||||
Retrieve a value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int32_t getLong(const char* key, int32_t defaultValue = 0)
|
||||
uint32_t getULong(const char* key, uint32_t defaultValue = 0)
|
||||
|
||||
..
|
||||
|
||||
Except for the data type returned, behaves exactly like ``getChar``.
|
||||
|
||||
|
||||
``getLong64, getULong64``
|
||||
*************************
|
||||
|
||||
Retrieve a value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int64_t getLong64(const char* key, int64_t defaultValue = 0)
|
||||
uint64_t getULong64(const char* key, uint64_t defaultValue = 0)
|
||||
|
||||
..
|
||||
|
||||
Except for the data type returned, behaves exactly like ``getChar``.
|
||||
|
||||
|
||||
``getFloat``
|
||||
*************
|
||||
|
||||
Retrieve a value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
float_t getFloat(const char* key, float_t defaultValue = NAN)
|
||||
|
||||
..
|
||||
|
||||
Except for the data type returned and the value of ``defaultValue``, behaves exactly like ``getChar``.
|
||||
|
||||
|
||||
``getDouble``
|
||||
*************
|
||||
|
||||
Retrieve a value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double_t getDouble(const char* key, double_t defaultValue = NAN)
|
||||
|
||||
..
|
||||
|
||||
Except for the data type returned and the value of ``defaultValue``, behaves exactly like ``getChar``.
|
||||
|
||||
|
||||
``getBool``
|
||||
************
|
||||
|
||||
Retrieve a value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint8_t getUChar(const char* key, uint8_t defaultValue = 0);
|
||||
|
||||
..
|
||||
|
||||
Except for the data type returned, behaves exactly like ``getChar``.
|
||||
|
||||
|
||||
``getString``
|
||||
*************
|
||||
|
||||
Copy a string of ``char`` stored against a given key in the currently open namespace to a buffer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t getString(const char* key, char* value, size_t len);
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
* ``value`` (Required)
|
||||
- a buffer of a size large enough to hold ``len`` bytes
|
||||
* ``len`` (Required)
|
||||
- the number of type ``char``` to be written to the buffer pointed to by ``value``
|
||||
|
||||
**Returns**
|
||||
* if successful; the number of bytes equal to ``len`` is written to the buffer pointed to by ``value``, and the method returns ``1``.
|
||||
* if the method fails, nothing is written to the buffer pointed to by ``value`` and the method returns ``0``.
|
||||
|
||||
**Notes**
|
||||
* ``len`` must equal the number of bytes stored against the key or the call will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``getString``
|
||||
*************
|
||||
|
||||
Retrieve an Arduino String value stored against a given key in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
String getString(const char* key, String defaultValue = String());
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
* ``defaultValue`` (Optional)
|
||||
|
||||
**Returns**
|
||||
* the value stored against ``key`` if the call if successful
|
||||
* if the method fails: it returns ``defaultValue``, if provided; ``""`` (an empty String) otherwise.
|
||||
|
||||
**Notes**
|
||||
* ``defaultValue`` must be of type ``String``.
|
||||
|
||||
|
||||
``getBytes``
|
||||
*************
|
||||
|
||||
Copy a series of bytes stored against a given key in the currently open namespace to a buffer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t getBytes(const char* key, void * buf, size_t len);
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
* ``buf`` (Required)
|
||||
- a buffer of a size large enough to hold ``len`` bytes.
|
||||
* ``len`` (Required)
|
||||
- the number of bytes to be written to the buffer pointed to by ``buf``
|
||||
|
||||
**Returns**
|
||||
* if successful, the number of bytes equal to ``len`` is written to buffer ``buf``, and the method returns ``1``.
|
||||
* if the method fails, nothing is written to the buffer and the method returns ``0``.
|
||||
|
||||
**Notes**
|
||||
* ``len`` must equal the number of bytes stored against the key or the call will fail.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``getBytesLength``
|
||||
******************
|
||||
|
||||
Get the number of bytes stored in the value against a key of type ``Bytes`` in the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t getBytesLength(const char* key)
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
|
||||
**Returns**
|
||||
* if successful: the number of bytes in the value stored against ``key``; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* This method will fail if ``key`` is not of type ``Bytes``.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
``getType``
|
||||
***********
|
||||
|
||||
Get the Preferences data type of a given key within the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
PreferenceType getType(const char* key)
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* ``key`` (Required)
|
||||
|
||||
**Returns**
|
||||
* an ``int`` value as per Table 2 below.
|
||||
* a value of ``10`` (PT_INVALID) if the call fails.
|
||||
|
||||
**Notes**
|
||||
* The return values are enumerated in ``Preferences.h``. Table 2 includes the enumerated values for information.
|
||||
* A return value can map to more than one Prefs Type.
|
||||
* The method will fail if: the namespace is not open; the key does not exist; the provided key exceeds 15 characters.
|
||||
|
||||
.. table:: **Table 2 — getType Return Values**
|
||||
:align: center
|
||||
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| Return value | Prefs Type | Data Type | Enumerated Value |
|
||||
+===============+===============+===================+=======================+
|
||||
| 0 | Char | int8_t | PT_I8 |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 1 | UChar | uint8_t | PT_U8 |
|
||||
| +---------------+-------------------+ |
|
||||
| | Bool | bool | |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 2 | Short | int16_t | PT_I16 |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 3 | UShort | uint16_t | PT_U16 |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 4 | Int | int32_t | PT_I32 |
|
||||
| +---------------+ | |
|
||||
| | Long | | |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 5 | UInt | uint32_t | PT_U32 |
|
||||
| +---------------+ | |
|
||||
| | ULong | | |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 6 | Long64 | int64_t | PT_I64 |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 7 | ULong64 | uint64_t | PT_U64 |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 8 | String | String | PT_STR |
|
||||
| | +-------------------+ |
|
||||
| | | \*char | |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 9 | Double | double_t | PT_BLOB |
|
||||
| +---------------+-------------------+ |
|
||||
| | Float | float_t | |
|
||||
| +---------------+-------------------+ |
|
||||
| | Bytes | uint8_t | |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
| 10 | \- | \- | PT_INVALID |
|
||||
+---------------+---------------+-------------------+-----------------------+
|
||||
|
||||
|
||||
``freeEntries``
|
||||
***************
|
||||
|
||||
Get the number of free entries available in the key table of the currently open namespace.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t freeEntries()
|
||||
|
||||
..
|
||||
|
||||
**Parameters**
|
||||
* none
|
||||
|
||||
**Returns**
|
||||
* if successful: the number of free entries available in the key table of the currently open namespace; ``0`` otherwise.
|
||||
|
||||
**Notes**
|
||||
* keys storing values of type ``Bool``, ``Char``, ``UChar``, ``Short``, ``UShort``, ``Int``, ``UInt``, ``Long``, ``ULong``, ``Long64``, ``ULong64`` use one entry in the key table.
|
||||
* keys storing values of type ``Float`` and ``Double`` use three entries in the key table.
|
||||
* Arduino or c-string ``String`` types use a minimum of two key table entries with the number of entries increasing with the length of the string.
|
||||
* keys storing values of type ``Bytes`` use a minimum of three key table entries with the number of entries increasing with the number of bytes stored.
|
||||
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
|
||||
|
||||
|
||||
.. --- EOF ----
|
84
docs/source/api/sigmadelta.rst
Normal file
84
docs/source/api/sigmadelta.rst
Normal file
@ -0,0 +1,84 @@
|
||||
##########
|
||||
SigmaDelta
|
||||
##########
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
ESP32 provides a second-order sigma delta modulation module and 8 (4 for ESP32-C3)
|
||||
independent modulation channels. The channels are capable to output 1-bit
|
||||
signals (output index: 100 ~ 107) with sigma delta modulation.
|
||||
|
||||
========= =============================
|
||||
ESP32 SoC Number of SigmaDelta channels
|
||||
========= =============================
|
||||
ESP32 8
|
||||
ESP32-S2 8
|
||||
ESP32-C3 4
|
||||
ESP32-S3 8
|
||||
========= =============================
|
||||
|
||||
Arduino-ESP32 SigmaDelta API
|
||||
----------------------------
|
||||
|
||||
sigmaDeltaSetup
|
||||
***************
|
||||
|
||||
This function is used to setup the SigmaDelta channel frequency and resolution.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits);
|
||||
|
||||
* ``pin`` select GPIO pin.
|
||||
* ``channel`` select SigmaDelta channel.
|
||||
* ``freq`` select frequency.
|
||||
|
||||
* range is 1-14 bits (1-20 bits for ESP32).
|
||||
|
||||
This function will return ``frequency`` configured for the SigmaDelta channel.
|
||||
If ``0`` is returned, error occurs and the SigmaDelta channel was not configured.
|
||||
|
||||
sigmaDeltaWrite
|
||||
***************
|
||||
|
||||
This function is used to set duty for the SigmaDelta channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void sigmaDeltaWrite(uint8_t channel, uint8_t duty);
|
||||
|
||||
* ``channel`` select SigmaDelta channel.
|
||||
* ``duty`` select duty to be set for selected channel.
|
||||
|
||||
sigmaDeltaRead
|
||||
**************
|
||||
|
||||
This function is used to get configured duty for the SigmaDelta channel.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint8_t sigmaDeltaRead(uint8_t channel)
|
||||
|
||||
* ``channnel`` select SigmaDelta channel.
|
||||
|
||||
This function will return ``duty`` configured for the selected SigmaDelta channel.
|
||||
|
||||
sigmaDeltaDetachPin
|
||||
*******************
|
||||
|
||||
This function is used to detach pin from SigmaDelta.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void sigmaDeltaDetachPin(uint8_t pin);
|
||||
|
||||
* ``pin`` select GPIO pin.
|
||||
|
||||
Example Applications
|
||||
********************
|
||||
|
||||
Here is example use of SigmaDelta:
|
||||
|
||||
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogOut/SigmaDelta/SigmaDelta.ino
|
||||
:language: arduino
|
377
docs/source/api/timer.rst
Normal file
377
docs/source/api/timer.rst
Normal file
@ -0,0 +1,377 @@
|
||||
##########
|
||||
Timer
|
||||
##########
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
The ESP32 SoCs contains from 2 to 4 hardware timers.
|
||||
They are all 64-bit (54-bit for ESP32-C3) generic timers based on 16-bit pre-scalers and 64-bit (54-bit for ESP32-C3)
|
||||
up / down counters which are capable of being auto-reloaded.
|
||||
|
||||
========= ================
|
||||
ESP32 SoC Number of timers
|
||||
========= ================
|
||||
ESP32 4
|
||||
ESP32-S2 4
|
||||
ESP32-C3 2
|
||||
ESP32-S3 4
|
||||
========= ================
|
||||
|
||||
Arduino-ESP32 Timer API
|
||||
----------------------------
|
||||
|
||||
timerBegin
|
||||
**********
|
||||
|
||||
This function is used to configure the timer. After successful setup the timer will automatically start.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp);
|
||||
|
||||
* ``num`` select timer number.
|
||||
* ``divider`` select timer divider.
|
||||
* ``resolution`` select timer resolution.
|
||||
|
||||
* range is 1-14 bits (1-20 bits for ESP32).
|
||||
|
||||
This function will return ``timer`` structure if configuration is successful.
|
||||
If ``NULL`` is returned, error occurs and the timer was not configured.
|
||||
|
||||
timerEnd
|
||||
********
|
||||
|
||||
This function is used to end timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerEnd(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
timerSetConfig
|
||||
**************
|
||||
|
||||
This function is used to configure initialized timer (timerBegin() called).
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint32_t timerGetConfig(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``configuration`` as uint32_t number.
|
||||
This can be translated by inserting it to struct ``timer_cfg_t.val``.
|
||||
|
||||
timerAttachInterrupt
|
||||
********************
|
||||
|
||||
This function is used to attach interrupt to timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
* ``fn`` funtion to be called when interrupt is triggered.
|
||||
* ``edge`` select edge to trigger interrupt (only LEVEL trigger is currently supported).
|
||||
|
||||
timerDetachInterrupt
|
||||
********************
|
||||
|
||||
This function is used to detach interrupt from timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerDetachInterrupt(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
timerStart
|
||||
**********
|
||||
|
||||
This function is used to start counter of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerStart(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
timerStop
|
||||
*********
|
||||
|
||||
This function is used to stop counter of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerStop(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
timerRestart
|
||||
************
|
||||
|
||||
This function is used to restart counter of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerRestart(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
timerWrite
|
||||
**********
|
||||
|
||||
This function is used to set counter value of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerWrite(hw_timer_t *timer, uint64_t val);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
* ``val`` counter value to be set.
|
||||
|
||||
timerSetDivider
|
||||
***************
|
||||
|
||||
This function is used to set the divider of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerSetDivider(hw_timer_t *timer, uint16_t divider);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
* ``divider`` divider to be set.
|
||||
|
||||
timerSetCountUp
|
||||
***************
|
||||
|
||||
This function is used to configure counting direction of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerSetCountUp(hw_timer_t *timer, bool countUp);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
* ``countUp`` select counting direction (``true`` = increment).
|
||||
|
||||
timerSetAutoReload
|
||||
******************
|
||||
|
||||
This function is used to set counter value of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerSetAutoReload(hw_timer_t *timer, bool autoreload);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
* ``autoreload`` select autoreload (``true`` = enabled).
|
||||
|
||||
timerStarted
|
||||
************
|
||||
|
||||
This function is used to get if the timer is running.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool timerStarted(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``true`` if the timer is running. If ``false`` is returned, timer is stopped.
|
||||
|
||||
timerRead
|
||||
*********
|
||||
|
||||
This function is used to read counter value of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint64_t timerRead(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``counter value`` of the timer.
|
||||
|
||||
timerReadMicros
|
||||
***************
|
||||
|
||||
This function is used to read counter value in microseconds of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint64_t timerReadMicros(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``counter value`` of the timer in microseconds.
|
||||
|
||||
timerReadMilis
|
||||
**************
|
||||
|
||||
This function is used to read counter value in miliseconds of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint64_t timerReadMilis(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``counter value`` of the timer in miliseconds.
|
||||
|
||||
timerReadSeconds
|
||||
****************
|
||||
|
||||
This function is used to read counter value in seconds of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double timerReadSeconds(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``counter value`` of the timer in seconds.
|
||||
|
||||
timerGetDivider
|
||||
***************
|
||||
|
||||
This function is used to get divider of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint16_t timerGetDivider(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``divider`` of the timer.
|
||||
|
||||
timerGetCountUp
|
||||
***************
|
||||
|
||||
This function is used get counting direction of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool timerGetCountUp(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``true`` if the timer counting direction is UP (incrementing).
|
||||
If ``false`` returned, the timer counting direction is DOWN (decrementing).
|
||||
|
||||
timerGetAutoReload
|
||||
******************
|
||||
|
||||
This function is used to get configuration of auto reload of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool timerGetAutoReload(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``true`` if the timer auto reload is enabled.
|
||||
If ``false`` returned, the timer auto reload is disabled.
|
||||
|
||||
timerAlarmEnable
|
||||
****************
|
||||
|
||||
This function is used to enable generation of timer alarm events.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerAlarmEnable(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
timerAlarmDisable
|
||||
*****************
|
||||
|
||||
This function is used to disable generation of timer alarm events.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerAlarmDisable(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
timerAlarmWrite
|
||||
***************
|
||||
|
||||
This function is used to configure alarm value and autoreload of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
* ``alarm_value`` alarm value to generate event.
|
||||
* ``autoreload`` enabled/disabled autorealod.
|
||||
|
||||
timerAlarmEnabled
|
||||
*****************
|
||||
|
||||
This function is used to get status of timer alarm.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool timerAlarmEnabled(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``true`` if the timer alarm is enabled.
|
||||
If ``false`` returned, the timer alarm is disabled.
|
||||
|
||||
timerAlarmRead
|
||||
**************
|
||||
|
||||
This function is used to read alarm value of the timer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint64_t timerAlarmRead(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
timerAlarmReadMicros
|
||||
********************
|
||||
|
||||
This function is used to read alarm value of the timer in microseconds.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint64_t timerAlarmReadMicros(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``alarm value`` of the timer in microseconds.
|
||||
|
||||
timerAlarmReadSeconds
|
||||
*********************
|
||||
|
||||
This function is used to read alarm value of the timer in seconds.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
double timerAlarmReadSeconds(hw_timer_t *timer);
|
||||
|
||||
* ``timer`` timer struct.
|
||||
|
||||
This function will return ``alarm value`` of the timer in seconds.
|
||||
|
||||
Example Applications
|
||||
********************
|
||||
|
||||
There are 2 examples uses of Timer:
|
||||
|
||||
Repeat timer example:
|
||||
|
||||
.. literalinclude:: ../../../libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino
|
||||
:language: arduino
|
||||
|
||||
Watchdog timer example:
|
||||
|
||||
.. literalinclude:: ../../../libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino
|
||||
:language: arduino
|
@ -34,6 +34,7 @@ Where ``event`` can be:
|
||||
* ARDUINO_USB_CDC_LINE_CODING_EVENT
|
||||
* ARDUINO_USB_CDC_RX_EVENT
|
||||
* ARDUINO_USB_CDC_TX_EVENT
|
||||
* ARDUINO_USB_CDC_RX_OVERFLOW_EVENT
|
||||
* ARDUINO_USB_CDC_MAX_EVENT
|
||||
|
||||
setRxBufferSize
|
||||
|
@ -67,6 +67,35 @@ Use static allocation if you want to have more performance and if your applicati
|
||||
|
||||
By default, the memory allocation will be set to **dynamic** if this function is not being used.
|
||||
|
||||
setDualAntennaConfig
|
||||
********************
|
||||
|
||||
Configures the Dual antenna functionallity. This function should be used only on the **ESP32-WROOM-DA** module or any other ESP32 with RF switch.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2, wifi_rx_ant_t rx_mode, wifi_tx_ant_t tx_mode);
|
||||
|
||||
|
||||
* ``gpio_ant1`` Configure the GPIO number for the antenna 1 connected to the RF switch (default ``GPIO2`` on ESP32-WROOM-DA)
|
||||
* ``gpio_ant2`` Configure the GPIO number for the antenna 2 connected to the RF switch (default ``GPIO25`` on ESP32-WROOM-DA)
|
||||
* ``rx_mode`` Set the RX antenna mode. See wifi_rx_ant_t for the options.
|
||||
* ``tx_mode`` Set the TX antenna mode. See wifi_tx_ant_t for the options.
|
||||
|
||||
Return ``true`` if the configuration was successful.
|
||||
|
||||
For the ``rx_mode`` you can use the following configuration:
|
||||
|
||||
* ``WIFI_RX_ANT0`` Selects the antenna 1 for all RX activity.
|
||||
* ``WIFI_RX_ANT1`` Selects the antenna 2 for all RX activity.
|
||||
* ``WIFI_RX_ANT_AUTO`` Selects the antenna for RX automatically.
|
||||
|
||||
For the ``tx_mode`` you can use the following configuration:
|
||||
|
||||
* ``WIFI_TX_ANT0`` Selects the antenna 1 for all TX activity.
|
||||
* ``WIFI_TX_ANT1`` Selects the antenna 2 for all TX activity.
|
||||
* ``WIFI_TX_ANT_AUTO`` Selects the antenna for TX automatically.
|
||||
|
||||
WiFiAP
|
||||
------
|
||||
|
||||
|
@ -98,18 +98,13 @@ Generic Vendor
|
||||
.. note::
|
||||
Create one file per board or one file with multiple boards. Do not add board information/description on this file.
|
||||
|
||||
.. include:: ../common/datasheet.inc
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* `ESP32 Datasheet`_ (Datasheet)
|
||||
* `ESP32-S2 Datasheet`_ (Datasheet)
|
||||
* `ESP32-C3 Datasheet`_ (Datasheet)
|
||||
|
||||
.. _Espressif Systems: https://www.espressif.com
|
||||
.. _Espressif Product Selector: https://products.espressif.com/
|
||||
.. _ESP32 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
.. _ESP32-S2 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
|
||||
.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
|
||||
|
||||
.. |board_lolin_d32| raw:: html
|
||||
|
||||
|
@ -26,9 +26,4 @@ Pin Layout
|
||||
|
||||
Add here the pin layout image (not required).
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* `ESP32`_ (Datasheet)
|
||||
|
||||
.. _ESP32: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
.. include:: ../common/datasheet.inc
|
||||
|
13
docs/source/common/datasheet.inc
Normal file
13
docs/source/common/datasheet.inc
Normal file
@ -0,0 +1,13 @@
|
||||
Datasheet
|
||||
---------
|
||||
|
||||
* `ESP32`_ (Datasheet)
|
||||
* `ESP32-S2`_ (Datasheet)
|
||||
* `ESP32-C3`_ (Datasheet)
|
||||
* `ESP32-S3`_ (Datasheet)
|
||||
|
||||
.. _Espressif Product Selector: https://products.espressif.com/
|
||||
.. _ESP32: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
.. _ESP32-S2: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
|
||||
.. _ESP32-C3: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
|
||||
.. _ESP32-S3: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf
|
@ -18,11 +18,11 @@ import sys
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'Arduino-ESP32'
|
||||
copyright = '2021, Espressif'
|
||||
copyright = '2022, Espressif'
|
||||
author = 'Espressif'
|
||||
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '2.0.0'
|
||||
release = '2.0.2'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
@ -30,7 +30,8 @@ release = '2.0.0'
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx_copybutton'
|
||||
'sphinx_copybutton',
|
||||
'sphinx_tabs.tabs'
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
|
@ -1,20 +1,31 @@
|
||||
##############################
|
||||
Arduino as a ESP-IDF component
|
||||
##############################
|
||||
###############################
|
||||
Arduino as an ESP-IDF component
|
||||
###############################
|
||||
|
||||
This method is recommended for advanced users. To use this method, you will need to have the ESP-IDF toolchain installed.
|
||||
|
||||
For a simplified method, see `Installing using Boards Manager <https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html#installing-using-boards-manager>`_.
|
||||
|
||||
ESP32 Arduino lib-builder
|
||||
-------------------------
|
||||
|
||||
For a simplified method, see `lib-builder <https://github.com/espressif/esp32-arduino-lib-builder>`_.
|
||||
If you don't need any modifications in the default Arduino ESP32 core, we recommend you to install using the Boards Manager.
|
||||
|
||||
Arduino Lib Builder is the tool that integrates ESP-IDF into Arduino. It allows you to customize the default settings used by Espressif and try them in Arduino IDE.
|
||||
|
||||
For more information see `Arduino lib builder <https://github.com/espressif/esp32-arduino-lib-builder>`_
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
.. note:: Latest Arduino Core ESP32 version is now compatible with `ESP-IDF v4.4 <https://github.com/espressif/esp-idf/tree/release/v4.4>`_. Please consider this compability when using Arduino as component in ESP-IDF.
|
||||
.. note:: Latest Arduino Core ESP32 version is now compatible with `ESP-IDF v4.4 <https://github.com/espressif/esp-idf/tree/release/v4.4>`_. Please consider this compatibility when using Arduino as a component in ESP-IDF.
|
||||
|
||||
- Download and install `ESP-IDF <https://github.com/espressif/esp-idf>`_.
|
||||
- Create blank ESP-IDF project (use sample_project from /examples/get-started) or choose one of the examples.
|
||||
- In the project folder, create a new folder called `components` and clone this repository inside the new created folder.
|
||||
#. Download and install `ESP-IDF <https://github.com/espressif/esp-idf>`_.
|
||||
|
||||
* For more information see `Get Started <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html#installation-step-by-step>`_.
|
||||
#. Create a blank ESP-IDF project (use sample_project from /examples/get-started) or choose one of the examples.
|
||||
#. In the project folder, create a new folder called ``components`` and clone this repository inside the newly created folder.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@ -26,19 +37,33 @@ Installation
|
||||
cd ../.. && \
|
||||
idf.py menuconfig
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
Depending on one of the two following options, in the menuconfig set the appropriate settings.
|
||||
|
||||
Go to the section ``Arduino Configuration --->``
|
||||
|
||||
1. For usage of ``app_main()`` function - Turn off ``Autostart Arduino setup and loop on boot``
|
||||
2. For usage of ``setup()`` and ``loop()`` functions - Turn on ``Autostart Arduino setup and loop on boot``
|
||||
|
||||
Experienced users can explore other options in the Arduino section.
|
||||
|
||||
After the setup you can save and exit:
|
||||
|
||||
- Save [S]
|
||||
- Confirm default filename [Enter]
|
||||
- Close confirmation window [Enter] or [Space] or [Esc]
|
||||
- Quit [Q]
|
||||
|
||||
Option 1. Using Arduino setup() and loop()
|
||||
******************************************
|
||||
|
||||
- The `idf.py menuconfig` has some Arduino options.
|
||||
- Turn on `Autostart Arduino setup and loop on boot`.
|
||||
- In main folder rename file `main.c` to `main.cpp`.
|
||||
- In main folder open file `CMakeList.txt` and change `main.c` to `main.cpp` as described below.
|
||||
- In main folder rename file `main.c` to `main.cpp`.
|
||||
|
||||
.. code-block:: bash
|
||||
- In main folder open file `CMakeList.txt` and change `main.c` to `main.cpp` as described below.
|
||||
|
||||
idf_component_register(SRCS "main.cpp" INCLUDE_DIRS ".")
|
||||
|
||||
- Your main.cpp should be formated like any other sketch.
|
||||
- Your main.cpp should be formatted like any other sketch.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@ -46,7 +71,10 @@ Option 1. Using Arduino setup() and loop()
|
||||
#include "Arduino.h"
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
Serial.begin(115200);
|
||||
while(!Serial){
|
||||
; // wait for serial port to connect
|
||||
}
|
||||
}
|
||||
|
||||
void loop(){
|
||||
@ -57,10 +85,10 @@ Option 1. Using Arduino setup() and loop()
|
||||
Option 2. Using ESP-IDF appmain()
|
||||
*********************************
|
||||
|
||||
- You need to implement ``app_main()`` and call ``initArduino();`` in it.
|
||||
In main.c or main.cpp you need to implement ``app_main()`` and call ``initArduino();`` in it.
|
||||
|
||||
Keep in mind that setup() and loop() will not be called in this case.
|
||||
If you plan to base your code on examples provided in `examples <https://github.com/espressif/esp-idf/tree/master/examples>`_, please make sure to move the app_main() function in main.cpp from the files in the example.
|
||||
Furthermore the ``app_main()`` is single execution as a normal function so if you need an infinite loop as in Arduino place it there.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@ -69,28 +97,39 @@ If you plan to base your code on examples provided in `examples <https://github.
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
initArduino();
|
||||
pinMode(4, OUTPUT);
|
||||
digitalWrite(4, HIGH);
|
||||
//do your own thing
|
||||
}
|
||||
initArduino();
|
||||
|
||||
- "Disable mutex locks for HAL"
|
||||
- If enabled, there will be no protection on the drivers from concurently accessing them from another thread/interrupt/core
|
||||
- "Autoconnect WiFi on boot"
|
||||
- If enabled, WiFi will start with the last known configuration
|
||||
- Otherwise it will wait for WiFi.begin
|
||||
// Arduino-like setup()
|
||||
Serial.begin(115200);
|
||||
while(!Serial){
|
||||
; // wait for serial port to connect
|
||||
}
|
||||
|
||||
// Arduino-like loop()
|
||||
while(true){
|
||||
Serial.println("loop");
|
||||
}
|
||||
|
||||
// WARNING: if program reaches end of function app_main() the MCU will restart.
|
||||
}
|
||||
|
||||
Build, flash and monitor
|
||||
************************
|
||||
|
||||
- For both options use command ``idf.py -p <your-board-serial-port> flash monitor``
|
||||
- It will build, upload and open serial monitor to your board.
|
||||
|
||||
- The project will build, upload and open the serial monitor to your board
|
||||
|
||||
- Some boards require button combo press on the board: press-and-hold Boot button + press-and-release RST button, release Boot button
|
||||
|
||||
- After a successful flash, you may need to press the RST button again
|
||||
|
||||
- To terminate the serial monitor press [Ctrl] + [ ] ]
|
||||
|
||||
Logging To Serial
|
||||
-----------------
|
||||
|
||||
If you are writing code that does not require Arduino to compile and you want your `ESP_LOGx` macros to work in Arduino IDE, you can enable the compatibility by adding the following lines after:
|
||||
If you are writing code that does not require Arduino to compile and you want your `ESP_LOGx` macros to work in Arduino IDE, you can enable the compatibility by adding the following lines:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@ -107,4 +146,4 @@ To fix that behavior, you need to set FreeRTOS tick rate to 1000Hz in `make menu
|
||||
Compilation Errors
|
||||
------------------
|
||||
|
||||
As commits are made to esp-idf and submodules, the codebases can develop incompatibilities which cause compilation errors. If you have problems compiling, follow the instructions in `Issue #1142 <https://github.com/espressif/arduino-esp32/issues/1142>`_ to roll esp-idf back to a different version.
|
||||
As commits are made to esp-idf and submodules, the codebases can develop incompatibilities that cause compilation errors. If you have problems compiling, follow the instructions in `Issue #1142 <https://github.com/espressif/arduino-esp32/issues/1142>`_ to roll esp-idf back to a different version.
|
||||
|
@ -26,6 +26,9 @@ power consumption.
|
||||
|
||||
The ESP32 series is available as a chip or module.
|
||||
|
||||
|
||||
.. _supported_socs:
|
||||
|
||||
Supported SoC's
|
||||
---------------
|
||||
|
||||
@ -34,10 +37,10 @@ Here are the ESP32 series supported by the Arduino-ESP32 project:
|
||||
======== ====== =========== ===================================
|
||||
SoC Stable Development Datasheet
|
||||
======== ====== =========== ===================================
|
||||
ESP32 Yes Yes `ESP32 Datasheet`_
|
||||
ESP32-S2 Yes Yes `ESP32-S2 Datasheet`_
|
||||
ESP32-C3 Yes Yes `ESP32-C3 Datasheet`_
|
||||
ESP32-S3 No No `ESP32-S3 Datasheet`_
|
||||
ESP32 Yes Yes `ESP32`_
|
||||
ESP32-S2 Yes Yes `ESP32-S2`_
|
||||
ESP32-C3 Yes Yes `ESP32-C3`_
|
||||
ESP32-S3 No Yes `ESP32-S3`_
|
||||
======== ====== =========== ===================================
|
||||
|
||||
See `Boards <boards/boards.html>`_ for more details about ESP32 development boards.
|
||||
@ -63,6 +66,20 @@ Supported Operating Systems
|
||||
.. |linux-logo| image:: _static/logo_linux.png
|
||||
.. |macos-logo| image:: _static/logo_macos.png
|
||||
|
||||
Supported IDEs
|
||||
---------------------------
|
||||
|
||||
Here is the list of supported IDE for Arduino ESP32 support integration.
|
||||
|
||||
+-------------------+-------------------+
|
||||
| |arduino-logo| | |pio-logo| |
|
||||
+-------------------+-------------------+
|
||||
| Arduino IDE | PlatformIO |
|
||||
+-------------------+-------------------+
|
||||
|
||||
.. |arduino-logo| image:: _static/logo_arduino.png
|
||||
.. |pio-logo| image:: _static/logo_pio.png
|
||||
|
||||
See `Installing Guides <installing.html>`_ for more details on how to install the Arduino ESP32 support.
|
||||
|
||||
Support
|
||||
@ -91,7 +108,9 @@ Before opening a new issue, please read this:
|
||||
Be sure to search for a similar reported issue. This avoids duplicating or creating noise in the GitHub Issues reporting.
|
||||
We also have the troubleshooting guide to save your time on the most common issues reported by users.
|
||||
|
||||
For more details, see the `Issue Template <https://github.com/espressif/arduino-esp32/blob/master/docs/ISSUE_TEMPLATE.md>`_.
|
||||
For more details about creating new Issue, see the `Issue Template <https://github.com/espressif/arduino-esp32/blob/master/.github/ISSUE_TEMPLATE/Issue-report.yml>`_.
|
||||
|
||||
If you have any new idea, see the `Feature request Template <https://github.com/espressif/arduino-esp32/blob/master/.github/ISSUE_TEMPLATE/Feature-request.yml>`_.
|
||||
|
||||
First Steps
|
||||
-----------
|
||||
@ -114,15 +133,14 @@ in the examples menu or inside each library folder.
|
||||
|
||||
https://github.com/espressif/arduino-esp32/tree/master/libraries
|
||||
|
||||
|
||||
.. include:: common/datasheet.inc
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
.. _Espressif Systems: https://www.espressif.com
|
||||
.. _Espressif Product Selector: https://products.espressif.com/
|
||||
.. _ESP32 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
.. _ESP32-S2 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
|
||||
.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
|
||||
.. _ESP32-S3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf
|
||||
.. _Arduino.cc: https://www.arduino.cc/en/Main/Software
|
||||
.. _Arduino Reference: https://www.arduino.cc/reference/en/
|
||||
.. _ESP32 Forum: https://esp32.com
|
||||
|
334
docs/source/guides/docs_contributing.rst
Normal file
334
docs/source/guides/docs_contributing.rst
Normal file
@ -0,0 +1,334 @@
|
||||
#####################################
|
||||
Documentation Contribution Guidelines
|
||||
#####################################
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This is a guideline for the Arduino ESP32 project documentation. The idea for this guideline is to show how to start collaborating on the project.
|
||||
|
||||
The guideline works to give you the directions and to keep the documentation more concise, helping users to better understand the structure.
|
||||
|
||||
About Documentation
|
||||
-------------------
|
||||
|
||||
We all know how important documentation is. This project is no different.
|
||||
|
||||
This documentation was created in a collaborative and open way, letting everyone contribute, from a small typo fix to a new chapter writing. We try to motivate our community by giving all the support needed through this guide.
|
||||
|
||||
The documentation is in **English only**. Future translations can be added when we finish the essential content in English first.
|
||||
|
||||
How to Collaborate
|
||||
------------------
|
||||
|
||||
Everyone with some knowledge to share is welcome to collaborate.
|
||||
|
||||
One thing you need to consider is the fact that your contribution must be concise and assertive since it will be used by people developing projects. The information is very important for everyone, be sure you are not making the developer's life harder!
|
||||
|
||||
Documentation Guide
|
||||
-------------------
|
||||
|
||||
This documentation is based on the `Sphinx`_ with `reStructuredText`_ and hosted by `ReadTheDocs`_.
|
||||
|
||||
If you want to get started with `Sphinx`_, see the official documentation:
|
||||
|
||||
* `Documentation Index <https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html>`_
|
||||
* `Basics <https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`_
|
||||
* `Directives <https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html>`_
|
||||
|
||||
First Steps
|
||||
***********
|
||||
|
||||
Before starting your collaboration, you need to get the documentation source code from the Arduino-ESP32 project.
|
||||
|
||||
* **Step 1** - Fork the `Arduino-ESP32`_ to your GitHub account.
|
||||
* **Step 2** - Check out the recently created fork.
|
||||
* **Step 3** - Create a new branch for the changes/addition to the docs.
|
||||
* **Step 4** - Write!
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
To properly work with the documentation, you need to install some packages in your system.
|
||||
|
||||
.. code-block::
|
||||
|
||||
pip install -U Sphinx
|
||||
pip install -r requirements.txt
|
||||
|
||||
The requirements file is under the ``docs`` folder.
|
||||
|
||||
Using Visual Studio Code
|
||||
************************
|
||||
|
||||
If you are using the Visual Studio Code, you can install some extensions to help you while writing documentation.
|
||||
|
||||
`reStructuredText Pack <https://marketplace.visualstudio.com/items?itemName=lextudio.restructuredtext-pack>`_
|
||||
|
||||
We also recommend you install to grammar check extension to help you to review English grammar.
|
||||
|
||||
`Grammarly <https://marketplace.visualstudio.com/items?itemName=znck.grammarly>`_
|
||||
|
||||
Building
|
||||
********
|
||||
|
||||
To build the documentation and generate the HTLM files, you can use the following command inside the ``docs`` folder. After a successful build, you can check the files inside the `build/html` folder.
|
||||
|
||||
.. code-block::
|
||||
|
||||
make html
|
||||
|
||||
This step is essential to ensure that there are no syntax errors and also to see the final result.
|
||||
|
||||
If everything is ok, you will see some output logs similar to this one:
|
||||
|
||||
.. code-block::
|
||||
|
||||
Running Sphinx v2.3.1
|
||||
loading pickled environment... done
|
||||
building [mo]: targets for 0 po files that are out of date
|
||||
building [html]: targets for 35 source files that are out of date
|
||||
updating environment: [extensions changed ('sphinx_tabs.tabs')] 41 added, 3 changed, 0 removed
|
||||
reading sources... [100%] tutorials/tutorials
|
||||
looking for now-outdated files... none found
|
||||
pickling environment... done
|
||||
checking consistency... done
|
||||
preparing documents... done
|
||||
writing output... [100%] tutorials/tutorials
|
||||
generating indices... genindexdone
|
||||
writing additional pages... searchdone
|
||||
copying images... [100%] tutorials/../_static/tutorials/peripherals/tutorial_peripheral_diagram.png
|
||||
copying static files... ... done
|
||||
copying extra files... done
|
||||
dumping search index in English (code: en)... done
|
||||
dumping object inventory... done
|
||||
build succeeded.
|
||||
|
||||
The HTML pages are in build/html.
|
||||
|
||||
Sections
|
||||
--------
|
||||
|
||||
The Arduino ESP32 is structured in some sections to make it easier to maintain. Here is a brief description of this structure.
|
||||
|
||||
API
|
||||
***
|
||||
|
||||
In this section, you will include all the documentation about drivers, libraries, and any other related to the core.
|
||||
|
||||
In this section, we do not add general information. For more general information, we have sections for other related parts, like the FAQ, library builder, troubleshooting, etc.
|
||||
|
||||
Boards
|
||||
******
|
||||
|
||||
Here is the place to add any special guide on the development boards, pin layout, schematics, and any other relevant content.
|
||||
|
||||
Common
|
||||
******
|
||||
|
||||
In this folder, you can add all common information used in several different places. This helps to make documentation easily maintainable.
|
||||
|
||||
|
||||
Guides
|
||||
******
|
||||
|
||||
This is the place to add the guides for common applications, IDEs configuration, and any other information that can be used as a guideline.
|
||||
|
||||
Tutorials
|
||||
*********
|
||||
|
||||
If you want to add a specific tutorial related to the Arduino core for ESP32, this is the place. The intention is not to create a blog or a demo area, but this can be used to add some complex description or to add some more information about APIs.
|
||||
|
||||
Images and Assets
|
||||
*****************
|
||||
|
||||
All the files used on the documentation must be stored in the ``_static`` folder. Be sure that the content used is not with any copyright restriction.
|
||||
|
||||
Documentation Rules
|
||||
-------------------
|
||||
|
||||
Here are some guidelines to help you. We also recommend copying a sample file from the same category you are creating.
|
||||
|
||||
This will help you to follow the structure as well as to get inspired.
|
||||
|
||||
Basic Structure
|
||||
***************
|
||||
|
||||
To help you create a new section from scratch, we recommend you include this structure in your content if it applies.
|
||||
|
||||
* **About** - Brief description of the document.
|
||||
* Description of the peripheral, driver, protocol, including all different modes and configurations.
|
||||
* **API** - Description of each public function, macros, and structs.
|
||||
* **Basic Usage**
|
||||
* **Example Application**
|
||||
|
||||
About Section
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
In this section, you need to add a brief description of the API. If you are describing a peripheral API, you should explain a little bit about the peripheral and the working modes, if it's applicable.
|
||||
|
||||
API Functions
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
To add a new function description, you must know that the users only have access to the public functions.
|
||||
|
||||
|
||||
Here is an example of how to add the function description from `I2C API <https://docs.espressif.com/projects/arduino-esp32/en/latest/api/i2c.html>`_:
|
||||
|
||||
.. code-block::
|
||||
|
||||
setPins
|
||||
^^^^^^^
|
||||
|
||||
This function is used to define the ``SDA`` and ``SCL`` pins.
|
||||
|
||||
.. note:: Call this function before ``begin`` to change the pins from the default ones.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool setPins(int sdaPin, int sclPin);
|
||||
|
||||
* ``sdaPin`` sets the GPIO to be used as the I2C peripheral data line.
|
||||
|
||||
* ``sclPin`` sets the GPIO to be used as the I2C peripheral clock line.
|
||||
|
||||
The default pins may vary from board to board. On the *Generic ESP32* the default I2C pins are:
|
||||
|
||||
* ``sdaPin`` **GPIO21**
|
||||
|
||||
* ``sclPin`` **GPIO22**
|
||||
|
||||
This function will return ``true`` if the peripheral was configured correctly.
|
||||
|
||||
Be sure to include a very comprehensive description, add all the parameters in and out, and describe the desired output.
|
||||
|
||||
If the function uses a specific structure, you can also describe the structure in the same function block or add a specific section if the structure is shared with other functions.
|
||||
|
||||
Basic Usage
|
||||
^^^^^^^^^^^
|
||||
|
||||
Some APIs are more complex to use or require more steps in order to configure or initialize. If the API is not straightforward in terms of usability, please consider adding a how-to-use section describing all the steps to get the API configured.
|
||||
|
||||
Here is an example:
|
||||
|
||||
.. code-block::
|
||||
|
||||
Basic Usage
|
||||
^^^^^^^^^^^
|
||||
|
||||
To start using I2C as slave mode on the Arduino, the first step is to include the ``Wire.h`` header to the sketch.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
#include "Wire.h"
|
||||
|
||||
Before calling ``begin``, you must create two callback functions to handle the communication with the master device.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
Wire.onReceive(onReceive);
|
||||
|
||||
and
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
Wire.onRequest(onRequest);
|
||||
|
||||
The ``onReceive`` will handle the request from the ``master`` device upon a slave read request and the ``onRequest`` will handle the answer to the master.
|
||||
|
||||
Now, we can start the peripheral configuration by calling ``begin`` function with the device address.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
Wire.begin((uint8_t)I2C_DEV_ADDR);
|
||||
|
||||
By using ``begin`` without any arguments, all the settings will be done by using the default values. To set the values on your own, see the function description. This function is described here: `i2c begin`_
|
||||
|
||||
|
||||
|
||||
Example Application
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
It is very important to include at least one application example or a code snippet to help people using the API.
|
||||
|
||||
If the API does not have any application example, you can embed the code directly. However, if the example is available, you must include it as a literal block.
|
||||
|
||||
.. code-block::
|
||||
|
||||
.. literalinclude:: ../../../libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino
|
||||
:language: arduino
|
||||
|
||||
|
||||
Sphinx Basics
|
||||
-------------
|
||||
|
||||
Heading Levels
|
||||
**************
|
||||
|
||||
The heading levels used on this documentation are:
|
||||
|
||||
* **H1**: - (Dash)
|
||||
* **H2**: * (Asterisk)
|
||||
* **H3**: ^ (Circumflex)
|
||||
* **H4**: # (Sharp)
|
||||
|
||||
Code Block
|
||||
**********
|
||||
|
||||
To add a code block, you can use the following structure:
|
||||
|
||||
.. code-block::
|
||||
|
||||
.. code-block:: arduino
|
||||
bool begin(); //Code example
|
||||
|
||||
Links
|
||||
*****
|
||||
|
||||
To include links to external content, you can use two ways.
|
||||
|
||||
* First option:
|
||||
|
||||
.. code-block::
|
||||
|
||||
`Arduino Wire Library`_
|
||||
|
||||
_Arduino Wire Library: https://www.arduino.cc/en/reference/wire
|
||||
|
||||
* Second option:
|
||||
|
||||
.. code-block::
|
||||
|
||||
`Arduino Wire Library <https://www.arduino.cc/en/reference/wire>`_
|
||||
|
||||
Images
|
||||
******
|
||||
|
||||
To include images in the docs, first, add all the files into the ``_static`` folder with a filename that makes sense for the topic.
|
||||
|
||||
After that, you can use the following structure to include the image in the docs.
|
||||
|
||||
.. code-block::
|
||||
|
||||
.. figure:: ../_static/arduino_i2c_master.png
|
||||
:align: center
|
||||
:width: 720
|
||||
:figclass: align-center
|
||||
|
||||
You can adjust the ``width`` according to the image size.
|
||||
|
||||
Be sure the file size does not exceed 600kB.
|
||||
|
||||
Support
|
||||
*******
|
||||
|
||||
If you need support on the documentation, you can ask a question in the discussion `here <https://github.com/espressif/arduino-esp32/discussions>`_.
|
||||
|
||||
Additional Guidelines
|
||||
---------------------
|
||||
|
||||
If you want to contribute with code on the Arduino ESP32 core, be sure to follow the `ESP-IDF Documenting Code <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/contribute/documenting-code.html>`_ as a reference.
|
||||
|
||||
.. _Arduino-ESP32: https://github.com/espressif/arduino-esp32
|
||||
.. _Sphinx: https://www.sphinx-doc.org/en/master/
|
||||
.. _ReadTheDocs: https://readthedocs.org/
|
||||
.. _reStructuredText: https://docutils.sourceforge.io/rst.html
|
10
docs/source/guides/guides.rst
Normal file
10
docs/source/guides/guides.rst
Normal file
@ -0,0 +1,10 @@
|
||||
######
|
||||
Guides
|
||||
######
|
||||
|
||||
.. toctree::
|
||||
:caption: Guides:
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
*
|
248
docs/source/guides/tools_menu.rst
Normal file
248
docs/source/guides/tools_menu.rst
Normal file
@ -0,0 +1,248 @@
|
||||
######################
|
||||
Arduino IDE Tools Menu
|
||||
######################
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This guide is a walkthrough of the Arduino IDE configuration menu for the ESP32 System on Chip (SoC's). In this guide, you will see the most relevant configuration
|
||||
to get your project optimized and working.
|
||||
|
||||
Since some boards and SoC's may vary in terms of hardware configuration, be sure you know all the board characteristics that you are using, like flash memory size, SoC variant (ESP32 family), PSRAM, etc.
|
||||
|
||||
.. note:: To help you identify the characteristics, you can see the `Espressif Product Selector`_.
|
||||
|
||||
Arduino IDE
|
||||
-----------
|
||||
|
||||
The Arduino IDE is widely used for ESP32 on Arduino development and offers a wide variety of configurations.
|
||||
|
||||
Tools Menu
|
||||
----------
|
||||
|
||||
To properly configure your project build and flash, some settings must be done in order to get it compiled and flashed without any issues.
|
||||
Some boards are natively supported and almost no configuration is required. However, if your is not yet supported or you have a custom board, you need to configure the environment by yourself.
|
||||
|
||||
For more details or to add a new board, see the `boards.txt`_ file.
|
||||
|
||||
Generic Options
|
||||
---------------
|
||||
|
||||
Most of the options are available for every ESP32 family. Some options will be available only for specific targets, like the USB configuration.
|
||||
|
||||
Board
|
||||
*****
|
||||
|
||||
This option is the target board and must be selected in order to get all the default configuration settings. Once you select the correct board, you will see that some configurations will be automatically selected, but be aware that some boards can have multiple versions (i.e different flash sizes).
|
||||
|
||||
To select the board, go to ``Tools -> Board -> ESP32 Arduino`` and select the target board.
|
||||
|
||||
If your board is not present on this list, you can select the generic ``ESP32-XX Dev Module``.
|
||||
|
||||
Currently, we have one generic development module for each of the supported targets.
|
||||
|
||||
If the board selected belongs to another SoC family, you will see the following information at the build output:
|
||||
|
||||
``A fatal error occurred: This chip is ESP32 not ESP32-S2. Wrong --chip argument?``
|
||||
|
||||
Upload Speed
|
||||
************
|
||||
|
||||
To select the flashing speed, change the ``Tools -> Upload Speed``. This value will be used for flashing the code to the device.
|
||||
|
||||
.. note:: If you have issues while flashing the device at high speed, try to decrease this value. This could be due to the external serial-to-USB chip limitations.
|
||||
|
||||
CPU Frequency
|
||||
*************
|
||||
|
||||
On this option, you can select the CPU clock frequency. This option is critical and must be selected according to the high-frequency crystal present on the board and the radio usage (Wi-Fi and Bluetooth).
|
||||
|
||||
In some applications, reducing the CPU clock frequency is recommended in order to reduce power consumption.
|
||||
|
||||
If you don't know why you should change this frequency, leave the default option.
|
||||
|
||||
Flash Frequency
|
||||
***************
|
||||
|
||||
Use this function to select the flash memory frequency. The frequency will be dependent on the memory model.
|
||||
|
||||
* **40MHz**
|
||||
* **80MHz**
|
||||
|
||||
If you don't know if your memory supports **80Mhz**, you can try to upload the sketch using the **80MHz** option and watch the log output via the serial monitor.
|
||||
|
||||
.. note:: In some boards/SoC, the flash frequency is automatically selected according to the flash mode. In some cases (i.e ESP32-S3), the flash frequency is up to 120MHz.
|
||||
|
||||
Flash Mode
|
||||
**********
|
||||
|
||||
This option is used to select the SPI communication mode with the flash memory.
|
||||
|
||||
Depending on the application, this mode can be changed in order to increase the flash communication speed.
|
||||
|
||||
* **QIO** - Quad I/O Fast Read
|
||||
* Four SPI pins are used to write to the flash and to read from the flash.
|
||||
|
||||
* **DIO** - Dual I/O Fast Read
|
||||
* Two SPI pins are used to write to the flash and to read from the flash.
|
||||
|
||||
* **QOUT** - Quad Output Fast Read
|
||||
* Four SPI pins are used to read the flash data.
|
||||
|
||||
* **DOUT** - Dual Output Fast Read
|
||||
* Two SPI pins are used to read flash data.
|
||||
|
||||
* **OPI** - Octal I/O
|
||||
* Eight SPI pins are used to write and to read from the flash.
|
||||
|
||||
If you don't know how the board flash is physically connected or the flash memory model, try the **QIO** at **80MHz** first.
|
||||
|
||||
Flash Size
|
||||
**********
|
||||
|
||||
This option is used to select the flash size. The flash size should be selected according to the flash model used on your board.
|
||||
|
||||
* **2MB** (16Mb)
|
||||
* **4MB** (32Mb)
|
||||
* **8MB** (64Mb)
|
||||
* **16MB** (128Mb)
|
||||
|
||||
If you choose the wrong size, you may have issues when selecting the partition scheme.
|
||||
|
||||
Embedded Flash
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Some SoC has embedded flash. The ESP32-S3 is a good example.
|
||||
|
||||
.. note:: Check the manufacturer part number of your SoC/module to see the right version.
|
||||
|
||||
Example: **ESP32-S3FH4R2**
|
||||
|
||||
This particular ESP32-S3 variant comes with 4MB Flash and 2MB PSRAM.
|
||||
|
||||
**Options for Embedded Flash**
|
||||
|
||||
* **Fx4** 4MB Flash (*QIO*)
|
||||
* **Fx8** 8MB Flash (*QIO*)
|
||||
* **V** 1.8V SPI
|
||||
|
||||
The **x** stands for the temperature range specification.
|
||||
|
||||
* **H** High Temperature (*-40 to 85ºC*)
|
||||
* **N** Low Temeprature (*-40 to 65ºC*)
|
||||
|
||||
For more details, please see the corresponding datasheet at `Espressif Product Selector`_.
|
||||
|
||||
Partition Scheme
|
||||
****************
|
||||
|
||||
This option is used to select the partition model according to the flash size and the resources needed, like storage area and OTA (Over The Air updates).
|
||||
|
||||
.. note:: Be careful selecting the right partition according to the flash size. If you select the wrong partition, the system will crash.
|
||||
|
||||
Core Debug Level
|
||||
****************
|
||||
|
||||
This option is used to select the Arduino core debugging level to be printed to the serial debug.
|
||||
|
||||
* **None** - Prints nothing.
|
||||
* **Error** - Only at error level.
|
||||
* **Warning** - Only at warning level and above.
|
||||
* **Info** - Only at info level and above.
|
||||
* **Debug** - Only at debug level and above.
|
||||
* **Verbose** - Prints everything.
|
||||
|
||||
PSRAM
|
||||
*****
|
||||
|
||||
The PSRAM is an internal or external extended RAM present on some boards, modules or SoC.
|
||||
|
||||
This option can be used to ``Enable`` or ``Disable`` PSRAM. In some SoCs, you can select the PSRAM mode as the following.
|
||||
|
||||
* **QSPI PSRAM** - Quad PSRAM
|
||||
* **OPI PSRAM** - Octal PSRAM
|
||||
|
||||
Embedded PSRAM
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Some SoC has embedded PSRAM. The ESP32-S3 is a good example.
|
||||
|
||||
Example: **ESP32-S3FH4R2**
|
||||
|
||||
This particular ESP32-S3 comes with 4MB Flash and 2MB PSRAM.
|
||||
|
||||
**Options for Embedded Flash and PSRAM**
|
||||
|
||||
* **R2** 2MB PSRAM (*QSPI*)
|
||||
* **R8** 8MB PSRAM (*OPI*)
|
||||
* **V** 1.8V SPI
|
||||
|
||||
The **x** stands for the temperature range specification.
|
||||
|
||||
* **H** High Temperature (*-40 to 85ºC*)
|
||||
* **N** Low Temeprature (*-40 to 65ºC*)
|
||||
|
||||
For more details, please see the corresponding datasheet at `Espressif Product Selector`_.
|
||||
|
||||
Arduino Runs On
|
||||
***************
|
||||
|
||||
This function is used to select the core that runs the Arduino core. This is only valid if the target SoC has 2 cores.
|
||||
|
||||
When you have some heavy task running, you might want to run this task on a different core than the Arduino tasks. For this reason, you have this configuration to select the right core.
|
||||
|
||||
Events Run On
|
||||
*************
|
||||
|
||||
This function is also used to select the core that runs the Arduino events. This is only valid if the target SoC has 2 cores.
|
||||
|
||||
Port
|
||||
****
|
||||
|
||||
This option is used to select the serial port to be used on the flashing and monitor.
|
||||
|
||||
USB Options
|
||||
-----------
|
||||
|
||||
Some ESP32 families have a USB peripheral. This peripheral can be used for flashing and debugging.
|
||||
|
||||
To see the supported list for each SoC, see this section: `Libraries <../libraries.html>`_.
|
||||
|
||||
The USB option will be available only if the correct target is selected.
|
||||
|
||||
USB CDC On Boot
|
||||
***************
|
||||
|
||||
The USB Communications Device Class, or USB CDC, is a class used for basic communication to be used as a regular serial controller (like RS-232).
|
||||
|
||||
This class is used for flashing the device without any other external device attached to the SoC.
|
||||
|
||||
This option can be used to ``Enable`` or ``Disable`` this function at the boot. If this option is ``Enabled``, once the device is connected via USB, one new serial port will appear in the list of the serial ports.
|
||||
Use this new serial port for flashing the device.
|
||||
|
||||
This option can be used as well for debugging via the ``Serial Monitor`` using **CDC** instead of the **UART0**.
|
||||
|
||||
To use the UART as serial output, you can use ``Serial0.print("Hello World!");`` instead of ``Serial.print("Hello World!");`` which will be printed using USB CDC.
|
||||
|
||||
USB Firmware MSC On Boot
|
||||
************************
|
||||
|
||||
The USB Mass Storage Class, or USB MSC, is a class used for storage devices, like a USB flash drive.
|
||||
|
||||
This option can be used to ``Enable`` or ``Disable`` this function at the boot. If this option is ``Enabled``, once the device is connected via USB, one new storage device will appear in the system as a storage drive.
|
||||
Use this new storage drive to write and read files or to drop a new firmware binary to flash the device.
|
||||
|
||||
.. figure:: ../_static/usb_msc_drive.png
|
||||
:align: center
|
||||
:width: 720
|
||||
:figclass: align-center
|
||||
|
||||
USB DFU On Boot
|
||||
***************
|
||||
|
||||
The USB Device Firmware Upgrade is a class used for flashing the device through USB.
|
||||
|
||||
This option can be used to ``Enable`` or ``Disable`` this function at the boot. If this option is ``Enabled``, once the device is connected via USB, the device will appear as a USB DFU capable device.
|
||||
|
||||
.. _Espressif Product Selector: https://products.espressif.com/
|
||||
.. _boards.txt: https://github.com/espressif/arduino-esp32/blob/master/boards.txt
|
@ -8,11 +8,12 @@ Here you will find all the relevant information about the project.
|
||||
This is a work in progress documentation and we will appreciate your help! We are looking for contributors!
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:maxdepth: 1
|
||||
:caption: Contents:
|
||||
|
||||
Getting Started <getting_started>
|
||||
Libraries <libraries>
|
||||
Guides <guides/guides>
|
||||
Tutorials <tutorials/tutorials>
|
||||
Advanced Utilities <advanced_utils>
|
||||
FAQ <faq>
|
||||
|
@ -7,16 +7,21 @@ This guide will show how to install the Arduino-ESP32 support.
|
||||
Before Installing
|
||||
-----------------
|
||||
|
||||
We recommend you install the support using the Boards Manager, but other options are available depending on your operating system.
|
||||
We recommend you install the support using your favorite IDE, but other options are available depending on your operating system.
|
||||
To install Arduino-ESP32 support, you can use one of the following options.
|
||||
|
||||
Installing using Boards Manager
|
||||
-------------------------------
|
||||
Installing using Arduino IDE
|
||||
----------------------------
|
||||
|
||||
This is the preferred and easiest way to install Arduino-ESP32.
|
||||
.. figure:: _static/logo_arduino.png
|
||||
:align: center
|
||||
:width: 200
|
||||
:figclass: align-center
|
||||
|
||||
This is the way to install Arduino-ESP32 directly from the Arduino IDE.
|
||||
|
||||
.. note::
|
||||
Currently, the support for new chips (ESP32-S2 and ESP32-C3) is in the development release. Consider installing the development release if you need to test the new supported SoC in beta.
|
||||
For overview of SoC's support, take a look on `Supported Soc's table <https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html#supported-soc-s>`_ where you can find if the particular chip is under stable or development release.
|
||||
|
||||
- Stable release link::
|
||||
|
||||
@ -58,8 +63,92 @@ To start the installation process using the Boards Managaer, follow these steps:
|
||||
|
||||
- Restart Arduino IDE.
|
||||
|
||||
Windows
|
||||
-------
|
||||
Installing using PlatformIO
|
||||
---------------------------
|
||||
|
||||
.. figure:: _static/logo_pio.png
|
||||
:align: center
|
||||
:width: 200
|
||||
:figclass: align-center
|
||||
|
||||
PlatformIO is a professional collaborative platform for embedded development. It has out-of-the-box support for ESP32 SoCs and allows working with Arduino ESP32 as well as ESP-IDF from Espressif without changing your development environment. PlatformIO includes lots of instruments for the most common development tasks such as debugging, unit testing, and static code analysis.
|
||||
|
||||
A detailed overview of the PlatformIO ecosystem and its philosophy can be found in `the official documentation <https://docs.platformio.org/en/latest/core/index.html>`_.
|
||||
|
||||
PlatformIO can be used in two flavors:
|
||||
|
||||
- `PlatformIO IDE <https://platformio.org/platformio-ide>`_ is a toolset for embedded C/C++ development available on Windows, macOS and Linux platforms
|
||||
|
||||
- `PlatformIO Core (CLI) <https://docs.platformio.org/en/latest/core/index.html>`_ is a command-line tool that consists of a multi-platform build system, platform and library managers and other integration components. It can be used with a variety of code development environments and allows integration with cloud platforms and web services
|
||||
|
||||
To install PlatformIO, you can follow this Getting Started, provided at `docs.platformio.org`_.
|
||||
|
||||
Using the stable code
|
||||
*********************
|
||||
|
||||
.. note::
|
||||
A detailed overview of supported development boards, examples and frameworks can be found on `the official Espressif32 dev-platform page <https://registry.platformio.org/platforms/platformio/espressif32>`_ in the PlatformIO Registry.
|
||||
|
||||
The most reliable and easiest way to get started is to use the latest stable version of the ESP32 development platform that passed all tests/verifications and can be used in production.
|
||||
|
||||
Create a new project and select one of the available boards. You can change after by changing the `platformio.ini <https://docs.platformio.org/en/latest/projectconf/index.html>`_ file.
|
||||
|
||||
- For ESP32
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
|
||||
- For ESP32-S2 (ESP32-S2-Saola-1 board)
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[env:esp32-s2-saola-1]
|
||||
platform = espressif32
|
||||
board = esp32-s2-saola-1
|
||||
framework = arduino
|
||||
|
||||
- For ESP32-C3 (ESP32-C3-DevKitM-1 board)
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[env:esp32-c3-devkitm-1]
|
||||
platform = espressif32
|
||||
board = esp32-c3-devkitm-1
|
||||
framework = arduino
|
||||
|
||||
How to update to the latest code
|
||||
********************************
|
||||
|
||||
To test the latest Arduino ESP32, you need to change your project *platformio.ini* accordingly.
|
||||
The following configuration uses the upstream version of the Espressif development platform and the latest Arduino core directly from the Espressif GitHub repository:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[env:esp32-c3-devkitm-1]
|
||||
platform = https://github.com/platformio/platform-espressif32.git
|
||||
board = esp32-c3-devkitm-1
|
||||
framework = arduino
|
||||
platform_packages =
|
||||
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#master
|
||||
|
||||
|
||||
To get more information about PlatformIO, see the following links:
|
||||
|
||||
- `PlatformIO Core (CLI) <https://docs.platformio.org/en/latest/core/index.html>`_
|
||||
|
||||
- `PlatformIO Home <https://docs.platformio.org/en/latest/home/index.html>`_
|
||||
|
||||
- `Tutorials and Examples <https://docs.platformio.org/en/latest/tutorials/index.html>`_
|
||||
|
||||
- `Library Management <https://docs.platformio.org/en/latest/librarymanager/index.html>`_
|
||||
|
||||
|
||||
Windows (manual installation)
|
||||
-----------------------------
|
||||
|
||||
.. warning:: Arduino ESP32 core v2.x.x cannot be used on Windows 8.x x86 (32 bits), Windows 7 or earlier. The Windows 32 bits OS is no longer supported by this toolchain.
|
||||
|
||||
@ -150,6 +239,11 @@ How to update to the latest code
|
||||
Linux
|
||||
-----
|
||||
|
||||
.. figure:: _static/logo_linux.png
|
||||
:align: center
|
||||
:width: 200
|
||||
:figclass: align-center
|
||||
|
||||
Debian/Ubuntu
|
||||
*************
|
||||
|
||||
@ -263,20 +357,5 @@ Where ``~/Documents/Arduino`` represents your sketch book location as per "Ardui
|
||||
|
||||
- Restart Arduino IDE.
|
||||
|
||||
PlatformIO
|
||||
----------
|
||||
|
||||
- `What is PlatformIO? <https://docs.platformio.org/en/latest/what-is-platformio.html?utm_source=github&utm_medium=arduino-esp32>`_
|
||||
|
||||
- `PlatformIO IDE <https://platformio.org/platformio-ide?utm_source=github&utm_medium=arduino-esp32>`_
|
||||
|
||||
- `PlatformIO Core <https://docs.platformio.org/en/latest/core.html?utm_source=github&utm_medium=arduino-esp32>`_
|
||||
|
||||
- `Advanced usage <https://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32>`_: Custom settings, uploading to SPIFFS, Over-the-Air (OTA), staging version
|
||||
|
||||
- `Integration with Cloud and Standalone IDEs <https://docs.platformio.org/en/latest/ide.html?utm_source=github&utm_medium=arduino-esp32>`_: Cloud9, Codeanywhere, Eclipse Che (Codenvy), Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, VIM, Visual Studio, and VSCode
|
||||
|
||||
- `Project Examples <https://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32#examples>`_
|
||||
|
||||
|
||||
.. _Arduino.cc: https://www.arduino.cc/en/Main/Software
|
||||
.. _docs.platformio.org: https://docs.platformio.org/en/latest/integration/ide/pioide.html
|
||||
|
@ -2,37 +2,178 @@
|
||||
Library Builder
|
||||
###############
|
||||
|
||||
How to Use Library Builder
|
||||
--------------------------
|
||||
About
|
||||
-----
|
||||
|
||||
Espressif has provided a `tool <https://github.com/espressif/esp32-arduino-lib-builder>`_ to simplify building your own compiled libraries for use in Arduino IDE (or your favorite IDE).
|
||||
To generate custom libraries, follow these steps:
|
||||
Espressif provides a `tool <https://github.com/espressif/esp32-arduino-lib-builder>`_ to simplify building your own compiled libraries for use in Arduino IDE (or your favorite IDE).
|
||||
|
||||
This tool can be used to change the project or a specific configuration according to your needs.
|
||||
|
||||
- Step 1 - Clone the ESP32 Arduino lib builder::
|
||||
Installing
|
||||
----------
|
||||
|
||||
To install the Library Builder into your environment, please, follow the instructions below.
|
||||
|
||||
- Clone the ESP32 Arduino lib builder:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://github.com/espressif/esp32-arduino-lib-builder
|
||||
|
||||
- Step 2 - Go to the ``esp32-arduino-lib-builder`` folder::
|
||||
- Go to the ``esp32-arduino-lib-builder`` folder:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd esp32-arduino-lib-builder
|
||||
|
||||
- Step 3 - Run the ``update-components`` script::
|
||||
- Build:
|
||||
|
||||
./tools/update-components.sh`
|
||||
.. code-block:: bash
|
||||
|
||||
- Step 4 - Run ``install-esp-idf`` installation script (if you already have an ``$IDF_PATH`` defined, it will use your local copy of the repository)::
|
||||
./build.sh
|
||||
|
||||
./tools/install-esp-idf.sh
|
||||
If everything works, you may see the following message: ``Successfully created esp32 image.``
|
||||
|
||||
- Step 5 - Copy the configuration (recommended) or directly edit sdkconfig using ``idf.py menuconfig``::
|
||||
Dependencies
|
||||
************
|
||||
|
||||
cp sdkconfig.esp32s2 sdkconfig
|
||||
To build the library you will need to install some dependencies. Maybe you already have installed it, but it is a good idea to check before building.
|
||||
|
||||
- Step 6 - Build::
|
||||
- Install all dependencies (**Ubuntu**):
|
||||
|
||||
idf.py build
|
||||
.. code-block:: bash
|
||||
|
||||
The script automates the process of building `Arduino as an ESP-IDF component <https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md>`_.
|
||||
Once it is complete, you can cherry pick the needed libraries from ``out/tools/sdk/lib``, or run ``tools/copy-to-arduino.sh`` to copy the entire built system.
|
||||
``tools/config.sh`` contains a number of variables that control the process, particularly the ``$IDF_BRANCH`` variable. You can adjust this to try building against newer versions, but there are absolutely no guarantees that any components will work or even successfully compile against a newer IDF.
|
||||
sudo apt-get install git wget curl libssl-dev libncurses-dev flex bison gperf cmake ninja-build ccache jq
|
||||
|
||||
- Install Python and upgrade pip:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install python3
|
||||
sudo pip install --upgrade pip
|
||||
|
||||
- Install all required packages:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install --user setuptools pyserial click cryptography future pyparsing pyelftools
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
If you have all the dependencies met, it is time to build the libraries.
|
||||
|
||||
To build using the default configuration:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh
|
||||
|
||||
Custom Build
|
||||
************
|
||||
|
||||
There are some options to help you create custom libraries. You can use the following options:
|
||||
|
||||
Usage
|
||||
^^^^^
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
build.sh [-s] [-A arduino_branch] [-I idf_branch] [-i idf_commit] [-c path] [-t <target>] [-b <build|menuconfig|idf_libs|copy_bootloader|mem_variant>] [config ...]
|
||||
|
||||
Skip Install/Update
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Skip installing/updating of ESP-IDF and all components
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -s
|
||||
|
||||
This option can be used if you already have the ESP-IDF and all components already in your environment.
|
||||
|
||||
Set Arduino-ESP32 Branch
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Set which branch of arduino-esp32 to be used for compilation
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -A <arduino_branch>
|
||||
|
||||
Set ESP-IDF Branch
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Set which branch of ESP-IDF is to be used for compilation
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -I <idf_branch>
|
||||
|
||||
Set the ESP-IDF Commit
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Set which commit of ESP-IDF to be used for compilation
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -i <idf_commit>
|
||||
|
||||
Deploy
|
||||
^^^^^^
|
||||
|
||||
Deploy the build to github arduino-esp32
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -d
|
||||
|
||||
Set the Arduino-ESP32 Destination Folder
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Set the arduino-esp32 folder to copy the result to. ex. '$HOME/Arduino/hardware/espressif/esp32'
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -c <path>
|
||||
|
||||
This function is used to copy the compiled libraries to the Arduino folder.
|
||||
|
||||
Set the Target
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Set the build target(chip). ex. 'esp32s3'
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -t <target>
|
||||
|
||||
This build command will build for the ESP32-S3 target. You can specify other targets.
|
||||
|
||||
* esp32
|
||||
* esp32s2
|
||||
* esp32c3
|
||||
* esp32s3
|
||||
|
||||
Set Build Type
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Set the build type. ex. 'build' to build the project and prepare for uploading to a board.
|
||||
|
||||
.. note:: This command depends on the ``-t`` argument.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -t esp32 -b <build|menuconfig|idf_libs|copy_bootloader|mem_variant>
|
||||
|
||||
Additional Configuration
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Specify additional configs to be applied. ex. 'qio 80m' to compile for QIO Flash@80MHz. Requires -b
|
||||
|
||||
.. note:: This command requires the ``-b`` to work properly.
|
||||
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./build.sh -t esp32 -b idf_libs qio 80m
|
||||
|
@ -28,7 +28,7 @@ Currently, the Arduino ESP32 supports the following peripherals with Arduino API
|
||||
+---------------+---------------+---------------+---------------+-------------------------------+
|
||||
| I2C | Yes | Yes | Yes | |
|
||||
+---------------+---------------+---------------+---------------+-------------------------------+
|
||||
| I2S | No | No | No | WIP |
|
||||
| I2S | Yes | No | No | WIP |
|
||||
+---------------+---------------+---------------+---------------+-------------------------------+
|
||||
| LEDC | Yes | Yes | Yes | |
|
||||
+---------------+---------------+---------------+---------------+-------------------------------+
|
||||
@ -64,12 +64,7 @@ Notes
|
||||
|
||||
.. note:: Some peripherals are not available for all ESP32 families. To see more details about it, see the corresponding SoC at `Product Selector <https://products.espressif.com>`_ page.
|
||||
|
||||
Datasheet
|
||||
^^^^^^^^^
|
||||
|
||||
* `ESP32 <https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf>`_
|
||||
* `ESP32-S2 <https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf>`_
|
||||
* `ESP32-C3 <https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf>`_
|
||||
.. include:: common/datasheet.inc
|
||||
|
||||
APIs
|
||||
----
|
||||
@ -78,13 +73,6 @@ The Arduino ESP32 offers some unique APIs, described in this section:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Bluetooth <api/bluetooth>
|
||||
Deep Sleep <api/deepsleep>
|
||||
ESPNOW <api/espnow>
|
||||
GPIO <api/gpio>
|
||||
I2C <api/i2c>
|
||||
RainMaker <api/rainmaker>
|
||||
Reset Reason <api/reset_reason>
|
||||
USB <api/usb.rst>
|
||||
Wi-Fi <api/wifi>
|
||||
:glob:
|
||||
|
||||
api/*
|
||||
|
@ -62,7 +62,7 @@ JTAG Dedicated GPIOs
|
||||
SD/SDIO/MMC HostController Dedicated GPIOs
|
||||
Motor PWM Any GPIO
|
||||
SDIO/SPI SlaveController Dedicated GPIOs
|
||||
UART Any GPIO
|
||||
UART Any GPIO[1]
|
||||
I2C Any GPIO
|
||||
I2S Any GPIO
|
||||
LED PWM Any GPIO
|
||||
@ -72,8 +72,11 @@ Parallel QSPI Dedicated GPIOs
|
||||
EMAC Dedicated GPIOs
|
||||
Pulse Counter Any GPIO
|
||||
TWAI Any GPIO
|
||||
USB Dedicated GPIOs
|
||||
============================== ===================================
|
||||
|
||||
[1] except for the download/programming mode decided by the bootloader.
|
||||
|
||||
This table is present on each datasheet provided by Espressif.
|
||||
|
||||
Usage Examples
|
||||
@ -106,16 +109,11 @@ To change the pins, we must call the ``Wire.setPins(int sda, int scl);`` functio
|
||||
|
||||
A similar approach also applies for the other peripherals.
|
||||
|
||||
.. include:: ../common/datasheet.inc
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* `ESP32`_ (Datasheet)
|
||||
* `ESP32-S2`_ (Datasheet)
|
||||
* `ESP32-C3`_ (Datasheet)
|
||||
|
||||
.. _Espressif Systems: https://www.espressif.com
|
||||
.. _Espressif Product Selector: https://products.espressif.com/
|
||||
.. _ESP32: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
.. _ESP32-S2: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
|
||||
.. _ESP32-C3: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
|
||||
.. _IO MUX GPIO: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#iomuxgpio
|
||||
|
697
docs/source/tutorials/preferences.rst
Normal file
697
docs/source/tutorials/preferences.rst
Normal file
@ -0,0 +1,697 @@
|
||||
###########
|
||||
Preferences
|
||||
###########
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The Preferences library is unique to arduino-esp32. It should be considered as the replacement for the Arduino EEPROM library.
|
||||
|
||||
It uses a portion of the on-board non-volatile memory (NVS) of the ESP32 to store data. This data is retained across restarts and loss of power events to the system.
|
||||
|
||||
Preferences works best for storing many small values, rather than a few large values. If you need to store large amounts of data, consider using a file system library such as LitteFS.
|
||||
|
||||
The Preferences library is usable by all ESP32 variants.
|
||||
|
||||
|
||||
Preferences Attributes
|
||||
----------------------
|
||||
|
||||
Preferences data is stored in NVS in sections called a "``namespace``". Within each namespace are a set of ``key-value`` pairs. The "``key``" is the name of the data item and the "``value``" is, well, the value of that piece of data. Kind of like variables. The key is the name of the variable and the value is its value. Like variables, a ``key-value`` pair has a data type.
|
||||
|
||||
Multiple namespaces are permitted within NVS. The name of each namespace must be unique. The keys within that namespace are unique to that namespace. Meaning the same key name can be used in multiple namespaces without conflict.
|
||||
|
||||
Namespace and key names are case sensitive.
|
||||
|
||||
Each key name must be unique within a namespace.
|
||||
|
||||
Namespace and key names are character strings and are limited to a maximum of 15 characters.
|
||||
|
||||
Only one namespace can be open (in use) at a time.
|
||||
|
||||
|
||||
Library Overview
|
||||
----------------
|
||||
|
||||
Library methods are provided to:
|
||||
- create a namespace;
|
||||
- open and close a namespace;
|
||||
- store and retrieve data within a namespace for supported data types;
|
||||
- determine if a key value has been initialized;
|
||||
- delete a ``key-value`` pair;
|
||||
- delete all ``key-value`` pairs in a namespace;
|
||||
- determine data types stored against a key;
|
||||
- determine the number of key entries available in the namespace.
|
||||
|
||||
Preferences directly suports the following data types:
|
||||
|
||||
.. table:: **Table 1 — Preferences Types**
|
||||
:align: center
|
||||
|
||||
+-------------------+-------------------+---------------+
|
||||
| Preferences Type | Data Type | Size (bytes) |
|
||||
+===================+===================+===============+
|
||||
| Bool | bool | 1 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Char | int8_t | 1 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| UChar | uint8_t | 1 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Short | int16_t | 2 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| UShort | uint16_t | 2 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Int | int32_t | 4 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| UInt | uint32_t | 4 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Long | int32_t | 4 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| ULong | uint32_t | 4 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Long64 | int64_t | 8 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| ULong64 | uint64_t | 8 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Float | float_t | 8 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Double | double_t | 8 |
|
||||
+-------------------+-------------------+---------------+
|
||||
| | const char* | |
|
||||
| String +-------------------+ variable |
|
||||
| | String | |
|
||||
+-------------------+-------------------+---------------+
|
||||
| Bytes | uint8_t | variable |
|
||||
+-------------------+-------------------+---------------+
|
||||
|
||||
String values can be stored and retrieved either as an Arduino String or as a null terminated ``char`` array (C-string).
|
||||
|
||||
Bytes type is used for storing and retrieving an arbitrary number of bytes in a namespace.
|
||||
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
Preferences workflow, once everything is initialized, is pretty simple.
|
||||
|
||||
To store a value:
|
||||
- Open the namespace in read-write mode.
|
||||
- Put the value into the key.
|
||||
- Close the namespace.
|
||||
|
||||
To retrieve a value:
|
||||
- Open the namespace in read-only mode.
|
||||
- Use the key to get the value.
|
||||
- Close the namespace.
|
||||
|
||||
*(Technically, you can retrieve a value if the namespace is open in either read-only or read-write mode but it's good practice to open the namespace in read-only mode if you are only retrieving values.)*
|
||||
|
||||
When storing information, a "``put[PreferencesType]``" method referenced to its key is used.
|
||||
|
||||
When retrieving information a "``get[PreferencesType]``" method referenced to its key is used.
|
||||
|
||||
Ensuring that the data types of your “``get``'s” and “``put``'s” all match, you’re good to go.
|
||||
|
||||
The nuance is in initializing everything at the start.
|
||||
|
||||
Before you can store or retrieve anything using Preferences, both the namespace and the key within that namespace need to exist. So the workflow is:
|
||||
|
||||
#. Create or open the namespace.
|
||||
#. Test for the existence of a key that should exist if the namespace has been initialized.
|
||||
#. If that key does not exist, create the key(s).
|
||||
#. Carry on with the rest of your sketch where data can now be stored and retrieved from the namespace.
|
||||
|
||||
Each step is discussed below.
|
||||
|
||||
.. note::
|
||||
|
||||
From here on when referring in general to a method used to store or retrieve data we'll use the shorthand "``putX``" and "``getX``" where the "``X``" is understood to be a Preferences Type; Bool, UInt, Char, and so on from the Preferences Types table above.
|
||||
|
||||
..
|
||||
|
||||
|
||||
Create or Open the Namespace
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In your sketch, first insert a declaration of a ``Preferences`` object by including a line like;
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
Preferences mySketchPrefs; // "mySketchPrefs" is the name of the Preferences object.
|
||||
// Can be whatever you want.
|
||||
|
||||
This object is used with the Preferences methods to access the namespace and the key-value pairs it contains.
|
||||
|
||||
A namespace is made available for use with the ``.begin`` method:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
mySketchPrefs.begin("myPrefs", false)
|
||||
|
||||
If the namespace does not yet exist, this will create and then open the namespace ``myPrefs``.
|
||||
|
||||
If the namespace already exists, this will open the namespace ``myPrefs``.
|
||||
|
||||
If the second argument is ``false`` the namespace is opened in read-write (RW) mode — values can be stored in to and retrieved from the namespace. If it is ``true`` the namespace is opened in read-only (RO) mode — values can be retrieved from the namespace but nothing can be stored.
|
||||
|
||||
|
||||
Test for Initial Existence of Your Key(s)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the ESP32 boots, there is no inherent way to know if this is the very first time it has ever powered on or if it is a subsequent launch and it has run its sketch before. We can use Preferences to store information that is retained across reboots that we can read, and based on that, decide if this is a first-time run and take the required actions if so.
|
||||
|
||||
We do this by testing for the existence of a certain key within a namespace. If that key exists, it is safe to assume the key was created during the first-time run of the sketch and so the namespace has already been initialized.
|
||||
|
||||
To determine if a key exists, use:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
isKey("myTestKey")
|
||||
|
||||
This returns ``true`` if ``"myTestKey"`` exists in the namespace, and ``false`` if it does not.
|
||||
|
||||
By example, consider this code segment:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
Preferences mySketchPrefs;
|
||||
String doesExist;
|
||||
|
||||
mySketchPrefs.begin("myPrefs", false); // open (or create and then open if it does not
|
||||
// yet exist) the namespace "myPrefs" in RW mode.
|
||||
|
||||
bool doesExist = mySketchPrefs.isKey("myTestKey");
|
||||
|
||||
if (doesExist == false) {
|
||||
/*
|
||||
If doesExist is false, we will need to create our
|
||||
namespace key(s) and store a value into them.
|
||||
*/
|
||||
|
||||
// Insert your "first time run" code to create your keys & assign their values below here.
|
||||
}
|
||||
else {
|
||||
/*
|
||||
If doesExist is true, the key(s) we need have been created before
|
||||
and so we can access their values as needed during startup.
|
||||
*/
|
||||
|
||||
// Insert your "we've been here before" startup code below here.
|
||||
}
|
||||
|
||||
|
||||
|
||||
Creating Namespace Keys and Storing Values
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To create a key, we use one of the ``.putX`` methods, matching ``"X"`` to the Preferences Type of the data we wish to store:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
myPreferences.putX("myKeyName", value)
|
||||
|
||||
If ``"myKeyName"`` does not exist in the namespace, it is first created and then ``value`` is stored against that keyname. The namespace must be open in RW mode to do this. Note that ``value`` is not optional and must be provided with every "``.putX``" statement. Thus every key within a namespace will always hold a valid value.
|
||||
|
||||
An example is:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
myPreferences.putFloat("pi", 3.14159265359); // stores an float_t data type
|
||||
// against the key "pi".
|
||||
|
||||
Reading Values From a Namespace
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once a key exists in a namespace and the namespace is open, its value is retrieved using one of the ``getX`` methods, matching ``"X"`` to the type of data stored against that key.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
myPreferences.getX("myKeyName")
|
||||
|
||||
Like so:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
String myString = myPreferences.getString("myStringKey");
|
||||
|
||||
This will retrieve the String value from the namespace key ``"myStringKey"`` and assign it to the String type variable ``myString``.
|
||||
|
||||
|
||||
Summary
|
||||
~~~~~~~
|
||||
|
||||
So the basics of using Preferences are:
|
||||
|
||||
#. You cannot store into or retrieve from a ``key-value`` pair until a namespace is created and opened and the key exists in that namespace.
|
||||
|
||||
#. If the key already exists, it was created the first time the sketch was run.
|
||||
|
||||
#. A key value can be retrieved regardless of the mode in which the namespace was opened, but a value can only be stored if the namespace is open in read-write mode.
|
||||
|
||||
#. Data types of the “``get``'s” and “``put``'s” must match.
|
||||
|
||||
#. Remember the 15 character limit for namespace and key names.
|
||||
|
||||
|
||||
Real World Example
|
||||
------------------
|
||||
|
||||
Here is part of a ``setup()`` function that uses Preferences.
|
||||
|
||||
Its purpose is to set either a factory default configuration if the system has never run before, or use the last configuration if it has.
|
||||
|
||||
When started, the system has no way of knowing which of the above conditions is true. So the first thing it does after opening the namespace is check for the existence of a key that we have predetermined can only exist if we have previously run the sketch. Based on its existence we decide if a factory default set of operating parameters should be used (and in so doing create the namespace keys and populate the values with defaults) or if we should use operating parameters from the last time the system was running.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
#include <Preferences.h>
|
||||
|
||||
#define RW_MODE false
|
||||
#define RO_MODE true
|
||||
|
||||
Preferences stcPrefs;
|
||||
|
||||
void setup() {
|
||||
|
||||
// not the complete setup(), but in setup(), include this...
|
||||
|
||||
stcPrefs.begin("STCPrefs", RO_MODE); // Open our namespace (or create it
|
||||
// if it doesn't exist) in in RO mode.
|
||||
|
||||
bool tpInit = stcPrefs.isKey("nvsInit"); // Test for the existence of the "already initialized" key.
|
||||
|
||||
if (tpInit == false) {
|
||||
// If tpInit is 'false', the key "nvsInit" does not yet exist therefore this
|
||||
// must be our first-time run. We need to set up our Preferences namespace keys. So...
|
||||
stcPrefs.end(); // close the namespace in RO mode and...
|
||||
stcPrefs.begin("STCPrefs", RW_MODE); // reopen it in RW mode.
|
||||
|
||||
|
||||
// The .begin() method created the "STCPrefs" namespace and since this is our
|
||||
// first-time run we will create our keys and store the initial "factory default" values.
|
||||
stcPrefs.putUChar("curBright", 10);
|
||||
stcPrefs.putString("talChan", "one");
|
||||
stcPrefs.putLong("talMax", -220226);
|
||||
stcPrefs.putBool("ctMde", true);
|
||||
|
||||
stcPrefs.putBool("nvsInit", true); // Create the "already initialized" key and store a value.
|
||||
|
||||
// The "factory defaults" are created and stored so...
|
||||
stcPrefs.end(); // Close the namespace in RW mode and...
|
||||
stcPrefs.begin("STCPrefs", RO_MODE); // reopen it in RO mode so the setup code
|
||||
// outside this first-time run 'if' block
|
||||
// can retrieve the run-time values
|
||||
// from the "STCPrefs" namespace.
|
||||
}
|
||||
|
||||
// Retrieve the operational parameters from the namespace
|
||||
// and save them into their run-time variables.
|
||||
currentBrightness = stcPrefs.getUChar("curBright"); //
|
||||
tChannel = stcPrefs.getString("talChan"); // The LHS variables were defined
|
||||
tChanMax = stcPrefs.getLong("talMax"); // earlier in the sketch.
|
||||
ctMode = stcPrefs.getBool("ctMde"); //
|
||||
|
||||
// All done. Last run state (or the factory default) is now restored.
|
||||
stcPrefs.end(); // Close our preferences namespace.
|
||||
|
||||
// Carry on with the rest of your setup code...
|
||||
|
||||
// When the sketch is running, it updates any changes to an operational parameter
|
||||
// to the appropriate key-value pair in the namespace.
|
||||
|
||||
}
|
||||
|
||||
|
||||
Utility Functions
|
||||
-----------------
|
||||
|
||||
There are a few other functions useful when working with namespaces.
|
||||
|
||||
Deleting key-value Pairs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
preferences.clear();
|
||||
|
||||
..
|
||||
|
||||
- Deletes *all* the key-value pairs in the currently opened namespace.
|
||||
|
||||
- The namespace still exists.
|
||||
|
||||
- The namespace must be open in read-write mode for this to work.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
preferences.remove("keyname");
|
||||
|
||||
..
|
||||
|
||||
- Deletes the "keyname" and value associated with it from the currently opened namespace.
|
||||
|
||||
- The namespace must be open in read-write mode for this to work.
|
||||
- Tip: use this to remove the "test key" to force a "factory reset" during the next reboot (see the *Real World Example* above).
|
||||
|
||||
If either of the above are used, the ``key-value`` pair will need to be recreated before using it again.
|
||||
|
||||
|
||||
Determining the Number of Available Keys
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For each namespace, Preferences keeps track of the keys in a key table. There must be an open entry in the table before a key can be created. This method will return the number of entires available in the table.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
freeEntries()
|
||||
|
||||
..
|
||||
|
||||
To send to the serial monitor the number of available entries the following could be used.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
Preferences mySketchPrefs;
|
||||
|
||||
mySketchPrefs.begin("myPrefs", true);
|
||||
size_t whatsLeft = freeEntries(); // this method works regardless of the mode in which the namespace is opened.
|
||||
Serial.printf("There are: %u entries available in the namespace table.\n, whatsLeft);
|
||||
mySketchPrefs.end();
|
||||
|
||||
..
|
||||
|
||||
The number of available entries in the key table changes depending on the number of keys in the namespace and also the dynamic size of certain types of data stored in the namespace. Details are in the `Preferences API Reference`_.
|
||||
|
||||
Do note that the number of entries in the key table does not guarantee that there is room in the opened NVS namespace for all the data to be stored in that namespace. Refer to the espressif `Non-volatile storage library`_ documentation for full details.
|
||||
|
||||
|
||||
Determining the Type of a key-value Pair
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Keeping track of the data types stored against a key-value pair is one of the bookkeeping tasks left to you. Should you want to discover the Preferences data type stored against a given key, use this method:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
getType("myKey")
|
||||
|
||||
..
|
||||
|
||||
As in:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
PreferenceType whatType = getType("myKey");
|
||||
|
||||
..
|
||||
|
||||
The value returned is a ``PreferenceType`` value that maps to a Preferences Type. Refer to the description in the `Preferences API Reference`_ for details.
|
||||
|
||||
|
||||
|
||||
Working with Large Data
|
||||
-----------------------
|
||||
|
||||
Recall that the Preferences library works best for storing many small values, rather than a few large values. Regardless, it may be desirable to store larger amounts of arbitrary data than what is provided by the basic types in the Preferences Types table above.
|
||||
|
||||
The library provides the following methods to facilitate this.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
putBytes("myBytesKey", value, valueLen)
|
||||
getBytes("myBytesKey", buffer, valueLen)
|
||||
getBytesLength("myBytesKey")
|
||||
|
||||
..
|
||||
|
||||
The ``put`` and ``get`` ``Bytes`` methods store and retrieve the data. The ``getBytesLength`` method is used to find the size of the data stored against the key (which is needed to retrieve ``Bytes`` data).
|
||||
|
||||
As the names of the methods imply, they operate on variable length bytes of data (often referred to as a "blob") and not on individual elements of a certain data type.
|
||||
|
||||
Meaning if you store for example an array of type ``int16_t`` against a ``Bytes`` type key, the value of that key becomes a series of bytes with no associated data type. Or if you like, all data stored as a blob gets converted to a series of ``uint8_t`` type bytes.
|
||||
|
||||
As a result, when using the ``getBytes`` method to retrieve the value of the key, what is returned to the buffer is a series of ``uint8_t`` bytes. It is up to you to manage the data types and size of the arrays and buffers when retrieving ``Bytes`` data.
|
||||
|
||||
Fortunately this is not as difficult as it may sound as the ``getBytesLength`` method and the ``sizeof`` operator help with keeping track of it all.
|
||||
|
||||
This is best explained with an example. Here the ``Bytes`` methods are used to store and retrieve an array, while ensuring the data type is preserved.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
/*
|
||||
* An example sketch using the Preferences "Bytes" methods
|
||||
* to store and retrieve an arbitrary number of bytes in
|
||||
* a namespace.
|
||||
*/
|
||||
|
||||
#include <Preferences.h>
|
||||
|
||||
#define RO_MODE true
|
||||
#define RW_MODE false
|
||||
|
||||
void setup() {
|
||||
|
||||
Preferences mySketchPrefs;
|
||||
|
||||
Serial.begin(115200);
|
||||
delay(250);
|
||||
|
||||
mySketchPrefs.begin("myPrefs", RW_MODE); // open (or create) the namespace "myPrefs" in RW mode
|
||||
mySketchPrefs.clear(); // delete any previous keys in this namespace
|
||||
|
||||
// Create an array of test values. We're using hex numbers throughout to better show how the bytes move around.
|
||||
int16_t myArray[] = { 0x1112, 0x2122, 0x3132, 0x4142, 0x5152, 0x6162, 0x7172 };
|
||||
|
||||
Serial.println("Printing myArray...");
|
||||
for (int i = 0; i < sizeof(myArray) / sizeof(int16_t); i++) {
|
||||
Serial.print(myArray[i], HEX); Serial.print(", ");
|
||||
}
|
||||
Serial.println("\r\n");
|
||||
|
||||
// In the next statement, the second sizeof() needs to match the data type of the elements of myArray
|
||||
Serial.print("The number of elements in myArray is: "); Serial.println( sizeof(myArray) / sizeof(int16_t) );
|
||||
Serial.print("But the size of myArray in bytes is: "); Serial.println( sizeof(myArray) );
|
||||
Serial.println("");
|
||||
|
||||
Serial.println("Storing myArray into the Preferences namespace \"myPrefs\" against the key \"myPrefsBytes\".");
|
||||
// Note: in the next statement, to store the entire array, we must use the
|
||||
// size of the arrray in bytes, not the number of elements in the array.
|
||||
mySketchPrefs.putBytes( "myPrefsBytes", myArray, sizeof(myArray) );
|
||||
Serial.print("The size of \"myPrefsBytes\" is (in bytes): "); Serial.println( mySketchPrefs.getBytesLength("myPrefsBytes") );
|
||||
Serial.println("");
|
||||
|
||||
int16_t myIntBuffer[20] = {}; // No magic about 20. Just making a buffer (array) big enough.
|
||||
Serial.println("Retrieving the value of myPrefsBytes into myIntBuffer.");
|
||||
Serial.println(" - Note the data type of myIntBuffer matches that of myArray");
|
||||
mySketchPrefs.getBytes( "myPrefsBytes", myIntBuffer, mySketchPrefs.getBytesLength("myPrefsBytes") );
|
||||
|
||||
Serial.println("Printing myIntBuffer...");
|
||||
// In the next statement, sizeof() needs to match the data type of the elements of myArray
|
||||
for (int i = 0; i < mySketchPrefs.getBytesLength("myPrefsBytes") / sizeof(int16_t); i++) {
|
||||
Serial.print(myIntBuffer[i], HEX); Serial.print(", ");
|
||||
}
|
||||
Serial.println("\r\n");
|
||||
|
||||
Serial.println("We can see how the data from myArray is actually stored in the namespace as follows.");
|
||||
uint8_t myByteBuffer[40] = {}; // No magic about 40. Just making a buffer (array) big enough.
|
||||
mySketchPrefs.getBytes( "myPrefsBytes", myByteBuffer, mySketchPrefs.getBytesLength("myPrefsBytes") );
|
||||
|
||||
Serial.println("Printing myByteBuffer...");
|
||||
for (int i = 0; i < mySketchPrefs.getBytesLength("myPrefsBytes"); i++) {
|
||||
Serial.print(myByteBuffer[i], HEX); Serial.print(", ");
|
||||
}
|
||||
Serial.println("");
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
;
|
||||
}
|
||||
|
||||
..
|
||||
|
||||
The resulting output is:
|
||||
::
|
||||
|
||||
Printing myArray...
|
||||
1112, 2122, 3132, 4142, 5152, 6162, 7172,
|
||||
|
||||
The number of elements in myArray is: 7
|
||||
But the size of myArray in bytes is: 14
|
||||
|
||||
Storing myArray into the Preferences namespace "myPrefs" against the key "myPrefsBytes".
|
||||
The size of "myPrefsBytes" is (in bytes): 14
|
||||
|
||||
Retrieving the value of myPrefsBytes into myIntBuffer.
|
||||
- Note the data type of myIntBuffer matches that of myArray
|
||||
Printing myIntBuffer...
|
||||
1112, 2122, 3132, 4142, 5152, 6162, 7172,
|
||||
|
||||
We can see how the data from myArray is actually stored in the namespace as follows.
|
||||
Printing myByteBuffer...
|
||||
12, 11, 22, 21, 32, 31, 42, 41, 52, 51, 62, 61, 72, 71,
|
||||
|
||||
You can copy the sketch and change the data type and values in ``myArray`` and follow along with the code and output to see how the ``Bytes`` methods work. The data type of ``myIntBuffer`` should be changed to match that of ``myArray`` (and check the "``sizeof()``'s" where indicated in the comments).
|
||||
|
||||
The main takeaway is to remember you're working with bytes and so attention needs to be paid to store all the data based on the size of its type and to manage the buffer size and data type for the value retrieved.
|
||||
|
||||
|
||||
Multiple Namespaces
|
||||
-------------------
|
||||
|
||||
As stated earlier, multiple namespaces can exist in the Preferences NVS partition. However, only one namespace at a time can be open (in use).
|
||||
|
||||
If you need to access a different namespace, close the one before opening the other. For example:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
Preferences currentNamespace;
|
||||
|
||||
currentNamespace.begin("myNamespace", false);
|
||||
// do stuff...
|
||||
|
||||
currentNamespace.end(); // closes 'myNamespace'
|
||||
|
||||
currentNamespace.begin("myOtherNamespace", false); // opens a different Preferences namesspace.
|
||||
// do other stuff...
|
||||
|
||||
currentNamespace.end(); // closes 'myOtherNamespace'
|
||||
|
||||
Here the "``currentNamespace``" object is reused, but different Preferences objects can be declared and used. Just remember to keep it all straight as all "``putX``'s" and "``getX``'s", etc. will only operate on the single currently opened namespace.
|
||||
|
||||
|
||||
A Closer Look at ``getX``
|
||||
--------------------------
|
||||
|
||||
Methods in the Preferences library return a status code that can be used to determine if the method completed successfully. This is described in the `Preferences API Reference`_.
|
||||
|
||||
Assume we have a key named "``favourites``" that contains a value of a ``String`` data type.
|
||||
|
||||
After executing the statement:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
dessert = mySketchPrefs.getString("favourites");
|
||||
|
||||
..
|
||||
|
||||
the variable ``dessert`` will contain the value of the string stored against the key ``"favourites"``.
|
||||
|
||||
But what if something went wrong and the ``getString`` call failed to retrieve the key value? How would we be able to detect the error?
|
||||
|
||||
With Preferences, the ``getX`` methods listed in Table 2 below will return a default value if an error is encountered.
|
||||
|
||||
.. table:: **Table 2 — getX Methods Defaults**
|
||||
:align: center
|
||||
|
||||
+------------------+-----------------+
|
||||
| Preferences | Default Return |
|
||||
| Type | Value |
|
||||
+==================+=================+
|
||||
| Char, UChar, | 0 |
|
||||
| | |
|
||||
| Short, UShort, | |
|
||||
| | |
|
||||
| Int, UInt, | |
|
||||
| | |
|
||||
| Long, ULong, | |
|
||||
| | |
|
||||
| Long64, ULong64 | |
|
||||
+------------------+-----------------+
|
||||
| Bool | false |
|
||||
+------------------+-----------------+
|
||||
| Float | NAN |
|
||||
| | |
|
||||
| Double | |
|
||||
+------------------+-----------------+
|
||||
| String (String) | "" |
|
||||
+------------------+-----------------+
|
||||
| String (* buf) | \\0 |
|
||||
+------------------+-----------------+
|
||||
|
||||
Thus to detect an error we could compare the value returned against its default return value and if they are equal assume an error occurred and take the appropriate action.
|
||||
|
||||
But what if a method default return value is also a potential legitimate value? How can we then know if an error occurred?
|
||||
|
||||
As it turns out, the complete form of the ``getX`` methods for each of the Preferences Types in Table 2 is:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
preferences.getX("myKey", myDefault)
|
||||
|
||||
..
|
||||
|
||||
In this form the method will return either the value associated with "``myKey``" or, if an error occurred, return the value ``myDefault``, where ``myDefault`` must be the same data type as the ``getX``.
|
||||
|
||||
Returning to the example above:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
dessert = mySketchPrefs.getString("favourites", "gravel");
|
||||
|
||||
..
|
||||
|
||||
will assign to the variable ``dessert`` the String ``gravel`` if an error occurred, or the value stored against the key ``favourites`` if not.
|
||||
|
||||
If we predetermine a default value that is outside all legitimate values, we now have a way to test if an error actually occurred.
|
||||
|
||||
In summary, if you need to confirm that a value was retrieved without error from a namespace, use the complete form of the ``getX`` method with a predetermined default "this can only happen if an error" value and compare that against the value returned by the call. Otherwise, you can omit the default value as the call will return the default for that particular ``getX`` method.
|
||||
|
||||
Additional detail is given in the `Preferences API Reference`_.
|
||||
|
||||
|
||||
Advanced Item
|
||||
-------------
|
||||
|
||||
In the arduino-esp32 implementation of Preferences there is no method to completely remove a namespace. As a result, over the course of a number of projects, it is possible that the ESP32 NVS Preferences partition becomes cluttered or full.
|
||||
|
||||
To completely erase and reformat the NVS memory used by Preferences, create and run a sketch that contains:
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
#include <nvs_flash.h>
|
||||
|
||||
void setup() {
|
||||
|
||||
nvs_flash_erase(); // erase the NVS partition and...
|
||||
nvs_flash_init(); // initialize the NVS partition.
|
||||
while (true);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
;
|
||||
}
|
||||
|
||||
..
|
||||
|
||||
.. warning::
|
||||
**You should download a new sketch to your board immediately after running the above or else it will reformat the NVS partition every time it is powered up or restarted!**
|
||||
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* `Preferences API Reference <../api/preferences.html>`_
|
||||
* `Non-volatile storage library`_ (espressif-IDF API Reference)
|
||||
* `Official ESP-IDF documentation`_ (espressif-IDF Reference)
|
||||
|
||||
|
||||
.. _Non-volatile storage library: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/storage/nvs_flash.html
|
||||
.. _Official ESP-IDF documentation: https://docs.espressif.com/projects/esp-idf/en/stable
|
||||
|
||||
|
||||
Contribute
|
||||
----------
|
||||
|
||||
.. ==*Do not change! Keep as is.*==
|
||||
|
||||
To contribute to this project, see `How to contribute`_.
|
||||
|
||||
If you have any **feedback** or **issue** to report on this tutorial, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
|
||||
|
||||
Before creating a new issue, be sure to try the Troubleshooting and to check if the same issue was already created by someone else.
|
||||
|
||||
.. _How to Contribute: https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst
|
||||
|
||||
.. ---- EOF ----
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user