forked from espressif/arduino-esp32
Compare commits
170 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 | |||
caef4006af | |||
44fbde0189 | |||
8c88ecbf77 | |||
5724275cd8 | |||
1c94c38dbb | |||
7cf162346a | |||
c66c7fe27e | |||
7ba11cc1ae | |||
c3d41c9b54 | |||
d6934a5289 | |||
6b90627b21 | |||
063119ac87 | |||
7b96374ea6 | |||
82ec74a072 | |||
5940d89e67 | |||
bb09615391 | |||
c2c8d18992 | |||
39b9e1e533 | |||
40a5c1e461 | |||
2981bde88f | |||
6d400df952 | |||
7bb30b3cf8 | |||
4b638de19d | |||
2463f57246 | |||
f29f4485b5 | |||
8a8f87d3a0 | |||
082491d552 | |||
794de50bf4 | |||
5e7db8dfac | |||
fb00b51f99 | |||
5dc8fb83c9 | |||
cb25fe8c7e | |||
f5b04b9197 | |||
8c5d18dd85 | |||
fa03966fcf | |||
3750b14d74 | |||
cebac569de | |||
d0e73bd269 | |||
26dddc5f94 | |||
c87ede88df | |||
c90dffef44 | |||
1945fae795 | |||
6e0b57784f | |||
399f4ecbb3 | |||
a5002c86a0 | |||
c9916c463f | |||
bd2be80b54 | |||
6f1f394680 | |||
5de09a9a49 | |||
b94b38c9d1 |
62
.github/ISSUE_TEMPLATE/Feature-request.yml
vendored
Normal file
62
.github/ISSUE_TEMPLATE/Feature-request.yml
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
name: Feature request
|
||||
description: Suggest an idea for this project
|
||||
labels: ["Type: Feature request"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
* We welcome any ideas or feature requests! It is helpful if you can explain exactly why the feature would be useful.
|
||||
* There are usually some outstanding feature requests in the [existing issues list](https://github.com/espressif/arduino-esp32/issues?q=is%3Aopen+is%3Aissue+label%3A%22Type%3A+Feature+request%22), feel free to add comments to them.
|
||||
* If you would like to contribute, please read the [contributions guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html).
|
||||
- type: input
|
||||
id: Area
|
||||
attributes:
|
||||
label: Related area
|
||||
description: Please briefly explain the area of your Feature Request.
|
||||
placeholder: eg. Board support, specific Peripheral, BT, Wifi...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: HW
|
||||
attributes:
|
||||
label: Hardware specification
|
||||
description: Please provide if your proposal depends on specific Hardware.
|
||||
placeholder: eg. Support for ESP32 DevKitC, ESP32-C3 DevKitM...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem-related
|
||||
attributes:
|
||||
label: Is your feature request related to a problem?
|
||||
description: Please provide a clear and concise description of what the problem is. Add relevant issue link.
|
||||
placeholder: ex. I'm facing the issue/missing function...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: Please provide a clear and concise description of what you want to happen.
|
||||
placeholder: ex. When using this function...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: Please provide a clear and concise description of any alternative solutions or features you've considered.
|
||||
placeholder: ex. Choosing other approach wouldn't work, because...
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
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
|
131
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
Normal file
131
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
name: Issue report
|
||||
description: Report any problem here
|
||||
labels: ["Status: Awaiting triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
* Before reporting a new issue please check and search in [List of existing issues](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue)
|
||||
* Please check [Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/index.html)
|
||||
* Take a look on [Troubleshooting guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html)
|
||||
* If still experiencing the issue, please provide as many details as possible below about your hardware, computer setup and code.
|
||||
- type: input
|
||||
id: Board
|
||||
attributes:
|
||||
label: Board
|
||||
description: On which Board does this issue occur?
|
||||
placeholder: eg. ESP32 Dev Module, ESP32-S2, LilyGo TTGO LoRa32...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: devboard
|
||||
attributes:
|
||||
label: Device Description
|
||||
description: What development board or other hardware is the chip attached to?
|
||||
placeholder: ex. DevKitC, plain module on breadboard, etc. If your hardware is custom or unusual, please attach a photo.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other-hw
|
||||
attributes:
|
||||
label: Hardware Configuration
|
||||
description: Is anything else attached to the development board?
|
||||
placeholder: ex. GPIO 18 & 19 are connected to I2C devices.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of Arduino ESP32 are you running? If possible, consider updating to the latest version.
|
||||
options:
|
||||
- latest master
|
||||
- v2.0.2
|
||||
- v2.0.1
|
||||
- v2.0.0
|
||||
- v1.0.6
|
||||
- other
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: IDE
|
||||
attributes:
|
||||
label: IDE Name
|
||||
description: What IDE are you using?
|
||||
placeholder: eg. Arduino IDE, PlatformIO, IDF component...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: On which OS does this issue occur?
|
||||
placeholder: ex. macOS 12.1, Windows 10...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: Flash
|
||||
attributes:
|
||||
label: Flash frequency
|
||||
description: What flash frequency is used?
|
||||
placeholder: eg. 40Mhz
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: PSRAM
|
||||
attributes:
|
||||
label: PSRAM enabled
|
||||
description: Is PSRAM enabled?
|
||||
options:
|
||||
- 'yes'
|
||||
- 'no'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: Upload
|
||||
attributes:
|
||||
label: Upload speed
|
||||
description: What upload speed is used?
|
||||
placeholder: eg. 115200
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Please describe your problem here and expected behaviour
|
||||
placeholder: ex. Can't connect/weird behaviour/wrong function/missing parameter..
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: sketch
|
||||
attributes:
|
||||
label: Sketch
|
||||
description: Please provide your sketch/code which was run
|
||||
placeholder: ex. related part of the code
|
||||
render: cpp
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Debug
|
||||
attributes:
|
||||
label: Debug Message
|
||||
description: Please provide a debug message or error message. If you have a Guru Meditation Error or Backtrace, please decode it with [ExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder)
|
||||
placeholder: Enable Core debug level - Debug on tools menu of Arduino IDE, then put the serial output here.
|
||||
render: plain
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other-remarks
|
||||
attributes:
|
||||
label: Other Steps to Reproduce
|
||||
description: Is there any other information you can think of which will help us reproduce this problem? Any additional info can be added as well.
|
||||
placeholder: ex. I also tried on other OS, HW...it works correctly on that setup.
|
||||
- type: checkboxes
|
||||
id: confirmation
|
||||
attributes:
|
||||
label: I have checked existing issues, online documentation and the Troubleshooting Guide
|
||||
description: You agree to check all the resources above before opening a new issue.
|
||||
options:
|
||||
- label: I confirm I have checked existing issues, online documentation and Troubleshooting guide.
|
||||
required: true
|
54
.github/ISSUE_TEMPLATE/bug_report.md
vendored
54
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,54 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Please fill in the bug report carefully
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
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).
|
||||
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***:
|
||||
https://github.com/me-no-dev/EspExceptionDecoder
|
||||
|
||||
----------------------------- Remove above -----------------------------
|
||||
|
||||
|
||||
### Hardware:
|
||||
Board: ?ESP32 Dev Module? ?node32? ?ttgo_lora?
|
||||
Core Installation version: ?1.0.0? ?1.0.1-rc4? ?1.0.1? ?1.0.1-git? ?1.0.2? ?1.0.3?
|
||||
IDE name: ?Arduino IDE? ?Platform.io? ?IDF component?
|
||||
Flash Frequency: ?40Mhz?
|
||||
PSRAM enabled: ?no? ?yes?
|
||||
Upload Speed: ?115200?
|
||||
Computer OS: ?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
|
||||
```
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Arduino ESP32 Gitter Channel
|
||||
url: https://gitter.im/espressif/arduino-esp32
|
||||
about: Community channel for questions and help
|
||||
- name: ESP32 Forum - Arduino
|
||||
url: https://esp32.com/viewforum.php?f=19
|
||||
about: Official Forum for questions
|
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,16 +1,18 @@
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
This entire section can be deleted if all items are checked.
|
||||
|
||||
*By completing this PR sufficiently, you help us to 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")
|
||||
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)
|
||||
|
||||
*This entire section above can be deleted if all items are checked.*
|
||||
|
||||
-----------
|
||||
## Summary
|
||||
Please describe your proposed PR and what it contains.
|
||||
|
||||
## Impact
|
||||
Please describe impact of your PR and it's function.
|
||||
|
||||
## Related links
|
||||
Please provide links to related issue, PRs etc.
|
||||
|
2
.github/scripts/check-cmakelists.sh
vendored
2
.github/scripts/check-cmakelists.sh
vendored
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This script is for Travis. It checks all non-examples source files in libraries/ and cores/ are listed in
|
||||
# This script is used in the CI workflow. It checks all non-examples source files in libraries/ and cores/ are listed in
|
||||
# CMakeLists.txt for the cmake-based IDF component
|
||||
#
|
||||
# If you see an error running this script, edit CMakeLists.txt and add any new source files into your PR
|
||||
|
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
|
||||
}
|
||||
|
29
.github/scripts/install-platformio-esp32.sh
vendored
29
.github/scripts/install-platformio-esp32.sh
vendored
@ -3,9 +3,7 @@
|
||||
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
|
||||
PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master"
|
||||
|
||||
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>]"
|
||||
|
0
.github/scripts/on-pages.sh
vendored
Normal file → Executable file
0
.github/scripts/on-pages.sh
vendored
Normal file → Executable file
161
.github/scripts/on-push.sh
vendored
161
.github/scripts/on-push.sh
vendored
@ -2,103 +2,118 @@
|
||||
|
||||
set -e
|
||||
|
||||
if [ ! -z "$TRAVIS_TAG" ]; then
|
||||
echo "Skipping Test: Tagged build"
|
||||
exit 0
|
||||
fi
|
||||
export ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
|
||||
|
||||
if [ ! -z "$GITHUB_WORKSPACE" ]; then
|
||||
export TRAVIS_BUILD_DIR="$GITHUB_WORKSPACE"
|
||||
export TRAVIS_REPO_SLUG="$GITHUB_REPOSITORY"
|
||||
elif [ ! -z "$TRAVIS_BUILD_DIR" ]; then
|
||||
export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR"
|
||||
export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG"
|
||||
else
|
||||
export GITHUB_WORKSPACE="$PWD"
|
||||
export GITHUB_REPOSITORY="espressif/arduino-esp32"
|
||||
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"
|
||||
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"
|
||||
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
|
||||
# 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"
|
||||
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"
|
||||
|
||||
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
|
||||
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
|
||||
|
189
.github/scripts/sketch_utils.sh
vendored
Executable file
189
.github/scripts/sketch_utils.sh
vendored
Executable file
@ -0,0 +1,189 @@
|
||||
#!/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
|
||||
|
||||
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
|
||||
local ide_path=$1
|
||||
local usr_path=$2
|
||||
local fqbn=$3
|
||||
local sketch=$4
|
||||
local xtra_opts=$5
|
||||
local win_opts=$6
|
||||
|
||||
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
|
35
.github/scripts/update-version.sh
vendored
Executable file
35
.github/scripts/update-version.sh
vendored
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
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
|
2
.github/workflows/gh-pages.yml
vendored
2
.github/workflows/gh-pages.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
name: Build GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
- name: Copy Files
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
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
|
||||
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: Check Artifacts
|
||||
run: |
|
||||
ls -R tests
|
||||
cat tests/*/build/build.options.json
|
||||
|
||||
- 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}}
|
37
.github/workflows/publish.yml
vendored
Normal file
37
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
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 != 'skipped'
|
||||
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"
|
34
.github/workflows/push.yml
vendored
34
.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
|
||||
@ -18,10 +30,20 @@ jobs:
|
||||
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
- 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
|
||||
|
||||
@ -34,8 +56,8 @@ jobs:
|
||||
os: [windows-latest, macOS-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build Sketches
|
||||
@ -50,8 +72,8 @@ jobs:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build Sketches
|
||||
|
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -10,10 +10,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build Release
|
||||
|
27
.github/workflows/test_selfhosted_runner.yml
vendored
27
.github/workflows/test_selfhosted_runner.yml
vendored
@ -1,27 +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
|
||||
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
|
||||
|
55
.travis.yml
55
.travis.yml
@ -1,55 +0,0 @@
|
||||
sudo: false
|
||||
|
||||
language: python
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
git:
|
||||
depth: false
|
||||
|
||||
before_install:
|
||||
- git submodule update --init --recursive
|
||||
|
||||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
- name: "Build Arduino 0"
|
||||
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
|
||||
stage: build
|
||||
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 0 10
|
||||
|
||||
- name: "Build Arduino 1"
|
||||
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
|
||||
stage: build
|
||||
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 1 10
|
||||
|
||||
- name: "Build Arduino 2"
|
||||
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
|
||||
stage: build
|
||||
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 2 10
|
||||
|
||||
- name: "Build Arduino 3"
|
||||
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
|
||||
stage: build
|
||||
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 3 10
|
||||
|
||||
- name: "Build PlatformIO"
|
||||
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
|
||||
stage: build
|
||||
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 1 1
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: change
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/cb057279c430d91a47a8
|
||||
on_success: change # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: never # options: [always|never|change] default: always
|
@ -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
|
@ -1,4 +1,4 @@
|
||||
# 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)
|
||||
|
||||
@ -27,6 +27,10 @@ You can use [Arduino-ESP32 Online Documentation](https://docs.espressif.com/proj
|
||||
* [FAQ](https://docs.espressif.com/projects/arduino-esp32/en/latest/faq.html)
|
||||
* [Troubleshooting](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html)
|
||||
|
||||
### Supported Chips
|
||||
|
||||
Visit the [supported chips](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html#supported-soc-s) documentation to see the list of current supported ESP32 SoCs.
|
||||
|
||||
### Decoding exceptions
|
||||
|
||||
You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder) to get meaningful call trace.
|
||||
@ -34,7 +38,7 @@ You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecod
|
||||
### 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](docs/ISSUE_TEMPLATE.md) while reporting any issue.
|
||||
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).
|
||||
|
||||
### Contributing
|
||||
|
||||
|
4129
boards.txt
Normal file → Executable file
4129
boards.txt
Normal file → Executable file
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;
|
||||
@ -179,6 +180,12 @@ uint16_t makeWord(uint8_t h, uint8_t l);
|
||||
|
||||
#define word(...) makeWord(__VA_ARGS__)
|
||||
|
||||
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);
|
||||
|
||||
@ -188,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;
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <Arduino.h>
|
||||
#include <MD5Builder.h>
|
||||
|
||||
uint8_t hex_char_to_byte(uint8_t c)
|
||||
static uint8_t hex_char_to_byte(uint8_t c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) :
|
||||
(c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) :
|
||||
@ -28,13 +28,13 @@ uint8_t hex_char_to_byte(uint8_t c)
|
||||
|
||||
void MD5Builder::begin(void)
|
||||
{
|
||||
memset(_buf, 0x00, 16);
|
||||
MD5Init(&_ctx);
|
||||
memset(_buf, 0x00, ESP_ROM_MD5_DIGEST_LEN);
|
||||
esp_rom_md5_init(&_ctx);
|
||||
}
|
||||
|
||||
void MD5Builder::add(uint8_t * data, uint16_t len)
|
||||
{
|
||||
MD5Update(&_ctx, data, len);
|
||||
esp_rom_md5_update(&_ctx, data, len);
|
||||
}
|
||||
|
||||
void MD5Builder::addHexString(const char * data)
|
||||
@ -82,7 +82,7 @@ bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
|
||||
}
|
||||
|
||||
// Update MD5 with buffer payload
|
||||
MD5Update(&_ctx, buf, numBytesRead);
|
||||
esp_rom_md5_update(&_ctx, buf, numBytesRead);
|
||||
|
||||
// update available number of bytes
|
||||
maxLengthLeft -= numBytesRead;
|
||||
@ -94,24 +94,24 @@ bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
|
||||
|
||||
void MD5Builder::calculate(void)
|
||||
{
|
||||
MD5Final(_buf, &_ctx);
|
||||
esp_rom_md5_final(_buf, &_ctx);
|
||||
}
|
||||
|
||||
void MD5Builder::getBytes(uint8_t * output)
|
||||
{
|
||||
memcpy(output, _buf, 16);
|
||||
memcpy(output, _buf, ESP_ROM_MD5_DIGEST_LEN);
|
||||
}
|
||||
|
||||
void MD5Builder::getChars(char * output)
|
||||
{
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
for(uint8_t i = 0; i < ESP_ROM_MD5_DIGEST_LEN; i++) {
|
||||
sprintf(output + (i * 2), "%02x", _buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
String MD5Builder::toString(void)
|
||||
{
|
||||
char out[33];
|
||||
char out[(ESP_ROM_MD5_DIGEST_LEN * 2) + 1];
|
||||
getChars(out);
|
||||
return String(out);
|
||||
}
|
||||
|
@ -23,25 +23,13 @@
|
||||
#include <Stream.h>
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/md5_hash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/md5_hash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/md5_hash.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/md5_hash.h"
|
||||
#endif
|
||||
#include "esp_rom_md5.h"
|
||||
|
||||
class MD5Builder
|
||||
{
|
||||
private:
|
||||
struct MD5Context _ctx;
|
||||
uint8_t _buf[16];
|
||||
md5_context_t _ctx;
|
||||
uint8_t _buf[ESP_ROM_MD5_DIGEST_LEN];
|
||||
public:
|
||||
void begin(void);
|
||||
void add(uint8_t * data, uint16_t len);
|
||||
|
@ -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
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
|
||||
cbuf *next;
|
||||
|
||||
private:
|
||||
protected:
|
||||
inline char* wrap_if_bufend(char* ptr) const
|
||||
{
|
||||
return (ptr == _bufend) ? _buf : ptr;
|
||||
|
@ -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,51 +13,37 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#define DAC1 25
|
||||
#define DAC2 26
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#define DAC1 17
|
||||
#define DAC2 18
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#ifndef SOC_DAC_SUPPORTED
|
||||
#define NODAC
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
|
||||
#ifndef NODAC
|
||||
#include "esp_attr.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/rtc_io_periph.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "driver/dac.h"
|
||||
#include "soc/dac_channel.h"
|
||||
#include "driver/dac_common.h"
|
||||
|
||||
void ARDUINO_ISR_ATTR __dacWrite(uint8_t pin, uint8_t value)
|
||||
{
|
||||
if(pin < DAC1 || pin > DAC2){
|
||||
if(pin < DAC_CHANNEL_1_GPIO_NUM || pin > DAC_CHANNEL_2_GPIO_NUM){
|
||||
return;//not dac pin
|
||||
}
|
||||
pinMode(pin, ANALOG);
|
||||
uint8_t channel = pin - DAC1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
SENS.sar_dac_ctrl1.dac_clkgate_en = 1;
|
||||
#endif
|
||||
RTCIO.pad_dac[channel].dac_xpd_force = 1;
|
||||
RTCIO.pad_dac[channel].xpd_dac = 1;
|
||||
if (channel == 0) {
|
||||
SENS.sar_dac_ctrl2.dac_cw_en1 = 0;
|
||||
} else if (channel == 1) {
|
||||
SENS.sar_dac_ctrl2.dac_cw_en2 = 0;
|
||||
|
||||
uint8_t channel = pin - DAC_CHANNEL_1_GPIO_NUM;
|
||||
dac_output_enable(channel);
|
||||
dac_output_voltage(channel, value);
|
||||
|
||||
}
|
||||
|
||||
void ARDUINO_ISR_ATTR __dacDisable(uint8_t pin)
|
||||
{
|
||||
if(pin < DAC_CHANNEL_1_GPIO_NUM || pin > DAC_CHANNEL_2_GPIO_NUM){
|
||||
return;//not dac pin
|
||||
}
|
||||
RTCIO.pad_dac[channel].dac = value;
|
||||
|
||||
uint8_t channel = pin - DAC_CHANNEL_1_GPIO_NUM;
|
||||
dac_output_disable(channel);
|
||||
}
|
||||
|
||||
extern void dacWrite(uint8_t pin, uint8_t value) __attribute__ ((weak, alias("__dacWrite")));
|
||||
extern void dacDisable(uint8_t pin) __attribute__ ((weak, alias("__dacDisable")));
|
||||
|
||||
#endif
|
||||
|
@ -28,6 +28,7 @@ extern "C" {
|
||||
#include "driver/gpio.h"
|
||||
|
||||
void dacWrite(uint8_t pin, uint8_t value);
|
||||
void dacDisable(uint8_t pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -13,138 +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
|
||||
// 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}
|
||||
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*);
|
||||
@ -159,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 = {
|
||||
@ -182,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) {
|
||||
@ -343,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);
|
||||
|
||||
@ -394,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");
|
||||
@ -416,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)
|
||||
@ -450,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);
|
||||
@ -465,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
|
||||
}
|
||||
|
||||
|
||||
@ -481,4 +212,3 @@ extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")
|
||||
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
|
||||
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
|
||||
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
|
||||
|
||||
|
@ -68,22 +68,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 +82,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
|
||||
|
12
cores/esp32/esp32-hal-i2c-slave.c
Executable file → Normal file
12
cores/esp32/esp32-hal-i2c-slave.c
Executable file → Normal file
@ -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;
|
||||
@ -302,7 +302,7 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
|
||||
i2c_ll_slave_init(i2c->dev);
|
||||
i2c_ll_set_fifo_mode(i2c->dev, true);
|
||||
i2c_ll_set_slave_addr(i2c->dev, slaveID, false);
|
||||
i2c_ll_set_tout(i2c->dev, 32000);
|
||||
i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT);
|
||||
i2c_slave_set_frequency(i2c, frequency);
|
||||
|
||||
if (!i2c_slave_check_line_state(sda, scl)) {
|
||||
@ -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;
|
||||
}
|
||||
|
0
cores/esp32/esp32-hal-i2c-slave.h
Executable file → Normal file
0
cores/esp32/esp32-hal-i2c-slave.h
Executable file → Normal file
@ -24,6 +24,7 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "hal/i2c_hal.h"
|
||||
#include "hal/i2c_ll.h"
|
||||
#include "driver/i2c.h"
|
||||
|
||||
typedef volatile struct {
|
||||
@ -91,6 +92,8 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency){
|
||||
} else {
|
||||
bus[i2c_num].initialized = true;
|
||||
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);
|
||||
}
|
||||
}
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
|
@ -13,46 +13,25 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/ledc_reg.h"
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/ledc.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#define LAST_CHAN (15)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#define LAST_CHAN (7)
|
||||
#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#define LAST_CHAN (7)
|
||||
#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V
|
||||
#ifdef SOC_LEDC_SUPPORT_HS_MODE
|
||||
#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1)
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM)
|
||||
#endif
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
#define LEDC_MUTEX_LOCK()
|
||||
#define LEDC_MUTEX_UNLOCK()
|
||||
//Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz
|
||||
//Need to be fixed in ESP-IDF
|
||||
#ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK
|
||||
#define LEDC_DEFAULT_CLK LEDC_USE_XTAL_CLK
|
||||
#else
|
||||
#define LEDC_MUTEX_LOCK() do {} while (xSemaphoreTake(_ledc_sys_lock, portMAX_DELAY) != pdPASS)
|
||||
#define LEDC_MUTEX_UNLOCK() xSemaphoreGive(_ledc_sys_lock)
|
||||
xSemaphoreHandle _ledc_sys_lock = NULL;
|
||||
#define LEDC_DEFAULT_CLK LEDC_AUTO_CLK
|
||||
#endif
|
||||
|
||||
#define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM
|
||||
|
||||
/*
|
||||
* LEDC Chan to Group/Channel/Timer Mapping
|
||||
** ledc: 0 => Group: 0, Channel: 0, Timer: 0
|
||||
@ -72,203 +51,59 @@ xSemaphoreHandle _ledc_sys_lock = NULL;
|
||||
** ledc: 14 => Group: 1, Channel: 6, Timer: 3
|
||||
** ledc: 15 => Group: 1, Channel: 7, Timer: 3
|
||||
*/
|
||||
#define LEDC_CHAN(g,c) LEDC.channel_group[(g)].channel[(c)]
|
||||
#define LEDC_TIMER(g,t) LEDC.timer_group[(g)].timer[(t)]
|
||||
|
||||
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
||||
if(ev_type == APB_AFTER_CHANGE && old_apb != new_apb){
|
||||
uint16_t iarg = *(uint16_t*)arg;
|
||||
uint8_t chan = 0;
|
||||
old_apb /= 1000000;
|
||||
new_apb /= 1000000;
|
||||
while(iarg){ // run though all active channels, adjusting timing configurations
|
||||
if(iarg & 1) {// this channel is active
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
if(LEDC_TIMER(group, timer).conf.tick_sel){
|
||||
LEDC_MUTEX_LOCK();
|
||||
uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider;
|
||||
uint32_t div_num = (new_apb * old_div) / old_apb;
|
||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V){
|
||||
div_num = ((REF_CLK_FREQ /1000000) * old_div) / old_apb;
|
||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
|
||||
}
|
||||
LEDC_TIMER(group, timer).conf.tick_sel = 0;
|
||||
} else if(div_num < 256) {
|
||||
div_num = 256;//highest clock possible
|
||||
}
|
||||
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
}
|
||||
else {
|
||||
log_d("using REF_CLK chan=%d",chan);
|
||||
}
|
||||
}
|
||||
iarg = iarg >> 1;
|
||||
chan++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//uint32_t frequency = (80MHz or 1MHz)/((div_num / 256.0)*(1 << bit_num));
|
||||
static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, bool apb_clk)
|
||||
{
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
static bool tHasStarted = false;
|
||||
static uint16_t _activeChannels = 0;
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
// ESP32-S2 TRM v1.0 on Page 789 -> BIT LEDC_TICK_SEL_TIMERx is 0 for LEDC_PWM_CLK and 1 for REF_TICK
|
||||
apb_clk = 0;
|
||||
#endif
|
||||
if(!tHasStarted) {
|
||||
tHasStarted = true;
|
||||
periph_module_enable(PERIPH_LEDC_MODULE);
|
||||
LEDC.conf.apb_clk_sel = 1;//LS use apb clock
|
||||
addApbChangeCallback((void*)&_activeChannels, _on_apb_change);
|
||||
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
_ledc_sys_lock = xSemaphoreCreateMutex();
|
||||
#endif
|
||||
}
|
||||
LEDC_MUTEX_LOCK();
|
||||
LEDC_TIMER(group, timer).conf.clock_divider = div_num;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part.
|
||||
LEDC_TIMER(group, timer).conf.duty_resolution = bit_num;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20.
|
||||
LEDC_TIMER(group, timer).conf.tick_sel = apb_clk;//apb clock
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(group) {
|
||||
#endif
|
||||
LEDC_TIMER(group, timer).conf.low_speed_update = 1;//This bit is only useful for low speed timer channels, reserved for high speed timers
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
}
|
||||
#endif
|
||||
LEDC_TIMER(group, timer).conf.pause = 0;
|
||||
LEDC_TIMER(group, timer).conf.rst = 1;//This bit is used to reset timer the counter will be 0 after reset.
|
||||
LEDC_TIMER(group, timer).conf.rst = 0;
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
_activeChannels |= (1 << chan); // mark as active for APB callback
|
||||
}
|
||||
|
||||
//max div_num 0x3FFFF (262143)
|
||||
//max bit_num 0x1F (31)
|
||||
static double _ledcSetupTimerFreq(uint8_t chan, double freq, uint8_t bit_num)
|
||||
{
|
||||
uint64_t clk_freq = getApbFrequency();
|
||||
clk_freq <<= 8;//div_num is 8 bit decimal
|
||||
uint32_t div_num = (clk_freq >> bit_num) / freq;
|
||||
bool apb_clk = true;
|
||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
clk_freq /= 80;
|
||||
div_num = (clk_freq >> bit_num) / freq;
|
||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
|
||||
}
|
||||
apb_clk = false;
|
||||
} else if(div_num < 256) {
|
||||
div_num = 256;//highest clock possible
|
||||
}
|
||||
_ledcSetupTimer(chan, div_num, bit_num, apb_clk);
|
||||
//log_i("Fin: %f, Fclk: %uMhz, bits: %u, DIV: %u, Fout: %f",
|
||||
// freq, apb_clk?80:1, bit_num, div_num, (clk_freq >> bit_num) / (double)div_num);
|
||||
return (clk_freq >> bit_num) / (double)div_num;
|
||||
}
|
||||
|
||||
static double _ledcTimerRead(uint8_t chan)
|
||||
{
|
||||
uint32_t div_num;
|
||||
uint8_t bit_num;
|
||||
bool apb_clk;
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
LEDC_MUTEX_LOCK();
|
||||
div_num = LEDC_TIMER(group, timer).conf.clock_divider;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part.
|
||||
bit_num = LEDC_TIMER(group, timer).conf.duty_resolution;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20.
|
||||
apb_clk = LEDC_TIMER(group, timer).conf.tick_sel;//apb clock
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
uint64_t clk_freq = 1000000;
|
||||
if(apb_clk) {
|
||||
clk_freq = getApbFrequency();
|
||||
}
|
||||
clk_freq <<= 8;//div_num is 8 bit decimal
|
||||
return (clk_freq >> bit_num) / (double)div_num;
|
||||
}
|
||||
|
||||
static void _ledcSetupChannel(uint8_t chan, uint8_t idle_level)
|
||||
{
|
||||
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
|
||||
LEDC_MUTEX_LOCK();
|
||||
LEDC_CHAN(group, channel).conf0.timer_sel = timer;//2 bit Selects the timer to attach 0-3
|
||||
LEDC_CHAN(group, channel).conf0.idle_lv = idle_level;//1 bit This bit is used to control the output value when channel is off.
|
||||
LEDC_CHAN(group, channel).hpoint.hpoint = 0;//20 bit The output value changes to high when timer selected by channel has reached hpoint
|
||||
LEDC_CHAN(group, channel).conf1.duty_inc = 1;//1 bit This register is used to increase the duty of output signal or decrease the duty of output signal for high speed channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_num = 1;//10 bit This register is used to control the number of increased or decreased times for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_cycle = 1;//10 bit This register is used to increase or decrease the duty every duty_cycle cycles for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_scale = 0;//10 bit This register controls the increase or decrease step scale for channel.
|
||||
LEDC_CHAN(group, channel).duty.duty = 0;
|
||||
LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(group) {
|
||||
#endif
|
||||
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
} else {
|
||||
LEDC_CHAN(group, channel).conf0.clk_en = 0;
|
||||
}
|
||||
#endif
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
}
|
||||
uint8_t channels_resolution[LEDC_CHANNELS] = {0};
|
||||
|
||||
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
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;
|
||||
}
|
||||
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
|
||||
_ledcSetupChannel(chan, LOW);
|
||||
return res_freq;
|
||||
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = group,
|
||||
.timer_num = timer,
|
||||
.duty_resolution = bit_num,
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
||||
void ledcWrite(uint8_t chan, uint32_t duty)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return;
|
||||
}
|
||||
uint8_t group=(chan/8), channel=(chan%8);
|
||||
LEDC_MUTEX_LOCK();
|
||||
LEDC_CHAN(group, channel).duty.duty = duty << 4;//25 bit (21.4)
|
||||
if(duty) {
|
||||
LEDC_CHAN(group, channel).conf0.sig_out_en = 1;//This is the output enable control bit for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_start = 1;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(group) {
|
||||
#endif
|
||||
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
} else {
|
||||
LEDC_CHAN(group, channel).conf0.clk_en = 1;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(group) {
|
||||
#endif
|
||||
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
} else {
|
||||
LEDC_CHAN(group, channel).conf0.clk_en = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//Fixing if all bits in resolution is set = LEDC FULL ON
|
||||
uint32_t max_duty = (1 << channels_resolution[chan]) - 1;
|
||||
|
||||
if(duty == max_duty){
|
||||
duty = max_duty + 1;
|
||||
}
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
|
||||
ledc_set_duty(group, channel, duty);
|
||||
ledc_update_duty(group, channel);
|
||||
}
|
||||
|
||||
uint32_t ledcRead(uint8_t chan)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return 0;
|
||||
}
|
||||
return LEDC.channel_group[chan/8].channel[chan%8].duty.duty >> 4;
|
||||
uint8_t group=(chan/8), channel=(chan%8);
|
||||
return ledc_get_duty(group,channel);
|
||||
}
|
||||
|
||||
double ledcReadFreq(uint8_t chan)
|
||||
@ -276,19 +111,38 @@ double ledcReadFreq(uint8_t chan)
|
||||
if(!ledcRead(chan)){
|
||||
return 0;
|
||||
}
|
||||
return _ledcTimerRead(chan);
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
return ledc_get_freq(group,timer);
|
||||
}
|
||||
|
||||
double ledcWriteTone(uint8_t chan, double freq)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return 0;
|
||||
}
|
||||
if(!freq) {
|
||||
if(!freq){
|
||||
ledcWrite(chan, 0);
|
||||
return 0;
|
||||
}
|
||||
double res_freq = _ledcSetupTimerFreq(chan, freq, 10);
|
||||
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = group,
|
||||
.timer_num = timer,
|
||||
.duty_resolution = 10,
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
|
||||
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);
|
||||
ledcWrite(chan, 0x1FF);
|
||||
return res_freq;
|
||||
}
|
||||
@ -308,15 +162,21 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
|
||||
|
||||
void ledcAttachPin(uint8_t pin, uint8_t chan)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return;
|
||||
}
|
||||
pinMode(pin, OUTPUT);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
pinMatrixOutAttach(pin, LEDC_LS_SIG_OUT0_IDX + chan, false, false);
|
||||
#else
|
||||
pinMatrixOutAttach(pin, ((chan/8)?LEDC_LS_SIG_OUT0_IDX:LEDC_HS_SIG_OUT0_IDX) + (chan%8), false, false);
|
||||
#endif
|
||||
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
|
||||
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.speed_mode = group,
|
||||
.channel = channel,
|
||||
.timer_sel = timer,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = pin,
|
||||
.duty = 0,
|
||||
.hpoint = 0
|
||||
};
|
||||
ledc_channel_config(&ledc_channel);
|
||||
}
|
||||
|
||||
void ledcDetachPin(uint8_t pin)
|
||||
@ -326,21 +186,37 @@ void ledcDetachPin(uint8_t pin)
|
||||
|
||||
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
|
||||
{
|
||||
if (chan > 15) {
|
||||
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;
|
||||
}
|
||||
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
|
||||
return res_freq;
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = group,
|
||||
.timer_num = timer,
|
||||
.duty_resolution = bit_num,
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 };
|
||||
static int cnt_channel = SOC_LEDC_CHANNEL_NUM;
|
||||
static int cnt_channel = LEDC_CHANNELS;
|
||||
void analogWrite(uint8_t pin, int value) {
|
||||
// Use ledc hardware for internal pins
|
||||
if (pin < SOC_GPIO_PIN_COUNT) {
|
||||
if (pin_to_channel[pin] == 0) {
|
||||
if (!cnt_channel) {
|
||||
log_e("No more analogWrite channels available! You can have maximum %u", SOC_LEDC_CHANNEL_NUM);
|
||||
log_e("No more analogWrite channels available! You can have maximum %u", LEDC_CHANNELS);
|
||||
return;
|
||||
}
|
||||
pin_to_channel[pin] = cnt_channel--;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,9 @@ extern "C" {
|
||||
#define RMT_FLAG_ERROR (4)
|
||||
#define RMT_FLAGS_ALL (RMT_FLAG_TX_DONE | RMT_FLAG_RX_DONE | RMT_FLAG_ERROR)
|
||||
|
||||
#define RMT_TX_MODE true
|
||||
#define RMT_RX_MODE false
|
||||
|
||||
struct rmt_obj_s;
|
||||
|
||||
typedef enum {
|
||||
@ -54,6 +57,13 @@ typedef struct {
|
||||
};
|
||||
} rmt_data_t;
|
||||
|
||||
|
||||
/**
|
||||
* Prints object information
|
||||
*
|
||||
*/
|
||||
void _rmtDumpStatus(rmt_obj_t* rmt);
|
||||
|
||||
/**
|
||||
* Initialize the object
|
||||
*
|
||||
@ -69,10 +79,17 @@ float rmtSetTick(rmt_obj_t* rmt, float tick);
|
||||
/**
|
||||
* Sending data in one-go mode or continual mode
|
||||
* (more data being send while updating buffers in interrupts)
|
||||
*
|
||||
* Non-Blocking mode - returns right after executing
|
||||
*/
|
||||
bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
|
||||
|
||||
/**
|
||||
* Sending data in one-go mode or continual mode
|
||||
* (more data being send while updating buffers in interrupts)
|
||||
* Blocking mode - only returns when data has been sent
|
||||
*/
|
||||
bool rmtWriteBlocking(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
|
||||
|
||||
/**
|
||||
* Loop data up to the reserved memsize continuously
|
||||
*
|
||||
|
@ -12,38 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "soc/gpio_sd_reg.h"
|
||||
#include "soc/gpio_sd_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "driver/sigmadelta.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"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
#define SD_MUTEX_LOCK()
|
||||
#define SD_MUTEX_UNLOCK()
|
||||
#else
|
||||
#define SD_MUTEX_LOCK() do {} while (xSemaphoreTake(_sd_sys_lock, portMAX_DELAY) != pdPASS)
|
||||
#define SD_MUTEX_UNLOCK() xSemaphoreGive(_sd_sys_lock)
|
||||
xSemaphoreHandle _sd_sys_lock;
|
||||
#endif
|
||||
static uint8_t duty_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0};
|
||||
static uint32_t prescaler_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0};
|
||||
|
||||
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
||||
if(old_apb == new_apb){
|
||||
@ -51,79 +27,60 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb
|
||||
}
|
||||
uint32_t iarg = (uint32_t)arg;
|
||||
uint8_t channel = iarg;
|
||||
if(ev_type == APB_BEFORE_CHANGE){
|
||||
SIGMADELTA.cg.clk_en = 0;
|
||||
} else {
|
||||
if(ev_type == APB_AFTER_CHANGE){
|
||||
old_apb /= 1000000;
|
||||
new_apb /= 1000000;
|
||||
SD_MUTEX_LOCK();
|
||||
uint32_t old_prescale = SIGMADELTA.channel[channel].prescale + 1;
|
||||
SIGMADELTA.channel[channel].prescale = ((new_apb * old_prescale) / old_apb) - 1;
|
||||
SIGMADELTA.cg.clk_en = 0;
|
||||
SIGMADELTA.cg.clk_en = 1;
|
||||
SD_MUTEX_UNLOCK();
|
||||
uint32_t old_prescale = prescaler_set[channel] + 1;
|
||||
uint32_t new_prescale = ((new_apb * old_prescale) / old_apb) - 1;
|
||||
sigmadelta_set_prescale(channel,new_prescale);
|
||||
prescaler_set[channel] = new_prescale;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-312500
|
||||
uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq) //chan 0-x according to SOC, freq 1220-312500
|
||||
{
|
||||
if(channel > 7) {
|
||||
if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
|
||||
return 0;
|
||||
}
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
static bool tHasStarted = false;
|
||||
if(!tHasStarted) {
|
||||
tHasStarted = true;
|
||||
_sd_sys_lock = xSemaphoreCreateMutex();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t apb_freq = getApbFrequency();
|
||||
uint32_t prescale = (apb_freq/(freq*256)) - 1;
|
||||
if(prescale > 0xFF) {
|
||||
prescale = 0xFF;
|
||||
}
|
||||
SD_MUTEX_LOCK();
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
SIGMADELTA.misc.function_clk_en = 1;
|
||||
#endif
|
||||
SIGMADELTA.channel[channel].prescale = prescale;
|
||||
SIGMADELTA.cg.clk_en = 0;
|
||||
SIGMADELTA.cg.clk_en = 1;
|
||||
SD_MUTEX_UNLOCK();
|
||||
|
||||
sigmadelta_config_t sigmadelta_cfg = {
|
||||
.channel = channel,
|
||||
.sigmadelta_prescale = prescale,
|
||||
.sigmadelta_duty = 0,
|
||||
.sigmadelta_gpio = pin,
|
||||
};
|
||||
sigmadelta_config(&sigmadelta_cfg);
|
||||
|
||||
prescaler_set[channel] = prescale;
|
||||
uint32_t iarg = channel;
|
||||
addApbChangeCallback((void*)iarg, _on_apb_change);
|
||||
|
||||
return apb_freq/((prescale + 1) * 256);
|
||||
}
|
||||
|
||||
void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-7 duty 8 bit
|
||||
void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-x according to SOC duty 8 bit
|
||||
{
|
||||
if(channel > 7) {
|
||||
if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
|
||||
return;
|
||||
}
|
||||
duty -= 128;
|
||||
SD_MUTEX_LOCK();
|
||||
SIGMADELTA.channel[channel].duty = duty;
|
||||
SD_MUTEX_UNLOCK();
|
||||
|
||||
sigmadelta_set_duty(channel,duty);
|
||||
duty_set[channel] = duty;
|
||||
}
|
||||
|
||||
uint8_t sigmaDeltaRead(uint8_t channel) //chan 0-7
|
||||
uint8_t sigmaDeltaRead(uint8_t channel) //chan 0-x according to SOC
|
||||
{
|
||||
if(channel > 7) {
|
||||
if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
|
||||
return 0;
|
||||
}
|
||||
SD_MUTEX_LOCK();
|
||||
uint8_t duty = SIGMADELTA.channel[channel].duty + 128;
|
||||
SD_MUTEX_UNLOCK();
|
||||
return duty;
|
||||
}
|
||||
|
||||
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel) //channel 0-7
|
||||
{
|
||||
if(channel > 7) {
|
||||
return;
|
||||
}
|
||||
pinMode(pin, OUTPUT);
|
||||
pinMatrixOutAttach(pin, GPIO_SD0_OUT_IDX + channel, false, false);
|
||||
return duty_set[channel]+128;
|
||||
}
|
||||
|
||||
void sigmaDeltaDetachPin(uint8_t pin)
|
||||
|
@ -23,10 +23,9 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
|
||||
//channel 0-7 freq 1220-312500 duty 0-255
|
||||
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq);
|
||||
uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq);
|
||||
void sigmaDeltaWrite(uint8_t channel, uint8_t duty);
|
||||
uint8_t sigmaDeltaRead(uint8_t channel);
|
||||
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel);
|
||||
void sigmaDeltaDetachPin(uint8_t pin);
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -13,335 +13,227 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#endif
|
||||
#include "freertos/task.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "esp_attr.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/timer.h"
|
||||
#include "soc/soc_caps.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"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/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
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t reserved0: 10;
|
||||
uint32_t alarm_en: 1; /*When set alarm is enabled*/
|
||||
uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/
|
||||
uint32_t edge_int_en: 1; /*When set edge type interrupt will be generated during alarm*/
|
||||
uint32_t divider: 16; /*Timer clock (T0/1_clk) pre-scale value.*/
|
||||
uint32_t autoreload: 1; /*When set timer 0/1 auto-reload at alarming is enabled*/
|
||||
uint32_t increase: 1; /*When set timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/
|
||||
uint32_t enable: 1; /*When set timer 0/1 time-base counter is enabled*/
|
||||
};
|
||||
uint32_t val;
|
||||
} timer_cfg_t;
|
||||
|
||||
#define HWTIMER_LOCK() portENTER_CRITICAL(timer->lock)
|
||||
#define HWTIMER_UNLOCK() portEXIT_CRITICAL(timer->lock)
|
||||
#define NUM_OF_TIMERS SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||
|
||||
typedef volatile struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t reserved0: 10;
|
||||
uint32_t alarm_en: 1; /*When set alarm is enabled*/
|
||||
uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/
|
||||
uint32_t edge_int_en: 1; /*When set edge type interrupt will be generated during alarm*/
|
||||
uint32_t divider: 16; /*Timer clock (T0/1_clk) pre-scale value.*/
|
||||
uint32_t autoreload: 1; /*When set timer 0/1 auto-reload at alarming is enabled*/
|
||||
uint32_t increase: 1; /*When set timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/
|
||||
uint32_t enable: 1; /*When set timer 0/1 time-base counter is enabled*/
|
||||
};
|
||||
uint32_t val;
|
||||
} config;
|
||||
uint32_t cnt_low; /*Register to store timer 0/1 time-base counter current value lower 32 bits.*/
|
||||
uint32_t cnt_high; /*Register to store timer 0 time-base counter current value higher 32 bits.*/
|
||||
uint32_t update; /*Write any value will trigger a timer 0 time-base counter value update (timer 0 current value will be stored in registers above)*/
|
||||
uint32_t alarm_low; /*Timer 0 time-base counter value lower 32 bits that will trigger the alarm*/
|
||||
uint32_t alarm_high; /*Timer 0 time-base counter value higher 32 bits that will trigger the alarm*/
|
||||
uint32_t load_low; /*Lower 32 bits of the value that will load into timer 0 time-base counter*/
|
||||
uint32_t load_high; /*higher 32 bits of the value that will load into timer 0 time-base counter*/
|
||||
uint32_t reload; /*Write any value will trigger timer 0 time-base counter reload*/
|
||||
} hw_timer_reg_t;
|
||||
typedef struct {
|
||||
int timer_group;
|
||||
int timer_idx;
|
||||
int alarm_interval;
|
||||
bool auto_reload;
|
||||
} timer_info_t;
|
||||
|
||||
typedef struct hw_timer_s {
|
||||
hw_timer_reg_t * dev;
|
||||
uint8_t num;
|
||||
uint8_t group;
|
||||
uint8_t timer;
|
||||
portMUX_TYPE lock;
|
||||
typedef struct hw_timer_s
|
||||
{
|
||||
uint8_t group;
|
||||
uint8_t num;
|
||||
} hw_timer_t;
|
||||
|
||||
static hw_timer_t hw_timer[4] = {
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE),0,0,0,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x0024),1,0,1,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1000),2,1,0,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1024),3,1,1,portMUX_INITIALIZER_UNLOCKED}
|
||||
// Works for all chips
|
||||
static hw_timer_t timer_dev[4] = {
|
||||
{0,0}, {1,0}, {1,0}, {1,1}
|
||||
};
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
static voidFuncPtr __timerInterruptHandlers[4] = {0,0,0,0};
|
||||
// NOTE: (in IDF 5.0 there wont be need to know groups/numbers
|
||||
// timer_init() will list thru all timers and return free timer handle)
|
||||
|
||||
void ARDUINO_ISR_ATTR __timerISR(void * arg){
|
||||
uint32_t s0 = TIMERG0.int_st_timers.val;
|
||||
uint32_t s1 = TIMERG1.int_st_timers.val;
|
||||
TIMERG0.int_clr_timers.val = s0;
|
||||
TIMERG1.int_clr_timers.val = s1;
|
||||
uint8_t status = (s1 & 3) << 2 | (s0 & 3);
|
||||
uint8_t i = 4;
|
||||
//restart the timers that should autoreload
|
||||
while(i--){
|
||||
hw_timer_reg_t * dev = hw_timer[i].dev;
|
||||
if((status & (1 << i)) && dev->config.autoreload){
|
||||
dev->config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
i = 4;
|
||||
//call callbacks
|
||||
while(i--){
|
||||
if(__timerInterruptHandlers[i] && (status & (1 << i))){
|
||||
__timerInterruptHandlers[i]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t inline timerRead(hw_timer_t *timer){
|
||||
timer->dev->update = 1;
|
||||
while (timer->dev->update) {};
|
||||
uint64_t h = timer->dev->cnt_high;
|
||||
uint64_t l = timer->dev->cnt_low;
|
||||
return (h << 32) | l;
|
||||
|
||||
uint64_t value;
|
||||
timer_get_counter_value(timer->group, timer->num,&value);
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t timerAlarmRead(hw_timer_t *timer){
|
||||
uint64_t h = timer->dev->alarm_high;
|
||||
uint64_t l = timer->dev->alarm_low;
|
||||
return (h << 32) | l;
|
||||
uint64_t value;
|
||||
timer_get_alarm_value(timer->group, timer->num, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void timerWrite(hw_timer_t *timer, uint64_t val){
|
||||
timer->dev->load_high = (uint32_t) (val >> 32);
|
||||
timer->dev->load_low = (uint32_t) (val);
|
||||
timer->dev->reload = 1;
|
||||
timer_set_counter_value(timer->group, timer->num, val);
|
||||
}
|
||||
|
||||
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){
|
||||
timer->dev->alarm_high = (uint32_t) (alarm_value >> 32);
|
||||
timer->dev->alarm_low = (uint32_t) alarm_value;
|
||||
timer->dev->config.autoreload = autoreload;
|
||||
timer_set_alarm_value(timer->group, timer->num, alarm_value);
|
||||
timerSetAutoReload(timer,autoreload);
|
||||
}
|
||||
|
||||
void timerSetConfig(hw_timer_t *timer, uint32_t config){
|
||||
timer->dev->config.val = config;
|
||||
timer_cfg_t cfg;
|
||||
cfg.val = config;
|
||||
timer_set_alarm(timer->group, timer->num, cfg.alarm_en);
|
||||
timerSetDivider(timer,cfg.divider);
|
||||
timerSetAutoReload(timer,cfg.autoreload);
|
||||
timerSetCountUp(timer, cfg.increase);
|
||||
|
||||
if (cfg.enable) {
|
||||
timerStart(timer);
|
||||
}
|
||||
else{
|
||||
timerStop(timer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t timerGetConfig(hw_timer_t *timer){
|
||||
return timer->dev->config.val;
|
||||
timer_config_t timer_cfg;
|
||||
timer_get_config(timer->group, timer->num,&timer_cfg);
|
||||
|
||||
//Translate to default uint32_t
|
||||
timer_cfg_t cfg;
|
||||
cfg.alarm_en = timer_cfg.alarm_en;
|
||||
cfg.autoreload = timer_cfg.auto_reload;
|
||||
cfg.divider = timer_cfg.divider;
|
||||
cfg.edge_int_en = timer_cfg.intr_type;
|
||||
cfg.level_int_en = !timer_cfg.intr_type;
|
||||
cfg.enable = timer_cfg.counter_en;
|
||||
cfg.increase = timer_cfg.counter_dir;
|
||||
|
||||
return cfg.val;
|
||||
}
|
||||
|
||||
void timerSetCountUp(hw_timer_t *timer, bool countUp){
|
||||
timer->dev->config.increase = countUp;
|
||||
timer_set_counter_mode(timer->group, timer->num,countUp);
|
||||
}
|
||||
|
||||
bool timerGetCountUp(hw_timer_t *timer){
|
||||
return timer->dev->config.increase;
|
||||
timer_cfg_t config;
|
||||
config.val = timerGetConfig(timer);
|
||||
return config.increase;
|
||||
}
|
||||
|
||||
void timerSetAutoReload(hw_timer_t *timer, bool autoreload){
|
||||
timer->dev->config.autoreload = autoreload;
|
||||
timer_set_auto_reload(timer->group, timer->num,autoreload);
|
||||
}
|
||||
|
||||
bool timerGetAutoReload(hw_timer_t *timer){
|
||||
return timer->dev->config.autoreload;
|
||||
timer_cfg_t config;
|
||||
config.val= timerGetConfig(timer);
|
||||
return config.autoreload;
|
||||
}
|
||||
|
||||
void timerSetDivider(hw_timer_t *timer, uint16_t divider){//2 to 65536
|
||||
if(!divider){
|
||||
divider = 0xFFFF;
|
||||
} else if(divider == 1){
|
||||
divider = 2;
|
||||
// Set divider from 2 to 65535
|
||||
void timerSetDivider(hw_timer_t *timer, uint16_t divider){
|
||||
if(divider < 2)
|
||||
{
|
||||
log_e("Timer divider must be set in range of 2 to 65535");
|
||||
return;
|
||||
}
|
||||
int timer_en = timer->dev->config.enable;
|
||||
timer->dev->config.enable = 0;
|
||||
timer->dev->config.divider = divider;
|
||||
timer->dev->config.enable = timer_en;
|
||||
timer_set_divider(timer->group, timer->num,divider);
|
||||
}
|
||||
|
||||
uint16_t timerGetDivider(hw_timer_t *timer){
|
||||
return timer->dev->config.divider;
|
||||
timer_cfg_t config;
|
||||
config.val = timerGetConfig(timer);
|
||||
return config.divider;
|
||||
}
|
||||
|
||||
void timerStart(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 1;
|
||||
timer_start(timer->group, timer->num);
|
||||
}
|
||||
|
||||
void timerStop(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
timer_pause(timer->group, timer->num);
|
||||
}
|
||||
|
||||
void timerRestart(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
timer->dev->reload = 1;
|
||||
timer->dev->config.enable = 1;
|
||||
timerWrite(timer,0);
|
||||
}
|
||||
|
||||
bool timerStarted(hw_timer_t *timer){
|
||||
return timer->dev->config.enable;
|
||||
timer_cfg_t config;
|
||||
config.val = timerGetConfig(timer);
|
||||
return config.enable;
|
||||
}
|
||||
|
||||
void timerAlarmEnable(hw_timer_t *timer){
|
||||
timer->dev->config.alarm_en = 1;
|
||||
timer_set_alarm(timer->group, timer->num,true);
|
||||
}
|
||||
|
||||
void timerAlarmDisable(hw_timer_t *timer){
|
||||
timer->dev->config.alarm_en = 0;
|
||||
timer_set_alarm(timer->group, timer->num,false);
|
||||
}
|
||||
|
||||
bool timerAlarmEnabled(hw_timer_t *timer){
|
||||
return timer->dev->config.alarm_en;
|
||||
timer_cfg_t config;
|
||||
config.val = timerGetConfig(timer);
|
||||
return config.alarm_en;
|
||||
}
|
||||
|
||||
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
||||
hw_timer_t * timer = (hw_timer_t *)arg;
|
||||
if(ev_type == APB_BEFORE_CHANGE){
|
||||
timer->dev->config.enable = 0;
|
||||
timerStop(timer);
|
||||
} else {
|
||||
old_apb /= 1000000;
|
||||
new_apb /= 1000000;
|
||||
timer->dev->config.divider = (new_apb * timer->dev->config.divider) / old_apb;
|
||||
timer->dev->config.enable = 1;
|
||||
uint16_t divider = (new_apb * timerGetDivider(timer)) / old_apb;
|
||||
timerSetDivider(timer,divider);
|
||||
timerStart(timer);
|
||||
}
|
||||
}
|
||||
|
||||
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
|
||||
if(num > 3){
|
||||
if(num >= NUM_OF_TIMERS)
|
||||
{
|
||||
log_e("Timer dont have that timer number.");
|
||||
return NULL;
|
||||
}
|
||||
hw_timer_t * timer = &hw_timer[num];
|
||||
if(timer->group) {
|
||||
periph_module_enable(PERIPH_TIMG1_MODULE);
|
||||
} else {
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
}
|
||||
timer->dev->config.enable = 0;
|
||||
if(timer->group) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG1.int_ena.val &= ~BIT(timer->timer);
|
||||
#else
|
||||
TIMERG1.int_ena_timers.val &= ~BIT(timer->timer);
|
||||
#endif
|
||||
TIMERG1.int_clr_timers.val |= BIT(timer->timer);
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG0.int_ena.val &= ~BIT(timer->timer);
|
||||
#else
|
||||
TIMERG0.int_ena_timers.val &= ~BIT(timer->timer);
|
||||
#endif
|
||||
TIMERG0.int_clr_timers.val |= BIT(timer->timer);
|
||||
}
|
||||
#ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK
|
||||
timer->dev->config.use_xtal = 0;
|
||||
#endif
|
||||
timerSetDivider(timer, divider);
|
||||
timerSetCountUp(timer, countUp);
|
||||
timerSetAutoReload(timer, false);
|
||||
timerAttachInterrupt(timer, NULL, false);
|
||||
timerWrite(timer, 0);
|
||||
timer->dev->config.enable = 1;
|
||||
|
||||
hw_timer_t * timer = &timer_dev[num]; //Get Timer group/num from 0-3 number
|
||||
|
||||
timer_config_t config = {
|
||||
.divider = divider,
|
||||
.counter_dir = countUp,
|
||||
.counter_en = TIMER_PAUSE,
|
||||
.alarm_en = TIMER_ALARM_DIS,
|
||||
.auto_reload = false,
|
||||
};
|
||||
|
||||
timer_init(timer->group, timer->num, &config);
|
||||
timer_set_counter_value(timer->group, timer->num, 0);
|
||||
timerStart(timer);
|
||||
addApbChangeCallback(timer, _on_apb_change);
|
||||
return timer;
|
||||
}
|
||||
|
||||
void timerEnd(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
timerAttachInterrupt(timer, NULL, false);
|
||||
removeApbChangeCallback(timer, _on_apb_change);
|
||||
timer_deinit(timer->group, timer->num);
|
||||
}
|
||||
|
||||
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(edge){
|
||||
log_w("EDGE timer interrupt does not work properly on ESP32! Setting to LEVEL...");
|
||||
log_w("EDGE timer interrupt is not supported! Setting to LEVEL...");
|
||||
edge = false;
|
||||
}
|
||||
#endif
|
||||
static bool initialized = false;
|
||||
static intr_handle_t intr_handle = NULL;
|
||||
if(intr_handle){
|
||||
esp_intr_disable(intr_handle);
|
||||
}
|
||||
if(fn == NULL){
|
||||
timer->dev->config.level_int_en = 0;
|
||||
timer->dev->config.edge_int_en = 0;
|
||||
timer->dev->config.alarm_en = 0;
|
||||
if(timer->num & 2){
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG1.int_ena.val &= ~BIT(timer->timer);
|
||||
#else
|
||||
TIMERG1.int_ena_timers.val &= ~BIT(timer->timer);
|
||||
#endif
|
||||
TIMERG1.int_clr_timers.val |= BIT(timer->timer);
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG0.int_ena.val &= ~BIT(timer->timer);
|
||||
#else
|
||||
TIMERG0.int_ena_timers.val &= ~BIT(timer->timer);
|
||||
#endif
|
||||
TIMERG0.int_clr_timers.val |= BIT(timer->timer);
|
||||
}
|
||||
__timerInterruptHandlers[timer->num] = NULL;
|
||||
} else {
|
||||
__timerInterruptHandlers[timer->num] = fn;
|
||||
timer->dev->config.level_int_en = edge?0:1;//When set, an alarm will generate a level type interrupt.
|
||||
timer->dev->config.edge_int_en = edge?1:0;//When set, an alarm will generate an edge type interrupt.
|
||||
int intr_source = 0;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
if(!edge){
|
||||
#endif
|
||||
if(timer->group){
|
||||
intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer->timer;
|
||||
} else {
|
||||
intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer->timer;
|
||||
}
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
} else {
|
||||
if(timer->group){
|
||||
intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer->timer;
|
||||
} else {
|
||||
intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer->timer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(!initialized){
|
||||
initialized = true;
|
||||
esp_intr_alloc(intr_source, (int)(ARDUINO_ISR_FLAG|ESP_INTR_FLAG_LOWMED), __timerISR, NULL, &intr_handle);
|
||||
} else {
|
||||
intr_matrix_set(esp_intr_get_cpu(intr_handle), intr_source, esp_intr_get_intno(intr_handle));
|
||||
}
|
||||
if(timer->group){
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG1.int_ena.val |= BIT(timer->timer);
|
||||
#else
|
||||
TIMERG1.int_ena_timers.val |= BIT(timer->timer);
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG0.int_ena.val |= BIT(timer->timer);
|
||||
#else
|
||||
TIMERG0.int_ena_timers.val |= BIT(timer->timer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(intr_handle){
|
||||
esp_intr_enable(intr_handle);
|
||||
}
|
||||
timer_enable_intr(timer->group, timer->num);
|
||||
|
||||
timer_info_t *timer_info = calloc(1, sizeof(timer_info_t));
|
||||
timer_info->timer_group = timer->group;
|
||||
timer_info->timer_idx = timer->num;
|
||||
timer_info->auto_reload = timerGetAutoReload(timer);
|
||||
timer_info->alarm_interval = timerAlarmRead(timer);
|
||||
|
||||
timer_isr_callback_add(timer->group, timer->num, (timer_isr_t)fn, timer_info, 0);
|
||||
}
|
||||
|
||||
void timerDetachInterrupt(hw_timer_t *timer){
|
||||
@ -354,6 +246,12 @@ uint64_t timerReadMicros(hw_timer_t *timer){
|
||||
return timer_val * div / (getApbFrequency() / 1000000);
|
||||
}
|
||||
|
||||
uint64_t timerReadMilis(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
return timer_val * div / (getApbFrequency() / 1000);
|
||||
}
|
||||
|
||||
double timerReadSeconds(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
@ -366,6 +264,12 @@ uint64_t timerAlarmReadMicros(hw_timer_t *timer){
|
||||
return timer_val * div / (getApbFrequency() / 1000000);
|
||||
}
|
||||
|
||||
uint64_t timerAlarmReadMilis(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerAlarmRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
return timer_val * div / (getApbFrequency() / 1000);
|
||||
}
|
||||
|
||||
double timerAlarmReadSeconds(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerAlarmRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
|
@ -20,13 +20,13 @@
|
||||
#ifndef MAIN_ESP32_HAL_TIMER_H_
|
||||
#define MAIN_ESP32_HAL_TIMER_H_
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
struct hw_timer_s;
|
||||
typedef struct hw_timer_s hw_timer_t;
|
||||
|
||||
@ -50,6 +50,7 @@ void timerSetAutoReload(hw_timer_t *timer, bool autoreload);
|
||||
bool timerStarted(hw_timer_t *timer);
|
||||
uint64_t timerRead(hw_timer_t *timer);
|
||||
uint64_t timerReadMicros(hw_timer_t *timer);
|
||||
uint64_t timerReadMilis(hw_timer_t *timer);
|
||||
double timerReadSeconds(hw_timer_t *timer);
|
||||
uint16_t timerGetDivider(hw_timer_t *timer);
|
||||
bool timerGetCountUp(hw_timer_t *timer);
|
||||
@ -57,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,251 @@
|
||||
// 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;
|
||||
}
|
||||
// Initial no Threshold and setup
|
||||
for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||
__touchInterruptHandlers[i].fn = NULL;
|
||||
touch_pad_config(i, SOC_TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK
|
||||
}
|
||||
// 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
|
||||
|
||||
// Initial no Threshold and setup - TOUCH0 is internal denoise channel
|
||||
for (int i = 1; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||
__touchInterruptHandlers[i].fn = NULL;
|
||||
touch_pad_config(i); // returns ESP_OK
|
||||
}
|
||||
// keep ISR activated - it can run all together (ISR + touchRead())
|
||||
err = touch_pad_isr_register(__touchISR, NULL, TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); // returns ESP_OK
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
return;
|
||||
err:
|
||||
log_e(" Touch sensor initialization error.");
|
||||
initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t __touchRead(uint8_t pin)
|
||||
static touch_value_t __touchRead(uint8_t pin)
|
||||
{
|
||||
int8_t pad = digitalPinToTouchChannel(pin);
|
||||
if(pad < 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
pinMode(pin, ANALOG);
|
||||
|
||||
__touchInit();
|
||||
|
||||
#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();
|
||||
__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,21 +58,46 @@ 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
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// solves issue https://github.com/espressif/arduino-esp32/issues/6032
|
||||
// baudrate must be multiplied when CPU Frequency is lower than APB 80MHz
|
||||
uint32_t _get_effective_baudrate(uint32_t baudrate)
|
||||
{
|
||||
uint32_t Freq = getApbFrequency()/1000000;
|
||||
if (Freq < 80) {
|
||||
return 80 / Freq * baudrate;
|
||||
}
|
||||
else {
|
||||
return 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)) {
|
||||
@ -81,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));
|
||||
// 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)) {
|
||||
@ -121,7 +154,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
UART_MUTEX_LOCK();
|
||||
|
||||
uart_config_t uart_config;
|
||||
uart_config.baud_rate = baudrate;
|
||||
uart_config.baud_rate = _get_effective_baudrate(baudrate);
|
||||
uart_config.data_bits = (config & 0xc) >> 2;
|
||||
uart_config.parity = (config & 0x3);
|
||||
uart_config.stop_bits = (config & 0x30) >> 4;
|
||||
@ -130,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));
|
||||
|
||||
@ -290,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));
|
||||
@ -304,7 +337,7 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), baud_rate);
|
||||
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate));
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
@ -388,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;
|
||||
}
|
||||
}
|
||||
@ -454,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;
|
||||
}
|
||||
@ -471,6 +506,9 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -515,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;
|
||||
@ -552,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
|
||||
|
0
cores/esp32/libb64/AUTHORS
Executable file → Normal file
0
cores/esp32/libb64/AUTHORS
Executable file → Normal file
0
cores/esp32/libb64/LICENSE
Executable file → Normal file
0
cores/esp32/libb64/LICENSE
Executable file → Normal file
0
cores/esp32/libb64/cdecode.c
Executable file → Normal file
0
cores/esp32/libb64/cdecode.c
Executable file → Normal file
0
cores/esp32/libb64/cdecode.h
Executable file → Normal file
0
cores/esp32/libb64/cdecode.h
Executable file → Normal file
0
cores/esp32/libb64/cencode.c
Executable file → Normal file
0
cores/esp32/libb64/cencode.c
Executable file → Normal file
0
cores/esp32/libb64/cencode.h
Executable file → Normal file
0
cores/esp32/libb64/cencode.h
Executable file → Normal file
@ -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"
|
||||
@ -33,6 +33,10 @@ void yieldIfNecessary(void){
|
||||
|
||||
bool loopTaskWDTEnabled;
|
||||
|
||||
__attribute__((weak)) size_t getArduinoLoopTaskStackSize(void) {
|
||||
return ARDUINO_LOOP_STACK_SIZE;
|
||||
}
|
||||
|
||||
void loopTask(void *pvParameters)
|
||||
{
|
||||
setup();
|
||||
@ -50,21 +54,21 @@ 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;
|
||||
initArduino();
|
||||
xTaskCreateUniversal(loopTask, "loopTask", ARDUINO_LOOP_STACK_SIZE, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
|
||||
xTaskCreateUniversal(loopTask, "loopTask", getArduinoLoopTaskStackSize(), NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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/gpio_output.png
Normal file
BIN
docs/source/_static/gpio_output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
BIN
docs/source/_static/gpio_pullup.png
Normal file
BIN
docs/source/_static/gpio_pullup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
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.
|
@ -1,3 +1,170 @@
|
||||
####
|
||||
GPIO
|
||||
####
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
One of the most used and versatile peripheral in a microcontroller is the GPIO. The GPIO is commonly used to write and read the pin state.
|
||||
|
||||
GPIO stands to General Purpose Input Output, and is responsible to control or read the state of a specific pin in the digital world. For example, this peripheral is widely used to create the LED blinking or to read a simple button.
|
||||
|
||||
.. note:: There are some GPIOs with special restrictions, and not all GPIOs are accessible through the developemnt board. For more information about it, see the corresponding board pin layout information.
|
||||
|
||||
GPIOs Modes
|
||||
***********
|
||||
|
||||
There are two different modes in the GPIO configuration:
|
||||
|
||||
- **Input Mode**
|
||||
|
||||
In this mode, the GPIO will receive the digital state from a specific device. This device could be a button or a switch.
|
||||
|
||||
- **Output Mode**
|
||||
|
||||
For the output mode, the GPIO will change the GPIO digital state to a specific device. You can drive an LED for example.
|
||||
|
||||
GPIO API
|
||||
--------
|
||||
|
||||
Here is the common functions used for the GPIO peripheral.
|
||||
|
||||
pinMode
|
||||
*******
|
||||
|
||||
The ``pinMode`` function is used to define the GPIO operation mode for a specific pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
* ``mode`` sets operation mode.
|
||||
|
||||
The following modes are supported for the basic `input` and `output`:
|
||||
|
||||
* **INPUT** sets the GPIO as input without pullup or pulldown (high impedance).
|
||||
* **OUTPUT** sets the GPIO as output/read mode.
|
||||
* **INPUT_PULLDOWN** sets the GPIO as input with the internal pulldown.
|
||||
* **INPUT_PULLUP** sets the GPIO as input with the internal pullup.
|
||||
|
||||
Internal Pullup and Pulldown
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ESP32 SoC families supports the internal pullup and pulldown throught a 45kR resistor, that can be enabled when configuring the GPIO mode as ``INPUT`` mode.
|
||||
If the pullup or pulldown mode is not defined, the pin will stay in the high impedance mode.
|
||||
|
||||
digitalWrite
|
||||
*************
|
||||
|
||||
The function ``digitalWrite`` sets the state of the selected GPIO to ``HIGH`` or ``LOW``. This function is only used if the ``pinMode`` was configured as ``OUTPUT``.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void digitalWrite(uint8_t pin, uint8_t val);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
* ``val`` set the output digital state to ``HIGH`` or ``LOW``.
|
||||
|
||||
digitalRead
|
||||
***********
|
||||
|
||||
To read the state of a given pin configured as ``INPUT``, the function ``digitalRead`` is used.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int digitalRead(uint8_t pin);
|
||||
|
||||
* ``pin`` select GPIO
|
||||
|
||||
This function will return the logical state of the selected pin as ``HIGH`` or ``LOW``.
|
||||
|
||||
Interrupts
|
||||
----------
|
||||
|
||||
The GPIO peripheral on the ESP32 supports interruptions.
|
||||
|
||||
attachInterrupt
|
||||
***************
|
||||
|
||||
The function ``attachInterruptArg`` is used to attach the interrupt to the defined pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
* ``handler`` set the handler function.
|
||||
* ``mode`` set the interrupt mode.
|
||||
|
||||
Here are the supported interrupt modes:
|
||||
|
||||
* **DISABLED**
|
||||
* **RISING**
|
||||
* **FALLING**
|
||||
* **CHANGE**
|
||||
* **ONLOW**
|
||||
* **ONHIGH**
|
||||
* **ONLOW_WE**
|
||||
* **ONHIGH_WE**
|
||||
|
||||
attachInterruptArg
|
||||
******************
|
||||
|
||||
The function ``attachInterruptArg`` is used to attach the interrupt to the defined pin using arguments.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
* ``handler`` set the handler function.
|
||||
* ``arg`` pointer to the interrupt arguments.
|
||||
* ``mode`` set the interrupt mode.
|
||||
|
||||
detachInterrupt
|
||||
***************
|
||||
|
||||
To detach the interruption from a specific pin, use the ``detachInterrupt`` function giving the GPIO to be detached.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
detachInterrupt(uint8_t pin);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
|
||||
.. _gpio_example_code:
|
||||
|
||||
Example Code
|
||||
------------
|
||||
|
||||
GPIO Input and Output Modes
|
||||
***************************
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
#define LED 12
|
||||
#define BUTTON 2
|
||||
|
||||
uint8_t stateLED = 0;
|
||||
|
||||
void setup() {
|
||||
pinMode(LED, OUTPUT);
|
||||
pinMode(BUTTON,INPUT_PULLUP);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
if(!digitalRead(BUTTON)){
|
||||
stateLED = stateLED^1;
|
||||
digitalWrite(LED,stateLED);
|
||||
}
|
||||
}
|
||||
|
||||
GPIO Interrupt
|
||||
**************
|
||||
|
||||
.. literalinclude:: ../../../libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino
|
||||
:language: arduino
|
||||
|
||||
.. _datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
|
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 ----
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user