forked from espressif/arduino-esp32
Compare commits
249 Commits
Author | SHA1 | Date | |
---|---|---|---|
33011ede30 | |||
f3e416217d | |||
0efa90df6e | |||
548412952b | |||
3e8f7fe8d4 | |||
832c08e9fb | |||
99ba0e1cc5 | |||
d32d70dc0d | |||
6b93a6c21e | |||
f9423ab83f | |||
e5913c36ea | |||
247bca8bda | |||
46a026a45d | |||
2cb664eeec | |||
2cde553e17 | |||
adb88d7bed | |||
1a7962ece8 | |||
2b67a4e68a | |||
722c4641c4 | |||
ba6e82c30d | |||
ad14258d2c | |||
ed33e15752 | |||
5482315036 | |||
09c0a39d2a | |||
a9d77ac66e | |||
14156d8071 | |||
b42b20850b | |||
edd2bd2dab | |||
1fed09bc74 | |||
49bdd5f053 | |||
709029996f | |||
bdeef89cc6 | |||
ca77502ceb | |||
d302091267 | |||
5dc4226cc5 | |||
85ec66a4e0 | |||
44beee2f2c | |||
0b3f1a9fa9 | |||
6707ceb63c | |||
142fceb856 | |||
ba591fd958 | |||
4453ca5493 | |||
ce2cd111a1 | |||
5f6d093d4a | |||
51bf1832b8 | |||
384dbc2081 | |||
f2cfe78705 | |||
45583af189 | |||
f60cd8a069 | |||
5fa0c2010e | |||
adfaaecc65 | |||
0dd517dc9f | |||
823fe77e41 | |||
a9d33de70e | |||
d7ffd573d0 | |||
b88a70a0bd | |||
f3bdfb31f9 | |||
d8a99ed449 | |||
0a1ba74b60 | |||
1aa16104ff | |||
22c51579da | |||
f0636d515f | |||
b3c203db26 | |||
323bbbf63b | |||
02f4178b72 | |||
e1c9606531 | |||
fb60efd592 | |||
12045d335b | |||
45b7fa05b6 | |||
d3340837c7 | |||
6cfe4613e4 | |||
7dc8ca4e1e | |||
d4e20294e5 | |||
f1acc432af | |||
6fe1c4c5d6 | |||
5d6b9d0939 | |||
6b72fee59b | |||
a1409ef90d | |||
ab197e12a9 | |||
1e388a24ce | |||
7c9b837cdb | |||
5c5a112ffa | |||
31510f4e17 | |||
aa783e6ac4 | |||
9d188f5c67 | |||
51040cc4eb | |||
c26e3f4299 | |||
ab34321a16 | |||
8ee5f0a11e | |||
3f79097d5f | |||
e03a9f5c53 | |||
528c071299 | |||
7b89b39e10 | |||
905f8f2991 | |||
c25feca639 | |||
6014ff433f | |||
77e95311e0 | |||
8fe0efe8c0 | |||
0b10c8b79e | |||
d977359e34 | |||
ba8024c0d2 | |||
e87b87d04c | |||
9b9744f25f | |||
68daea4a4a | |||
52e018198b | |||
883241229e | |||
9b00d4ae6b | |||
66596fa581 | |||
02a3a71e7c | |||
3a7dfa14db | |||
96f8f5e3ef | |||
4da1051266 | |||
7d4992a811 | |||
95b8e7e42b | |||
e8d6050a7b | |||
683dbf3b1b | |||
c2e5957f35 | |||
eae67a9fb4 | |||
52575d63f4 | |||
d1f0d6c0fc | |||
bf58ab65e9 | |||
c280225738 | |||
4f7e88a177 | |||
b254765ef8 | |||
8899de760a | |||
524279d468 | |||
f319804521 | |||
2884215f85 | |||
a57cac63e4 | |||
de6994187d | |||
491444c15a | |||
a135169176 | |||
b5f3d6c836 | |||
d5e8c9dddc | |||
65cfab7868 | |||
4517b9c8fc | |||
dad946a641 | |||
7c58696223 | |||
02a70bbd21 | |||
50e9772ecf | |||
01303b700d | |||
4900979906 | |||
c7cc5c90eb | |||
70b7c3afcb | |||
e83a9b5f60 | |||
7be846cb23 | |||
2c7052a64c | |||
c99f594b63 | |||
05d8cddee7 | |||
c4954dd582 | |||
4cbb7389db | |||
ab6e010c20 | |||
7eec41dcb5 | |||
9dbc908784 | |||
9b066ea61c | |||
bb4d9027dd | |||
1046f59f6b | |||
6591f5bd4c | |||
0ea485e518 | |||
3a96fc0e4a | |||
5be3ff74ea | |||
dafdc05249 | |||
ef35baffb0 | |||
7a6dae02aa | |||
9f08cf4767 | |||
96a5ddcd0e | |||
9fe34f6553 | |||
cbeb7c4df8 | |||
754ceddf48 | |||
39a2080922 | |||
9555ed4b76 | |||
0d665d7e55 | |||
bb7df04446 | |||
ce68d72157 | |||
6a7bcabd6b | |||
a61609376a | |||
4a1cbeb69b | |||
a5932064f9 | |||
a45790b20e | |||
0b4516eef5 | |||
cbfcfbf970 | |||
c9b0dc99d3 | |||
a134088a0b | |||
78b2df74f5 | |||
77756d8a06 | |||
c6e30e0027 | |||
41d972564c | |||
a0beb81a4c | |||
460af2e1a5 | |||
48a722aae8 | |||
702db50627 | |||
1ac3aefa61 | |||
e84e9c153e | |||
1d3ff0520a | |||
b3b3403296 | |||
c014eaf352 | |||
5ae3886c66 | |||
1bbe61ab6f | |||
841599c248 | |||
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
|
133
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
Normal file
133
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
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 (checkout manually)
|
||||
- latest development Release Candidate (RC-X)
|
||||
- v2.0.3
|
||||
- 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, Sloeber...
|
||||
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 full minimal sketch/code which can be run to reproduce your issue
|
||||
placeholder: ex. Related part of the code to replicate the issue
|
||||
render: cpp
|
||||
validations:
|
||||
required: true
|
||||
- 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
|
29
.github/PULL_REQUEST_TEMPLATE.md
vendored
29
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,16 +1,23 @@
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
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*
|
||||
*By completing this PR sufficiently, you help us to review this Pull Request quicker and also help improve the quality of Release Notes*
|
||||
|
||||
### Checklist
|
||||
1. [ ] Please provide specific title of the PR describing the change, including the component name (*eg. „Update of Documentation link on Readme.md“*)
|
||||
2. [ ] Please provide related links (*eg. Issue which will be closed by this Pull Request*)
|
||||
3. [ ] Please **update relevant Documentation** if applicable
|
||||
4. [ ] Please check [Contributing guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html)
|
||||
|
||||
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..)
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
*This entire section above can be deleted if all items are checked.*
|
||||
|
||||
## Summary
|
||||
Please describe your proposed PR and what it contains.
|
||||
-----------
|
||||
## Description of Change
|
||||
Please describe your proposed Pull Request and it's impact.
|
||||
|
||||
## Impact
|
||||
Please describe impact of your PR and it's function.
|
||||
## Tests scenarios
|
||||
Please describe on what Hardware and Software combinations you have tested this Pull Request and how.
|
||||
|
||||
(*eg. I have tested my Pull Request on Arduino-esp32 core v2.0.2 with ESP32 and ESP32-S2 Board with this scenario*)
|
||||
|
||||
## Related links
|
||||
Please provide links to related issue, PRs etc.
|
||||
|
||||
(*eg. Closes #number of issue*)
|
||||
|
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
|
||||
}
|
||||
|
31
.github/scripts/install-platformio-esp32.sh
vendored
31
.github/scripts/install-platformio-esp32.sh
vendored
@ -1,11 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
|
||||
PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master"
|
||||
PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git"
|
||||
|
||||
XTENSA32_TOOLCHAIN_VERSION="8.4.0+2021r1"
|
||||
XTENSA32S2_TOOLCHAIN_VERSION="8.4.0+2021r1"
|
||||
RISCV_TOOLCHAIN_VERSION="8.4.0+2021r1"
|
||||
TOOLCHAIN_VERSION="8.4.0+2021r2-patch3"
|
||||
ESPTOOLPY_VERSION="~1.30100.0"
|
||||
ESPRESSIF_ORGANIZATION_NAME="espressif"
|
||||
|
||||
@ -30,9 +28,12 @@ replace_script+="data['packages']['toolchain-xtensa-esp32']['owner']='$ESPRESSIF
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
|
||||
replace_script+="data['packages']['toolchain-riscv32-esp']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
|
||||
# Update versions to use the upstream
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$XTENSA32_TOOLCHAIN_VERSION';"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$XTENSA32S2_TOOLCHAIN_VERSION';"
|
||||
replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$RISCV_TOOLCHAIN_VERSION';"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$TOOLCHAIN_VERSION';"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$TOOLCHAIN_VERSION';"
|
||||
replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$TOOLCHAIN_VERSION';"
|
||||
# Add ESP32-S3 Toolchain
|
||||
replace_script+="data['packages'].update({'toolchain-xtensa-esp32s3':{'type':'toolchain','optional':True,'owner':'$ESPRESSIF_ORGANIZATION_NAME','version':'$TOOLCHAIN_VERSION'}});"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32'].update({'optional':False});"
|
||||
# esptool.py may require an upstream version (for now platformio is the owner)
|
||||
replace_script+="data['packages']['tool-esptoolpy']['version']='$ESPTOOLPY_VERSION';"
|
||||
# Save results
|
||||
@ -40,11 +41,11 @@ replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close
|
||||
python -c "$replace_script"
|
||||
|
||||
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
|
||||
echo "Linking Core..."
|
||||
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
|
||||
echo "Linking Core..."
|
||||
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
|
||||
else
|
||||
echo "Cloning Core Repository ..."
|
||||
git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
|
||||
echo "Cloning Core Repository ..."
|
||||
git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
echo "PlatformIO for ESP32 has been installed"
|
||||
@ -66,8 +67,7 @@ function build_pio_sketch(){ # build_pio_sketch <board> <options> <path-to-ino>
|
||||
python -m platformio ci --board "$board" "$sketch_dir" --project-option="$options"
|
||||
}
|
||||
|
||||
function count_sketches() # count_sketches <examples-path>
|
||||
{
|
||||
function count_sketches(){ # count_sketches <examples-path>
|
||||
local examples="$1"
|
||||
rm -rf sketches.txt
|
||||
if [ ! -d "$examples" ]; then
|
||||
@ -82,7 +82,7 @@ function count_sketches() # count_sketches <examples-path>
|
||||
local sketchname=$(basename $sketch)
|
||||
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
|
||||
continue
|
||||
fi;
|
||||
fi
|
||||
if [[ -f "$sketchdir/.test.skip" ]]; then
|
||||
continue
|
||||
fi
|
||||
@ -92,8 +92,7 @@ function count_sketches() # count_sketches <examples-path>
|
||||
return $sketchnum
|
||||
}
|
||||
|
||||
function build_pio_sketches() # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks>
|
||||
{
|
||||
function build_pio_sketches(){ # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks>
|
||||
if [ "$#" -lt 3 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: build_pio_sketches <board> <options> <examples-path> [<chunk> <total-chunks>]"
|
||||
|
2
.github/scripts/on-pages.sh
vendored
Normal file → Executable file
2
.github/scripts/on-pages.sh
vendored
Normal file → Executable file
@ -71,7 +71,7 @@ function git_safe_upload_to_pages(){
|
||||
local name=$(basename "$file")
|
||||
local size=`get_file_size "$file"`
|
||||
local upload_res=`git_upload_to_pages "$path" "$file"`
|
||||
if [ $? -ne 0 ]; then
|
||||
if [ $? -ne 0 ]; then
|
||||
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||
return 1
|
||||
fi
|
||||
|
165
.github/scripts/on-push.sh
vendored
165
.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"
|
||||
|
||||
# PlatformIO ESP32 Test
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
|
||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
|
||||
|
||||
# PlatformIO ESP32 Test
|
||||
# OPTIONS="board_build.mcu = esp32s2"
|
||||
# build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
||||
# build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
|
||||
|
||||
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s2" --project-option="board_build.partitions = huge_app.csv"
|
||||
|
||||
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
|
||||
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32c3" --project-option="board_build.partitions = huge_app.csv"
|
||||
|
||||
echo "Hacking in S3 support ..."
|
||||
replace_script="import json; import os;"
|
||||
replace_script+="fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+');"
|
||||
replace_script+="data=json.load(fp);"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32']['optional']=True;"
|
||||
replace_script+="data['packages']['toolchain-xtensa-esp32s3']['optional']=False;"
|
||||
replace_script+="data['packages']['tool-esptoolpy']['owner']='tasmota';"
|
||||
replace_script+="data['packages']['tool-esptoolpy']['version']='https://github.com/tasmota/esptool/releases/download/v3.3/esptool-3.3.zip';"
|
||||
replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close()"
|
||||
python -c "$replace_script"
|
||||
|
||||
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s3" --project-option="board_build.partitions = huge_app.csv"
|
||||
|
||||
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
|
||||
fi
|
||||
|
19
.github/scripts/on-release.sh
vendored
19
.github/scripts/on-release.sh
vendored
@ -33,7 +33,7 @@ PACKAGE_JSON_DEV="package_esp32_dev_index.json"
|
||||
PACKAGE_JSON_REL="package_esp32_index.json"
|
||||
|
||||
echo "Event: $GITHUB_EVENT_NAME, Repo: $GITHUB_REPOSITORY, Path: $GITHUB_WORKSPACE, Ref: $GITHUB_REF"
|
||||
echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID"
|
||||
echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID"
|
||||
echo "Tag: $RELEASE_TAG, Draft: $draft, Pre-Release: $RELEASE_PRE"
|
||||
|
||||
function get_file_size(){
|
||||
@ -60,7 +60,7 @@ function git_safe_upload_asset(){
|
||||
local name=$(basename "$file")
|
||||
local size=`get_file_size "$file"`
|
||||
local upload_res=`git_upload_asset "$file"`
|
||||
if [ $? -ne 0 ]; then
|
||||
if [ $? -ne 0 ]; then
|
||||
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||
return 1
|
||||
fi
|
||||
@ -112,7 +112,7 @@ function git_safe_upload_to_pages(){
|
||||
local name=$(basename "$file")
|
||||
local size=`get_file_size "$file"`
|
||||
local upload_res=`git_upload_to_pages "$path" "$file"`
|
||||
if [ $? -ne 0 ]; then
|
||||
if [ $? -ne 0 ]; then
|
||||
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||
return 1
|
||||
fi
|
||||
@ -131,7 +131,7 @@ function merge_package_json(){
|
||||
local jsonOut=$2
|
||||
local old_json=$OUTPUT_DIR/oldJson.json
|
||||
local merged_json=$OUTPUT_DIR/mergedJson.json
|
||||
|
||||
|
||||
echo "Downloading previous JSON $jsonLink ..."
|
||||
curl -L -o "$old_json" "https://github.com/$GITHUB_REPOSITORY/releases/download/$jsonLink?access_token=$GITHUB_TOKEN" 2>/dev/null
|
||||
if [ $? -ne 0 ]; then echo "ERROR: Download Failed! $?"; exit 1; fi
|
||||
@ -140,7 +140,7 @@ function merge_package_json(){
|
||||
set +e
|
||||
stdbuf -oL python "$PACKAGE_JSON_MERGE" "$jsonOut" "$old_json" > "$merged_json"
|
||||
set -e
|
||||
|
||||
|
||||
set -v
|
||||
if [ ! -s $merged_json ]; then
|
||||
rm -f "$merged_json"
|
||||
@ -172,6 +172,7 @@ mkdir -p "$PKG_DIR/tools"
|
||||
# Copy all core files to the package folder
|
||||
echo "Copying files for packaging ..."
|
||||
cp -f "$GITHUB_WORKSPACE/boards.txt" "$PKG_DIR/"
|
||||
cp -f "$GITHUB_WORKSPACE/package.json" "$PKG_DIR/"
|
||||
cp -f "$GITHUB_WORKSPACE/programmers.txt" "$PKG_DIR/"
|
||||
cp -Rf "$GITHUB_WORKSPACE/cores" "$PKG_DIR/"
|
||||
cp -Rf "$GITHUB_WORKSPACE/libraries" "$PKG_DIR/"
|
||||
@ -317,7 +318,7 @@ releaseNotes=""
|
||||
relNotesRaw=`git -C "$GITHUB_WORKSPACE" show -s --format=%b $RELEASE_TAG`
|
||||
readarray -t msgArray <<<"$relNotesRaw"
|
||||
arrLen=${#msgArray[@]}
|
||||
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
|
||||
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
|
||||
ind=3
|
||||
while [ $ind -lt $arrLen ]; do
|
||||
if [ $ind -eq 3 ]; then
|
||||
@ -327,7 +328,7 @@ if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
|
||||
oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')"
|
||||
if [ ${#oneLine} -gt 0 ]; then
|
||||
if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi
|
||||
if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi
|
||||
if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi
|
||||
releaseNotes+="$oneLine"
|
||||
releaseNotes+=$'\r\n'
|
||||
fi
|
||||
@ -368,9 +369,9 @@ done
|
||||
rm -f $commitFile
|
||||
|
||||
# Prepend the original release body
|
||||
if [ "${RELEASE_BODY: -1}" == $'\r' ]; then
|
||||
if [ "${RELEASE_BODY: -1}" == $'\r' ]; then
|
||||
RELEASE_BODY="${RELEASE_BODY:0:-1}"
|
||||
else
|
||||
else
|
||||
RELEASE_BODY="$RELEASE_BODY"
|
||||
fi
|
||||
RELEASE_BODY+=$'\r\n'
|
||||
|
192
.github/scripts/sketch_utils.sh
vendored
Executable file
192
.github/scripts/sketch_utils.sh
vendored
Executable file
@ -0,0 +1,192 @@
|
||||
#!/bin/bash
|
||||
|
||||
function build_sketch(){ # build_sketch <ide_path> <user_path> <fqbn> <path-to-ino> [extra-options]
|
||||
if [ "$#" -lt 4 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: ${0} build <ide_path> <user_path> <fqbn> <path-to-ino> [extra-options]"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local ide_path=$1
|
||||
local usr_path=$2
|
||||
local fqbn=$3
|
||||
local sketch=$4
|
||||
local xtra_opts=$5
|
||||
local win_opts=$6
|
||||
|
||||
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
|
||||
if [ -z "$ARDUINO_BUILD_DIR" ]; then
|
||||
build_dir="$(dirname $sketch)/build"
|
||||
else
|
||||
build_dir="$ARDUINO_BUILD_DIR"
|
||||
fi
|
||||
|
||||
echo $sketch
|
||||
|
||||
rm -rf "$build_dir"
|
||||
mkdir -p "$build_dir"
|
||||
mkdir -p "$ARDUINO_CACHE_DIR"
|
||||
$ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \
|
||||
-fqbn=$fqbn \
|
||||
-warnings="all" \
|
||||
-tools "$ide_path/tools-builder" \
|
||||
-tools "$ide_path/tools" \
|
||||
-built-in-libraries "$ide_path/libraries" \
|
||||
-hardware "$ide_path/hardware" \
|
||||
-hardware "$usr_path/hardware" \
|
||||
-libraries "$usr_path/libraries" \
|
||||
-build-cache "$ARDUINO_CACHE_DIR" \
|
||||
-build-path "$build_dir" \
|
||||
$win_opts $xtra_opts "$sketch"
|
||||
}
|
||||
|
||||
function count_sketches(){ # count_sketches <path> [target]
|
||||
local path=$1
|
||||
local target=$2
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: ${0} count <path> [target]"
|
||||
fi
|
||||
|
||||
rm -rf sketches.txt
|
||||
if [ ! -d "$path" ]; then
|
||||
touch sketches.txt
|
||||
return 0
|
||||
fi
|
||||
|
||||
local sketches=$(find $path -name *.ino | sort)
|
||||
local sketchnum=0
|
||||
for sketch in $sketches; do
|
||||
local sketchdir=$(dirname $sketch)
|
||||
local sketchdirname=$(basename $sketchdir)
|
||||
local sketchname=$(basename $sketch)
|
||||
if [[ "$sketchdirname.ino" != "$sketchname" ]]; then
|
||||
continue
|
||||
elif [[ -n $target ]] && [[ -f "$sketchdir/.skip.$target" ]]; then
|
||||
continue
|
||||
else
|
||||
echo $sketch >> sketches.txt
|
||||
sketchnum=$(($sketchnum + 1))
|
||||
fi
|
||||
done
|
||||
return $sketchnum
|
||||
}
|
||||
|
||||
function build_sketches(){ # build_sketches <ide_path> <user_path> <fqbn> <target> <path> <chunk> <total-chunks> [extra-options]
|
||||
local ide_path=$1
|
||||
local usr_path=$2
|
||||
local fqbn=$3
|
||||
local target=$4
|
||||
local path=$5
|
||||
local chunk_idex=$6
|
||||
local chunks_num=$7
|
||||
local xtra_opts=$8
|
||||
|
||||
if [ "$#" -lt 7 ]; then
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE: ${0} chunk_build <ide_path> <user_path> <fqbn> <target> <path> [<chunk> <total-chunks>] [extra-options]"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$chunks_num" -le 0 ]; then
|
||||
echo "ERROR: Chunks count must be positive number"
|
||||
return 1
|
||||
fi
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
|
||||
echo "ERROR: Chunk index must be less than chunks count"
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
count_sketches "$path" "$target"
|
||||
local sketchcount=$?
|
||||
set -e
|
||||
local sketches=$(cat sketches.txt)
|
||||
rm -rf sketches.txt
|
||||
|
||||
local chunk_size=$(( $sketchcount / $chunks_num ))
|
||||
local all_chunks=$(( $chunks_num * $chunk_size ))
|
||||
if [ "$all_chunks" -lt "$sketchcount" ]; then
|
||||
chunk_size=$(( $chunk_size + 1 ))
|
||||
fi
|
||||
|
||||
local start_index=0
|
||||
local end_index=0
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ]; then
|
||||
start_index=$chunk_idex
|
||||
end_index=$sketchcount
|
||||
else
|
||||
start_index=$(( $chunk_idex * $chunk_size ))
|
||||
if [ "$sketchcount" -le "$start_index" ]; then
|
||||
echo "Skipping job"
|
||||
return 0
|
||||
fi
|
||||
|
||||
end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
|
||||
if [ "$end_index" -gt "$sketchcount" ]; then
|
||||
end_index=$sketchcount
|
||||
fi
|
||||
fi
|
||||
|
||||
local start_num=$(( $start_index + 1 ))
|
||||
echo "Found $sketchcount Sketches for target '$target'";
|
||||
echo "Chunk Index : $chunk_idex"
|
||||
echo "Chunk Count : $chunks_num"
|
||||
echo "Chunk Size : $chunk_size"
|
||||
echo "Start Sketch: $start_num"
|
||||
echo "End Sketch : $end_index"
|
||||
|
||||
local sketchnum=0
|
||||
for sketch in $sketches; do
|
||||
local sketchdir=$(dirname $sketch)
|
||||
local sketchdirname=$(basename $sketchdir)
|
||||
local sketchname=$(basename $sketch)
|
||||
sketchnum=$(($sketchnum + 1))
|
||||
if [ "$sketchnum" -le "$start_index" ] \
|
||||
|| [ "$sketchnum" -gt "$end_index" ]; then
|
||||
continue
|
||||
fi
|
||||
echo ""
|
||||
echo "Building Sketch Index $(($sketchnum - 1)) - $sketchdirname"
|
||||
build_sketch "$ide_path" "$usr_path" "$fqbn" "$sketch" "$xtra_opts"
|
||||
local result=$?
|
||||
if [ $result -ne 0 ]; then
|
||||
return $result
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
USAGE="
|
||||
USAGE: ${0} [command] [options]
|
||||
Available commands:
|
||||
count: Count sketches.
|
||||
build: Build a sketch.
|
||||
chunk_build: Build a chunk of sketches.
|
||||
"
|
||||
|
||||
cmd=$1
|
||||
shift
|
||||
if [ -z $cmd ]; then
|
||||
echo "ERROR: No command supplied"
|
||||
echo "$USAGE"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "$cmd" in
|
||||
"count")
|
||||
count_sketches $*
|
||||
;;
|
||||
"build")
|
||||
build_sketch $*
|
||||
;;
|
||||
"chunk_build")
|
||||
build_sketches $*
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unrecognized command"
|
||||
echo "$USAGE"
|
||||
exit 2
|
||||
esac
|
||||
|
58
.github/scripts/tests_build.sh
vendored
Executable file
58
.github/scripts/tests_build.sh
vendored
Executable file
@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPTS_DIR="./.github/scripts"
|
||||
BUILD_CMD=""
|
||||
|
||||
if [ $# -eq 3 ]; then
|
||||
chunk_build=1
|
||||
elif [ $# -eq 2 ]; then
|
||||
chunk_build=0
|
||||
else
|
||||
echo "ERROR: Illegal number of parameters"
|
||||
echo "USAGE:
|
||||
${0} <target> <sketch_dir>
|
||||
${0} <target> <chunk> <total_chunks>
|
||||
"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
target=$1
|
||||
|
||||
case "$target" in
|
||||
"esp32") fqbn="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
|
||||
;;
|
||||
"esp32s2") fqbn="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
|
||||
;;
|
||||
"esp32c3") fqbn="espressif:esp32:esp32c3:PartitionScheme=huge_app"
|
||||
;;
|
||||
"esp32s3") fqbn="espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z $fqbn ]; then
|
||||
echo "Unvalid chip $1"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
source ${SCRIPTS_DIR}/install-arduino-ide.sh
|
||||
source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
|
||||
|
||||
args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH \"$fqbn\""
|
||||
|
||||
if [ $chunk_build -eq 1 ]; then
|
||||
chunk_index=$2
|
||||
chunk_max=$3
|
||||
|
||||
if [ "$chunk_index" -gt "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then
|
||||
chunk_index=$chunk_max
|
||||
fi
|
||||
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
|
||||
args+=" $target $PWD/tests $chunk_index $chunk_max"
|
||||
else
|
||||
sketchdir=$2
|
||||
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh build"
|
||||
args+=" $PWD/tests/$sketchdir/$sketchdir.ino"
|
||||
fi
|
||||
|
||||
${BUILD_CMD} ${args}
|
||||
|
71
.github/scripts/tests_run.sh
vendored
Executable file
71
.github/scripts/tests_run.sh
vendored
Executable file
@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
|
||||
target=$1
|
||||
chunk_idex=$2
|
||||
chunks_num=$3
|
||||
|
||||
SCRIPTS_DIR="./.github/scripts"
|
||||
COUNT_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh count"
|
||||
|
||||
source ${SCRIPTS_DIR}/install-arduino-ide.sh
|
||||
|
||||
if [ "$chunks_num" -le 0 ]; then
|
||||
echo "ERROR: Chunks count must be positive number"
|
||||
return 1
|
||||
fi
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
|
||||
echo "ERROR: Chunk index must be less than chunks count"
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
${COUNT_SKETCHES} $PWD/tests $target
|
||||
sketchcount=$?
|
||||
set -e
|
||||
sketches=$(cat sketches.txt)
|
||||
rm -rf sketches.txt
|
||||
|
||||
chunk_size=$(( $sketchcount / $chunks_num ))
|
||||
all_chunks=$(( $chunks_num * $chunk_size ))
|
||||
if [ "$all_chunks" -lt "$sketchcount" ]; then
|
||||
chunk_size=$(( $chunk_size + 1 ))
|
||||
fi
|
||||
|
||||
start_index=0
|
||||
end_index=0
|
||||
if [ "$chunk_idex" -ge "$chunks_num" ]; then
|
||||
start_index=$chunk_idex
|
||||
end_index=$sketchcount
|
||||
else
|
||||
start_index=$(( $chunk_idex * $chunk_size ))
|
||||
if [ "$sketchcount" -le "$start_index" ]; then
|
||||
echo "Skipping job"
|
||||
return 0
|
||||
fi
|
||||
|
||||
end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
|
||||
if [ "$end_index" -gt "$sketchcount" ]; then
|
||||
end_index=$sketchcount
|
||||
fi
|
||||
fi
|
||||
|
||||
start_num=$(( $start_index + 1 ))
|
||||
sketchnum=0
|
||||
|
||||
for sketch in $sketches; do
|
||||
sketchdir=$(dirname $sketch)
|
||||
sketchdirname=$(basename $sketchdir)
|
||||
sketchname=$(basename $sketch)
|
||||
sketchnum=$(($sketchnum + 1))
|
||||
if [ "$sketchnum" -le "$start_index" ] \
|
||||
|| [ "$sketchnum" -gt "$end_index" ]; then
|
||||
continue
|
||||
fi
|
||||
echo ""
|
||||
echo "Test for Sketch Index $(($sketchnum - 1)) - $sketchdirname"
|
||||
pytest tests -k test_$sketchdirname --junit-xml=tests/$sketchdirname/$sketchdirname.xml
|
||||
result=$?
|
||||
if [ $result -ne 0 ]; then
|
||||
return $result
|
||||
fi
|
||||
done
|
39
.github/scripts/update-version.sh
vendored
Executable file
39
.github/scripts/update-version.sh
vendored
Executable file
@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
# For reference: add tools for all boards by replacing one line in each board
|
||||
# "[board].upload.tool=esptool_py" to "[board].upload.tool=esptool_py\n[board].upload.tool.default=esptool_py\n[board].upload.tool.network=esp_ota"
|
||||
#cat boards.txt | sed "s/\([a-zA-Z0-9_\-]*\)\.upload\.tool\=esptool_py/\1\.upload\.tool\=esptool_py\\n\1\.upload\.tool\.default\=esptool_py\\n\1\.upload\.tool\.network\=esp_ota/"
|
||||
|
||||
if [ ! $# -eq 3 ]; then
|
||||
echo "Bad number of arguments: $#" >&2
|
||||
echo "usage: $0 <major> <minor> <patch>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
re='^[0-9]+$'
|
||||
if [[ ! $1 =~ $re ]] || [[ ! $2 =~ $re ]] || [[ ! $3 =~ $re ]] ; then
|
||||
echo "error: Not a valid version: $1.$2.$3" >&2
|
||||
echo "usage: $0 <major> <minor> <patch>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ESP_ARDUINO_VERSION_MAJOR="$1"
|
||||
ESP_ARDUINO_VERSION_MINOR="$2"
|
||||
ESP_ARDUINO_VERSION_PATCH="$3"
|
||||
ESP_ARDUINO_VERSION="$ESP_ARDUINO_VERSION_MAJOR.$ESP_ARDUINO_VERSION_MINOR.$ESP_ARDUINO_VERSION_PATCH"
|
||||
|
||||
echo "New Arduino Version: $ESP_ARDUINO_VERSION"
|
||||
|
||||
echo "Updating platform.txt..."
|
||||
cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > __platform.txt && mv __platform.txt platform.txt
|
||||
|
||||
echo "Updating package.json..."
|
||||
cat package.json | sed "s/.*\"version\":.*/ \"version\": \"$ESP_ARDUINO_VERSION\",/g" > __package.json && mv __package.json package.json
|
||||
|
||||
echo "Updating cores/esp32/esp_arduino_version.h..."
|
||||
cat cores/esp32/esp_arduino_version.h | \
|
||||
sed "s/#define ESP_ARDUINO_VERSION_MAJOR.*/#define ESP_ARDUINO_VERSION_MAJOR $ESP_ARDUINO_VERSION_MAJOR/g" | \
|
||||
sed "s/#define ESP_ARDUINO_VERSION_MINOR.*/#define ESP_ARDUINO_VERSION_MINOR $ESP_ARDUINO_VERSION_MINOR/g" | \
|
||||
sed "s/#define ESP_ARDUINO_VERSION_PATCH.*/#define ESP_ARDUINO_VERSION_PATCH $ESP_ARDUINO_VERSION_PATCH/g" > __esp_arduino_version.h && mv __esp_arduino_version.h cores/esp32/esp_arduino_version.h
|
||||
|
||||
exit 0
|
26
.github/stale.yml
vendored
26
.github/stale.yml
vendored
@ -1,26 +0,0 @@
|
||||
# This workflow firstly warns and then closes issues that have had no activity for a specified amount of time.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information can be found here: https://github.com/actions/stale
|
||||
|
||||
name: Mark stale issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 9 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.'
|
||||
days-before-stale: 60
|
||||
days-before-close: 14
|
||||
exempt-issue-labels: 'Type: For reference,Type: To be implemented,Type: Feature request'
|
||||
stale-issue-label: 'Status: Stale'
|
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 }}
|
||||
|
123
.github/workflows/hil.yml
vendored
Normal file
123
.github/workflows/hil.yml
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
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' && github.repository == 'espressif/arduino-esp32')
|
||||
name: Generate Chunks matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
chunks: ${{ steps.gen-chunks.outputs.chunks }}
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Generate Chunks matrix
|
||||
id: gen-chunks
|
||||
run: |
|
||||
set +e
|
||||
bash .github/scripts/sketch_utils.sh count tests
|
||||
sketches=$((? - 1))
|
||||
if [[ $sketches -gt ${{env.MAX_CHUNKS}} ]]; then
|
||||
$sketches=${{env.MAX_CHUNKS}}
|
||||
fi
|
||||
set -e
|
||||
rm sketches.txt
|
||||
CHUNKS=$(jq -c -n '$ARGS.positional' --args `seq 0 1 $sketches`)
|
||||
echo "::set-output name=chunks::${CHUNKS}"
|
||||
|
||||
Build:
|
||||
needs: gen_chunks
|
||||
name: ${{matrix.chip}}-Build#${{matrix.chunks}}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
|
||||
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build sketches
|
||||
run: |
|
||||
bash .github/scripts/tests_build.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
|
||||
- name: Upload ${{matrix.chip}}-${{matrix.chunks}} artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
|
||||
path: |
|
||||
tests/*/build/*.bin
|
||||
tests/*/build/*.json
|
||||
Test:
|
||||
needs: [gen_chunks, Build]
|
||||
name: ${{matrix.chip}}-Test#${{matrix.chunks}}
|
||||
runs-on:
|
||||
- ESP32
|
||||
- ESP32-S2
|
||||
- ESP32-S3
|
||||
- ESP32-C3
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
|
||||
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
|
||||
container:
|
||||
image: python:3.10.1-bullseye
|
||||
options: --privileged
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Download ${{matrix.chip}}-${{matrix.chunks}} artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
|
||||
path: tests/
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install -U pip
|
||||
pip install -r tests/requirements.txt
|
||||
|
||||
- name: Run Tests
|
||||
run: |
|
||||
bash .github/scripts/tests_run.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
|
||||
|
||||
- name: Upload test result artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: test_results-${{matrix.chip}}-${{matrix.chunks}}
|
||||
path: tests/*/*.xml
|
||||
|
||||
event_file:
|
||||
name: "Event File"
|
||||
if: |
|
||||
contains(github.event.pull_request.labels.*.name, 'hil_test') ||
|
||||
github.event_name == 'schedule'
|
||||
needs: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Event File
|
||||
path: ${{github.event_path}}
|
38
.github/workflows/publish.yml
vendored
Normal file
38
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: Unit Test Results
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Run tests in hardware]
|
||||
branches-ignore: [master]
|
||||
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
unit-test-results:
|
||||
name: Unit Test Results
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.event.workflow_run.event == 'pull_request' &&
|
||||
(github.event.workflow_run.conclusion == 'success' ||
|
||||
github.event.workflow_run.conclusion == 'failure')
|
||||
steps:
|
||||
- name: Download and Extract Artifacts
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
run: |
|
||||
mkdir -p artifacts && cd artifacts
|
||||
artifacts_url=${{ github.event.workflow_run.artifacts_url }}
|
||||
gh api "$artifacts_url" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact
|
||||
do
|
||||
IFS=$'\t' read name url <<< "$artifact"
|
||||
gh api $url > "$name.zip"
|
||||
unzip -d "$name" "$name.zip"
|
||||
done
|
||||
- name: Publish Unit Test Results
|
||||
uses: EnricoMi/publish-unit-test-result-action@v1
|
||||
with:
|
||||
commit: ${{ github.event.workflow_run.head_sha }}
|
||||
event_file: artifacts/Event File/event.json
|
||||
event_name: ${{ github.event.workflow_run.event }}
|
||||
files: "artifacts/**/*.xml"
|
69
.github/workflows/push.yml
vendored
69
.github/workflows/push.yml
vendored
@ -1,14 +1,26 @@
|
||||
name: ESP32 Arduino CI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release/*
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: build-${{github.event.pull_request.number || github.ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
|
||||
cmake-check:
|
||||
name: Check cmake file
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: bash ./.github/scripts/check-cmakelists.sh
|
||||
|
||||
# Ubuntu
|
||||
build-arduino-linux:
|
||||
name: Arduino ${{ matrix.chunk }} on ubuntu-latest
|
||||
@ -16,12 +28,22 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@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
|
||||
|
||||
@ -32,10 +54,10 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
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
|
||||
@ -48,11 +70,38 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
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
|
||||
run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO
|
||||
|
||||
build-esp-idf-component:
|
||||
name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
# The version names here correspond to the versions of espressif/idf Docker image.
|
||||
# See https://hub.docker.com/r/espressif/idf/tags and
|
||||
# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html
|
||||
# for details.
|
||||
idf_ver: ["release-v4.4"]
|
||||
idf_target: ["esp32", "esp32s2", "esp32s3", "esp32c3"]
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
steps:
|
||||
- name: Check out arduino-esp32 as a component
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
path: components/arduino-esp32
|
||||
- name: Build
|
||||
env:
|
||||
IDF_TARGET: ${{ matrix.idf_target }}
|
||||
shell: bash
|
||||
run: |
|
||||
. ${IDF_PATH}/export.sh
|
||||
idf.py create-project test
|
||||
idf.py -C test -DEXTRA_COMPONENT_DIRS=$PWD/components build
|
||||
|
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:
|
||||
- '*'
|
||||
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
|
||||
@ -93,6 +95,8 @@ set(LIBRARY_SRCS
|
||||
libraries/RainMaker/src/RMakerParam.cpp
|
||||
libraries/RainMaker/src/RMakerDevice.cpp
|
||||
libraries/RainMaker/src/RMakerType.cpp
|
||||
libraries/RainMaker/src/RMakerQR.cpp
|
||||
libraries/RainMaker/src/RMakerUtils.cpp
|
||||
libraries/SD_MMC/src/SD_MMC.cpp
|
||||
libraries/SD/src/SD.cpp
|
||||
libraries/SD/src/sd_diskio.cpp
|
||||
@ -115,6 +119,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 +166,6 @@ set(BLE_SRCS
|
||||
libraries/BLE/src/GeneralUtils.cpp
|
||||
)
|
||||
|
||||
|
||||
set(includedirs
|
||||
variants/${IDF_TARGET}/
|
||||
cores/esp32/
|
||||
@ -173,11 +177,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 +204,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 +239,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()
|
||||
|
@ -21,7 +21,8 @@ config AUTOSTART_ARDUINO
|
||||
|
||||
choice ARDUINO_RUNNING_CORE
|
||||
bool "Core on which Arduino's setup() and loop() are running"
|
||||
default ARDUINO_RUN_CORE1
|
||||
default ARDUINO_RUN_CORE0 if FREERTOS_UNICORE
|
||||
default ARDUINO_RUN_CORE1 if !FREERTOS_UNICORE
|
||||
help
|
||||
Select on which core Arduino's setup() and loop() functions run
|
||||
|
||||
@ -29,8 +30,10 @@ choice ARDUINO_RUNNING_CORE
|
||||
bool "CORE 0"
|
||||
config ARDUINO_RUN_CORE1
|
||||
bool "CORE 1"
|
||||
depends on !FREERTOS_UNICORE
|
||||
config ARDUINO_RUN_NO_AFFINITY
|
||||
bool "BOTH"
|
||||
depends on !FREERTOS_UNICORE
|
||||
|
||||
endchoice
|
||||
|
||||
@ -48,7 +51,8 @@ config ARDUINO_LOOP_STACK_SIZE
|
||||
|
||||
choice ARDUINO_EVENT_RUNNING_CORE
|
||||
bool "Core on which Arduino's event handler is running"
|
||||
default ARDUINO_EVENT_RUN_CORE1
|
||||
default ARDUINO_EVENT_RUN_CORE0 if FREERTOS_UNICORE
|
||||
default ARDUINO_EVENT_RUN_CORE1 if !FREERTOS_UNICORE
|
||||
help
|
||||
Select on which core Arduino's WiFi.onEvent() run
|
||||
|
||||
@ -56,8 +60,10 @@ choice ARDUINO_EVENT_RUNNING_CORE
|
||||
bool "CORE 0"
|
||||
config ARDUINO_EVENT_RUN_CORE1
|
||||
bool "CORE 1"
|
||||
depends on !FREERTOS_UNICORE
|
||||
config ARDUINO_EVENT_RUN_NO_AFFINITY
|
||||
bool "BOTH"
|
||||
depends on !FREERTOS_UNICORE
|
||||
|
||||
endchoice
|
||||
|
||||
@ -67,9 +73,45 @@ config ARDUINO_EVENT_RUNNING_CORE
|
||||
default 1 if ARDUINO_EVENT_RUN_CORE1
|
||||
default -1 if ARDUINO_EVENT_RUN_NO_AFFINITY
|
||||
|
||||
choice ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
|
||||
bool "Core on which Arduino's Serial Event task is running"
|
||||
default ARDUINO_SERIAL_EVENT_RUN_CORE0 if FREERTOS_UNICORE
|
||||
default ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY if !FREERTOS_UNICORE
|
||||
help
|
||||
Select on which core Arduino's Serial Event task run
|
||||
|
||||
config ARDUINO_SERIAL_EVENT_RUN_CORE0
|
||||
bool "CORE 0"
|
||||
config ARDUINO_SERIAL_EVENT_RUN_CORE1
|
||||
bool "CORE 1"
|
||||
depends on !FREERTOS_UNICORE
|
||||
config ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY
|
||||
bool "BOTH"
|
||||
depends on !FREERTOS_UNICORE
|
||||
|
||||
endchoice
|
||||
|
||||
config ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
|
||||
int
|
||||
default 0 if ARDUINO_SERIAL_EVENT_RUN_CORE0
|
||||
default 1 if ARDUINO_SERIAL_EVENT_RUN_CORE1
|
||||
default -1 if ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY
|
||||
|
||||
config ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE
|
||||
int "Serial Event task stack size"
|
||||
default 2048
|
||||
help
|
||||
Amount of stack available for the Serial Event task.
|
||||
|
||||
config ARDUINO_SERIAL_EVENT_TASK_PRIORITY
|
||||
int "Priority of the Serial Event task"
|
||||
default 24
|
||||
help
|
||||
Select at what priority you want the Serial Event task to run.
|
||||
|
||||
choice ARDUINO_UDP_RUNNING_CORE
|
||||
bool "Core on which Arduino's UDP is running"
|
||||
default ARDUINO_UDP_RUN_CORE1
|
||||
default ARDUINO_UDP_RUN_CORE0
|
||||
help
|
||||
Select on which core Arduino's UDP run
|
||||
|
||||
@ -77,23 +119,25 @@ choice ARDUINO_UDP_RUNNING_CORE
|
||||
bool "CORE 0"
|
||||
config ARDUINO_UDP_RUN_CORE1
|
||||
bool "CORE 1"
|
||||
depends on !FREERTOS_UNICORE
|
||||
config ARDUINO_UDP_RUN_NO_AFFINITY
|
||||
bool "BOTH"
|
||||
depends on !FREERTOS_UNICORE
|
||||
|
||||
endchoice
|
||||
|
||||
config ARDUINO_UDP_TASK_PRIORITY
|
||||
int "Priority of the UDP task"
|
||||
default 3
|
||||
help
|
||||
Select at what priority you want the UDP task to run.
|
||||
|
||||
config ARDUINO_UDP_RUNNING_CORE
|
||||
int
|
||||
default 0 if ARDUINO_UDP_RUN_CORE0
|
||||
default 1 if ARDUINO_UDP_RUN_CORE1
|
||||
default -1 if ARDUINO_UDP_RUN_NO_AFFINITY
|
||||
|
||||
config ARDUINO_UDP_TASK_PRIORITY
|
||||
int "Priority of the UDP task"
|
||||
default 3
|
||||
help
|
||||
Select at what priority you want the UDP task to run.
|
||||
|
||||
config ARDUINO_ISR_IRAM
|
||||
bool "Run interrupts in IRAM"
|
||||
default "n"
|
||||
@ -356,3 +400,4 @@ config ARDUINO_SELECTIVE_Wire
|
||||
|
||||
|
||||
endmenu
|
||||
|
||||
|
@ -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
|
29
README.md
29
README.md
@ -1,14 +1,18 @@
|
||||
# Arduino core for the ESP32, ESP32-S2 and ESP32-C3
|
||||
# Arduino core for the ESP32, ESP32-S2, ESP32-S3 and ESP32-C3
|
||||
|
||||
 [](https://docs.espressif.com/projects/arduino-esp32/en/latest/?badge=latest)
|
||||
|
||||
### Need help or have a question? Join the chat at [](https://gitter.im/espressif/arduino-esp32?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
### Need help or have a question? Join the chat at [](https://gitter.im/espressif/arduino-esp32?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) or [open a new Discussion](https://github.com/espressif/arduino-esp32/discussions)
|
||||
|
||||
## Contents
|
||||
|
||||
- [Development Status](#development-status)
|
||||
- [Decoding Exceptions](#decoding-exceptions)
|
||||
- [Issue/Bug report template](#issuebug-report-template)
|
||||
- [Development Status](#development-status)
|
||||
- [Development Planning](#development-planning)
|
||||
- [Documentation](#documentation)
|
||||
- [Supported Chips](#supported-chips)
|
||||
- [Decoding exceptions](#decoding-exceptions)
|
||||
- [Issue/Bug report template](#issuebug-report-template)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
### Development Status
|
||||
|
||||
@ -16,9 +20,15 @@ Latest Stable Release [](https://github.com/espressif/arduino-esp32/releases/) [](https://github.com/espressif/arduino-esp32/releases/) [](https://github.com/espressif/arduino-esp32/releases/)
|
||||
|
||||
### Development Planning
|
||||
|
||||
Our Development is fully tracked on this public **[Roadmap 🎉](https://github.com/orgs/espressif/projects/3)**
|
||||
|
||||
For even more information you can take a look at [Sprint Meeting notes](https://github.com/espressif/arduino-esp32/discussions/categories/sprints-meeting-notes) or join [Monthly Community Meetings 🔔](https://github.com/espressif/arduino-esp32/discussions/categories/monthly-community-meetings)
|
||||
|
||||
### Documentation
|
||||
|
||||
You can use [Arduino-ESP32 Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/) to get all information about this project.
|
||||
You can use the [Arduino-ESP32 Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/) to get all information about this project.
|
||||
|
||||
* [Getting Started](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html)
|
||||
* [Installing (Windows, Linux and macOS)](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html)
|
||||
@ -27,14 +37,19 @@ 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.
|
||||
|
||||
### 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
|
||||
|
||||
|
5437
boards.txt
5437
boards.txt
File diff suppressed because it is too large
Load Diff
36
component.mk
36
component.mk
@ -1,36 +0,0 @@
|
||||
ARDUINO_ALL_LIBRARIES := $(patsubst $(COMPONENT_PATH)/libraries/%,%,$(wildcard $(COMPONENT_PATH)/libraries/*))
|
||||
|
||||
# Macro returns non-empty if Arduino library $(1) should be included in the build
|
||||
# (either because selective compilation is of, or this library is enabled
|
||||
define ARDUINO_LIBRARY_ENABLED
|
||||
$(if $(CONFIG_ARDUINO_SELECTIVE_COMPILATION),$(CONFIG_ARDUINO_SELECTIVE_$(1)),y)
|
||||
endef
|
||||
|
||||
ARDUINO_ENABLED_LIBRARIES := $(foreach LIBRARY,$(sort $(ARDUINO_ALL_LIBRARIES)),$(if $(call ARDUINO_LIBRARY_ENABLED,$(LIBRARY)),$(LIBRARY)))
|
||||
|
||||
$(info Arduino libraries in build: $(ARDUINO_ENABLED_LIBRARIES))
|
||||
|
||||
# Expand all subdirs under $(1)
|
||||
define EXPAND_SUBDIRS
|
||||
$(sort $(dir $(wildcard $(1)/* $(1)/*/* $(1)/*/*/* $(1)/*/*/*/* $(1)/*/*/*/*/*)))
|
||||
endef
|
||||
|
||||
# Macro returns SRCDIRS for library
|
||||
define ARDUINO_LIBRARY_GET_SRCDIRS
|
||||
$(if $(wildcard $(COMPONENT_PATH)/libraries/$(1)/src/.), \
|
||||
$(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)/src), \
|
||||
$(filter-out $(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)/examples), \
|
||||
$(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)) \
|
||||
) \
|
||||
)
|
||||
endef
|
||||
|
||||
# Make a list of all srcdirs in enabled libraries
|
||||
ARDUINO_LIBRARY_SRCDIRS := $(patsubst $(COMPONENT_PATH)/%,%,$(foreach LIBRARY,$(ARDUINO_ENABLED_LIBRARIES),$(call ARDUINO_LIBRARY_GET_SRCDIRS,$(LIBRARY))))
|
||||
|
||||
#$(info Arduino libraries src dirs: $(ARDUINO_LIBRARY_SRCDIRS))
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := cores/esp32 variants/esp32 $(ARDUINO_LIBRARY_SRCDIRS)
|
||||
COMPONENT_PRIV_INCLUDEDIRS := cores/esp32/libb64
|
||||
COMPONENT_SRCDIRS := cores/esp32/libb64 cores/esp32 variants/esp32 $(ARDUINO_LIBRARY_SRCDIRS)
|
||||
CXXFLAGS += -fno-rtti
|
@ -69,7 +69,12 @@
|
||||
#define __STRINGIFY(a) #a
|
||||
#endif
|
||||
|
||||
// can't define max() / min() because of conflicts with C++
|
||||
#define _min(a,b) ((a)<(b)?(a):(b))
|
||||
#define _max(a,b) ((a)>(b)?(a):(b))
|
||||
#define _abs(x) ((x)>0?(x):-(x)) // abs() comes from STL
|
||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||
#define _round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) // round() comes from STL
|
||||
#define radians(deg) ((deg)*DEG_TO_RAD)
|
||||
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
||||
#define sq(x) ((x)*(x))
|
||||
@ -89,6 +94,7 @@
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define bitToggle(value, bit) ((value) ^= (1UL << (bit)))
|
||||
#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))
|
||||
|
||||
// avr-libc defines _NOP() since 1.6.2
|
||||
@ -166,19 +172,27 @@ 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"
|
||||
|
||||
// Use float-compatible stl abs() and round(), we don't use Arduino macros to avoid issues with the C++ libraries
|
||||
using std::abs;
|
||||
using std::isinf;
|
||||
using std::isnan;
|
||||
using std::max;
|
||||
using std::min;
|
||||
using ::round;
|
||||
using std::round;
|
||||
|
||||
uint16_t makeWord(uint16_t w);
|
||||
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,13 +202,14 @@ 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 */
|
||||
|
||||
#define _min(a,b) ((a)<(b)?(a):(b))
|
||||
#define _max(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#endif /* _ESP32_CORE_ARDUINO_H_ */
|
||||
|
@ -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,25 @@
|
||||
#include "pins_arduino.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "driver/uart.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#ifndef ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE
|
||||
#define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINO_SERIAL_EVENT_TASK_PRIORITY
|
||||
#define ARDUINO_SERIAL_EVENT_TASK_PRIORITY (configMAX_PRIORITIES-1)
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
|
||||
#define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -1
|
||||
#endif
|
||||
|
||||
#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 +34,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 +53,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 +65,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 +78,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 +98,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 +112,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 +124,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
|
||||
xTaskCreateUniversal(_uartEventTask, "uart_event_task", ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE, this, ARDUINO_SERIAL_EVENT_TASK_PRIORITY, &_eventTask, ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE);
|
||||
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 +292,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 +353,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 +378,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 +488,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 +508,26 @@ size_t HardwareSerial::setRxBufferSize(size_t new_size) {
|
||||
}
|
||||
|
||||
if (new_size <= SOC_UART_FIFO_LEN) {
|
||||
log_e("RX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN);
|
||||
log_e("RX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN); // ESP32, S2, S3 and C3 means higher than 128
|
||||
return 0;
|
||||
}
|
||||
|
||||
_rxBufferSize = new_size;
|
||||
return _rxBufferSize;
|
||||
}
|
||||
|
||||
size_t HardwareSerial::setTxBufferSize(size_t new_size) {
|
||||
|
||||
if (_uart) {
|
||||
log_e("TX Buffer can't be resized when Serial is already running.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (new_size <= SOC_UART_FIFO_LEN) {
|
||||
log_e("TX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN); // ESP32, S2, S3 and C3 means higher than 128
|
||||
return 0;
|
||||
}
|
||||
|
||||
_txBufferSize = new_size;
|
||||
return _txBufferSize;
|
||||
}
|
||||
|
@ -46,19 +46,61 @@
|
||||
#define HardwareSerial_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <functional>
|
||||
#include "Stream.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "HWCDC.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
typedef enum {
|
||||
UART_BREAK_ERROR,
|
||||
UART_BUFFER_FULL_ERROR,
|
||||
UART_FIFO_OVF_ERROR,
|
||||
UART_FRAME_ERROR,
|
||||
UART_PARITY_ERROR
|
||||
} hardwareSerial_error_t;
|
||||
|
||||
typedef std::function<void(void)> OnReceiveCb;
|
||||
typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb;
|
||||
|
||||
class HardwareSerial: public Stream
|
||||
{
|
||||
public:
|
||||
HardwareSerial(int uart_nr);
|
||||
~HardwareSerial();
|
||||
|
||||
// setRxTimeout sets the timeout after which onReceive callback will be called (after receiving data, it waits for this time of UART rx inactivity to call the callback fnc)
|
||||
// param symbols_timeout defines a timeout threshold in uart symbol periods. Setting 0 symbol timeout disables the callback call by timeout.
|
||||
// Maximum timeout setting is calculacted automatically by IDF. If set above the maximum, it is ignored and an error is printed on Serial0 (check console).
|
||||
// Examples: Maximum for 11 bits symbol is 92 (SERIAL_8N2, SERIAL_8E1, SERIAL_8O1, etc), Maximum for 10 bits symbol is 101 (SERIAL_8N1).
|
||||
// For example symbols_timeout=1 defines a timeout equal to transmission time of one symbol (~11 bit) on current baudrate.
|
||||
// For a baudrate of 9600, SERIAL_8N1 (10 bit symbol) and symbols_timeout = 3, the timeout would be 3 / (9600 / 10) = 3.125 ms
|
||||
void setRxTimeout(uint8_t symbols_timeout);
|
||||
|
||||
// onReceive will setup a callback that will be called whenever an UART interruption occurs (UART_INTR_RXFIFO_FULL or UART_INTR_RXFIFO_TOUT)
|
||||
// UART_INTR_RXFIFO_FULL interrupt triggers at UART_FULL_THRESH_DEFAULT bytes received (defined as 120 bytes by default in IDF)
|
||||
// UART_INTR_RXFIFO_TOUT interrupt triggers at UART_TOUT_THRESH_DEFAULT symbols passed without any reception (defined as 10 symbos by default in IDF)
|
||||
// onlyOnTimeout parameter will define how onReceive will behave:
|
||||
// Default: true -- The callback will only be called when RX Timeout happens.
|
||||
// Whole stream of bytes will be ready for being read on the callback function at once.
|
||||
// This option may lead to Rx Overflow depending on the Rx Buffer Size and number of bytes received in the streaming
|
||||
// false -- The callback will be called when FIFO reaches 120 bytes and also on RX Timeout.
|
||||
// The stream of incommig bytes will be "split" into blocks of 120 bytes on each callback.
|
||||
// This option avoid any sort of Rx Overflow, but leaves the UART packet reassembling work to the Application.
|
||||
void onReceive(OnReceiveCb function, bool onlyOnTimeout = true);
|
||||
|
||||
// onReceive will be called on error events (see hardwareSerial_error_t)
|
||||
void onReceiveError(OnReceiveErrorCb function);
|
||||
|
||||
// eventQueueReset clears all events in the queue (the events that trigger onReceive and onReceiveError) - maybe usefull in some use cases
|
||||
void eventQueueReset();
|
||||
|
||||
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);
|
||||
void end(bool turnOffDebug = true);
|
||||
void end(bool fullyTerminate = true);
|
||||
void updateBaudRate(unsigned long baud);
|
||||
int available(void);
|
||||
int availableForWrite(void);
|
||||
@ -103,13 +145,34 @@ public:
|
||||
void setDebugOutput(bool);
|
||||
|
||||
void setRxInvert(bool);
|
||||
void setPins(uint8_t rxPin, uint8_t txPin);
|
||||
|
||||
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
|
||||
// SetPins shall be called after Serial begin()
|
||||
void setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin = -1, int8_t rtsPin = -1);
|
||||
// Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
|
||||
void setHwFlowCtrlMode(uint8_t mode = HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64); // 64 is half FIFO Length
|
||||
|
||||
size_t setRxBufferSize(size_t new_size);
|
||||
size_t setTxBufferSize(size_t new_size);
|
||||
|
||||
protected:
|
||||
int _uart_nr;
|
||||
uart_t* _uart;
|
||||
size_t _rxBufferSize;
|
||||
size_t _txBufferSize;
|
||||
OnReceiveCb _onReceiveCB;
|
||||
OnReceiveErrorCb _onReceiveErrorCB;
|
||||
// _onReceive and _rxTimeout have be consistent when timeout is disabled
|
||||
bool _onReceiveTimeout;
|
||||
uint8_t _rxTimeout;
|
||||
TaskHandle_t _eventTask;
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
SemaphoreHandle_t _lock;
|
||||
#endif
|
||||
|
||||
void _createEventTask(void *args);
|
||||
void _destroyEventTask(void);
|
||||
static void _uartEventTask(void *args);
|
||||
};
|
||||
|
||||
extern void serialEventRun(void) __attribute__((weak));
|
||||
@ -119,10 +182,10 @@ extern void serialEventRun(void) __attribute__((weak));
|
||||
#define ARDUINO_USB_CDC_ON_BOOT 0
|
||||
#endif
|
||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||
#if !ARDUINO_USB_MODE
|
||||
#include "USB.h"
|
||||
#include "USBCDC.h"
|
||||
extern HardwareSerial Serial0;
|
||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
||||
#endif
|
||||
extern HardwareSerial Serial0;
|
||||
#else
|
||||
extern HardwareSerial Serial;
|
||||
|
@ -120,3 +120,6 @@ bool IPAddress::fromString(const char *address)
|
||||
_address.bytes[3] = acc;
|
||||
return true;
|
||||
}
|
||||
|
||||
// declared one time - as external in IPAddress.h
|
||||
IPAddress INADDR_NONE(0, 0, 0, 0);
|
||||
|
@ -91,6 +91,6 @@ public:
|
||||
friend class DNSClient;
|
||||
};
|
||||
|
||||
const IPAddress INADDR_NONE(0, 0, 0, 0);
|
||||
|
||||
// changed to extern because const declaration creates copies in BSS of INADDR_NONE for each CPP unit that includes it
|
||||
extern IPAddress INADDR_NONE;
|
||||
#endif
|
||||
|
@ -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)
|
||||
{
|
||||
|
138
cores/esp32/Tone.cpp
Normal file
138
cores/esp32/Tone.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
#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=%lu 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,
|
||||
.pin = 0, // Ignored
|
||||
.frequency = 0, // Ignored
|
||||
.duration = 0, // Ignored
|
||||
.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,
|
||||
.frequency = 0, // Ignored
|
||||
.duration = 0, // Ignored
|
||||
.channel = 0 // Ignored
|
||||
};
|
||||
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=%lu ms", _pin, frequency, duration);
|
||||
if(tone_init()){
|
||||
tone_msg_t tone_msg = {
|
||||
.tone_cmd = TONE_START,
|
||||
.pin = _pin,
|
||||
.frequency = frequency,
|
||||
.duration = duration,
|
||||
.channel = 0 // Ignored
|
||||
};
|
||||
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,46 @@ 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(long long value, unsigned char base) {
|
||||
init();
|
||||
char buf[2 + 8 * sizeof(long long)];
|
||||
if (base==10) {
|
||||
sprintf(buf, "%lld", value); // NOT SURE - NewLib Nano ... does it support %lld?
|
||||
} else {
|
||||
lltoa(value, buf, base);
|
||||
}
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned long long value, unsigned char base) {
|
||||
init();
|
||||
char buf[1 + 8 * sizeof(unsigned long long)];
|
||||
ulltoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::~String() {
|
||||
@ -395,6 +426,17 @@ unsigned char String::concat(double num) {
|
||||
return concat(string, strlen(string));
|
||||
}
|
||||
|
||||
unsigned char String::concat(long long num) {
|
||||
char buf[2 + 3 * sizeof(long long)];
|
||||
return concat(buf, sprintf(buf, "%lld", num)); // NOT SURE - NewLib Nano ... does it support %lld?
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned long long num) {
|
||||
char buf[1 + 3 * sizeof(unsigned long long)];
|
||||
ulltoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(const __FlashStringHelper * str) {
|
||||
if (!str) return 0;
|
||||
int length = strlen_P((PGM_P)str);
|
||||
@ -480,6 +522,20 @@ StringSumHelper & operator +(const StringSumHelper &lhs, double num) {
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, long long num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long long num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
@ -761,8 +817,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,10 @@ 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);
|
||||
explicit String(long long, unsigned char base = 10);
|
||||
explicit String(unsigned long long, unsigned char base = 10);
|
||||
~String(void);
|
||||
|
||||
// memory management
|
||||
@ -122,6 +124,8 @@ class String {
|
||||
unsigned char concat(unsigned long num);
|
||||
unsigned char concat(float num);
|
||||
unsigned char concat(double num);
|
||||
unsigned char concat(long long num);
|
||||
unsigned char concat(unsigned long long num);
|
||||
unsigned char concat(const __FlashStringHelper * str);
|
||||
|
||||
// if there's not enough memory for the concatenated value, the string
|
||||
@ -166,6 +170,14 @@ class String {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(long long num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(unsigned long long num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator += (const __FlashStringHelper *str){
|
||||
concat(str);
|
||||
return (*this);
|
||||
@ -182,6 +194,8 @@ class String {
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, float num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, double num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, long long num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long long num);
|
||||
|
||||
// comparison (only works w/ Strings and "strings")
|
||||
operator StringIfHelperType() const {
|
||||
@ -373,6 +387,12 @@ class StringSumHelper: public String {
|
||||
StringSumHelper(double num) :
|
||||
String(num) {
|
||||
}
|
||||
StringSumHelper(long long num) :
|
||||
String(num) {
|
||||
}
|
||||
StringSumHelper(unsigned long long num) :
|
||||
String(num) {
|
||||
}
|
||||
};
|
||||
|
||||
extern const String emptyString;
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
|
||||
cbuf *next;
|
||||
|
||||
private:
|
||||
protected:
|
||||
inline char* wrap_if_bufend(char* ptr) const
|
||||
{
|
||||
return (ptr == _bufend) ? _buf : ptr;
|
||||
|
@ -13,37 +13,16 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-adc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_attr.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "driver/adc.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp_adc_cal.h"
|
||||
|
||||
#if SOC_DAC_SUPPORTED //ESP32, ESP32S2
|
||||
#include "soc/dac_channel.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_VREF 1100
|
||||
static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL};
|
||||
static uint16_t __analogVRef = 0;
|
||||
static uint8_t __analogVRefPin = 0;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/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
|
||||
#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
|
||||
|
||||
static uint8_t __analogAttenuation = 3;//11db
|
||||
static uint8_t __analogWidth = ADC_WIDTH_MAX - 1; //3 for ESP32/ESP32C3; 4 for ESP32S2
|
||||
@ -51,6 +30,11 @@ static uint8_t __analogReturnedWidth = SOC_ADC_MAX_BITWIDTH; //12 for ESP32/ESP3
|
||||
static uint8_t __analogClockDiv = 1;
|
||||
static adc_attenuation_t __pin_attenuation[SOC_GPIO_PIN_COUNT];
|
||||
|
||||
static uint16_t __analogVRef = 0;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static uint8_t __analogVRefPin = 0;
|
||||
#endif
|
||||
|
||||
static inline uint16_t mapResolution(uint16_t value)
|
||||
{
|
||||
uint8_t from = __analogWidth + 9;
|
||||
@ -111,8 +95,8 @@ void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)
|
||||
if(channel < 0 || attenuation > 3){
|
||||
return ;
|
||||
}
|
||||
if(channel > 9){
|
||||
adc2_config_channel_atten(channel - 10, attenuation);
|
||||
if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){
|
||||
adc2_config_channel_atten(channel - SOC_ADC_MAX_CHANNEL_NUM, attenuation);
|
||||
} else {
|
||||
adc1_config_channel_atten(channel, attenuation);
|
||||
}
|
||||
@ -141,10 +125,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
|
||||
@ -175,8 +159,8 @@ uint16_t __analogRead(uint8_t pin)
|
||||
return value;
|
||||
}
|
||||
__adcAttachPin(pin);
|
||||
if(channel > 9){
|
||||
channel -= 10;
|
||||
if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){
|
||||
channel -= SOC_ADC_MAX_CHANNEL_NUM;
|
||||
r = adc2_get_raw( channel, __analogWidth, &value);
|
||||
if ( r == ESP_OK ) {
|
||||
return mapResolution(value);
|
||||
@ -200,7 +184,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin){
|
||||
log_e("Pin %u is not ADC pin!", pin);
|
||||
return 0;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
if(!__analogVRef){
|
||||
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
|
||||
log_d("eFuse Two Point: Supported");
|
||||
@ -212,6 +196,8 @@ uint32_t __analogReadMilliVolts(uint8_t pin){
|
||||
}
|
||||
if(!__analogVRef){
|
||||
__analogVRef = DEFAULT_VREF;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(__analogVRefPin){
|
||||
esp_adc_cal_characteristics_t chars;
|
||||
if(adc_vref_to_gpio(ADC_UNIT_2, __analogVRefPin) == ESP_OK){
|
||||
@ -221,42 +207,44 @@ uint32_t __analogReadMilliVolts(uint8_t pin){
|
||||
log_d("Vref to GPIO%u: %u", __analogVRefPin, __analogVRef);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
uint8_t unit = 1;
|
||||
if(channel > 9){
|
||||
if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){
|
||||
unit = 2;
|
||||
}
|
||||
|
||||
uint16_t adc_reading = __analogRead(pin);
|
||||
if(__analogCharacteristics[unit - 1] == NULL){
|
||||
__analogCharacteristics[unit - 1] = calloc(1, sizeof(esp_adc_cal_characteristics_t));
|
||||
if(__analogCharacteristics[unit - 1] == NULL){
|
||||
return 0;
|
||||
}
|
||||
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, __analogAttenuation, __analogWidth, __analogVRef, __analogCharacteristics[unit - 1]);
|
||||
|
||||
uint8_t atten = __analogAttenuation;
|
||||
if (__pin_attenuation[pin] != ADC_ATTENDB_MAX){
|
||||
atten = __pin_attenuation[pin];
|
||||
}
|
||||
|
||||
esp_adc_cal_characteristics_t chars = {};
|
||||
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, __analogWidth, __analogVRef, &chars);
|
||||
|
||||
static bool print_chars_info = true;
|
||||
if(print_chars_info)
|
||||
{
|
||||
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
|
||||
log_i("ADC%u: Characterized using Two Point Value: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
|
||||
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
|
||||
log_i("ADC%u: Characterized using eFuse Vref: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
|
||||
} else if(__analogVRef != DEFAULT_VREF){
|
||||
log_i("ADC%u: Characterized using Vref to GPIO%u: %u\n", unit, __analogVRefPin, __analogCharacteristics[unit - 1]->vref);
|
||||
} else {
|
||||
log_i("ADC%u: Characterized using Default Vref: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
|
||||
log_i("ADC%u: Characterized using Two Point Value: %u\n", unit, chars.vref);
|
||||
}
|
||||
else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
|
||||
log_i("ADC%u: Characterized using eFuse Vref: %u\n", unit, chars.vref);
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
else if(__analogVRef != DEFAULT_VREF){
|
||||
log_i("ADC%u: Characterized using Vref to GPIO%u: %u\n", unit, __analogVRefPin, chars.vref);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
log_i("ADC%u: Characterized using Default Vref: %u\n", unit, chars.vref);
|
||||
}
|
||||
print_chars_info = false;
|
||||
}
|
||||
return esp_adc_cal_raw_to_voltage(adc_reading, __analogCharacteristics[unit - 1]);
|
||||
#else
|
||||
uint16_t adc_reading = __analogRead(pin);
|
||||
uint16_t max_reading = 8191;
|
||||
uint16_t max_mv = 1100;
|
||||
switch(__analogAttenuation){
|
||||
case 3: max_mv = 3900; break;
|
||||
case 2: max_mv = 2200; break;
|
||||
case 1: max_mv = 1500; break;
|
||||
default: break;
|
||||
}
|
||||
return (adc_reading * max_mv) / max_reading;
|
||||
#endif
|
||||
return esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, &chars);
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@ -291,4 +279,3 @@ extern void analogSetVRefPin(uint8_t pin) __attribute__ ((weak, alias("__analogS
|
||||
extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth")));
|
||||
extern int hallRead() __attribute__ ((weak, alias("__hallRead")));
|
||||
#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
|
||||
@ -104,7 +107,7 @@ bool addApbChangeCallback(void * arg, apb_change_cb_t cb){
|
||||
// look for duplicate callbacks
|
||||
while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;
|
||||
if (r) {
|
||||
log_e("duplicate func=%08X arg=%08X",c->cb,c->arg);
|
||||
log_e("duplicate func=%8p arg=%8p",c->cb,c->arg);
|
||||
free(c);
|
||||
xSemaphoreGive(apb_change_lock);
|
||||
return false;
|
||||
@ -126,7 +129,7 @@ bool removeApbChangeCallback(void * arg, apb_change_cb_t cb){
|
||||
// look for matching callback
|
||||
while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;
|
||||
if ( r == NULL ) {
|
||||
log_e("not found func=%08X arg=%08X",cb,arg);
|
||||
log_e("not found func=%8p arg=%8p",cb,arg);
|
||||
xSemaphoreGive(apb_change_lock);
|
||||
return false;
|
||||
}
|
||||
@ -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
|
||||
#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"
|
||||
// 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
|
||||
// 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,180 +91,50 @@ 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)) {
|
||||
return;
|
||||
}
|
||||
gpio_config_t conf = {
|
||||
.pin_bit_mask = (1ULL<<pin), /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
|
||||
.mode = GPIO_MODE_DISABLE, /*!< GPIO mode: set input/output mode */
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE, /*!< GPIO pull-up */
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE, /*!< GPIO pull-down */
|
||||
.intr_type = GPIO_INTR_DISABLE /*!< GPIO interrupt type */
|
||||
};
|
||||
if (mode < 0x20) {//io
|
||||
conf.mode = mode & (INPUT | OUTPUT);
|
||||
if (mode & OPEN_DRAIN) {
|
||||
conf.mode |= GPIO_MODE_DEF_OD;
|
||||
}
|
||||
if (mode & PULLUP) {
|
||||
conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
}
|
||||
if (mode & PULLDOWN) {
|
||||
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_IS_VALID_GPIO(pin)) {
|
||||
log_e("Invalid pin selected");
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_hal_context_t gpiohal;
|
||||
gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
|
||||
|
||||
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
|
||||
gpio_config_t conf = {
|
||||
.pin_bit_mask = (1ULL<<pin), /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
|
||||
.mode = GPIO_MODE_DISABLE, /*!< GPIO mode: set input/output mode */
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE, /*!< GPIO pull-up */
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE, /*!< GPIO pull-down */
|
||||
.intr_type = gpiohal.dev->pin[pin].int_type /*!< GPIO interrupt type - previously set */
|
||||
};
|
||||
if (mode < 0x20) {//io
|
||||
conf.mode = mode & (INPUT | OUTPUT);
|
||||
if (mode & OPEN_DRAIN) {
|
||||
conf.mode |= GPIO_MODE_DEF_OD;
|
||||
}
|
||||
#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 (mode & PULLUP) {
|
||||
conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
}
|
||||
if (rtc_io_desc[rtc_io].pulldown) {
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pulldown);
|
||||
if (mode & PULLDOWN) {
|
||||
conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if(gpio_config(&conf) != ESP_OK)
|
||||
{
|
||||
log_e("GPIO config failed");
|
||||
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 +145,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 +153,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 +170,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 +195,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 +206,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 +216,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")));
|
||||
|
||||
|
@ -42,20 +42,15 @@ extern "C" {
|
||||
|
||||
//GPIO FUNCTIONS
|
||||
#define INPUT 0x01
|
||||
#define OUTPUT 0x02
|
||||
// Changed OUTPUT from 0x02 to behave the same as Arduino pinMode(pin,OUTPUT)
|
||||
// where you can read the state of pin even when it is set as OUTPUT
|
||||
#define OUTPUT 0x03
|
||||
#define PULLUP 0x04
|
||||
#define INPUT_PULLUP 0x05
|
||||
#define PULLDOWN 0x08
|
||||
#define INPUT_PULLDOWN 0x09
|
||||
#define OPEN_DRAIN 0x10
|
||||
#define OUTPUT_OPEN_DRAIN 0x12
|
||||
#define SPECIAL 0xF0
|
||||
#define FUNCTION_1 0x00
|
||||
#define FUNCTION_2 0x20
|
||||
#define FUNCTION_3 0x40
|
||||
#define FUNCTION_4 0x60
|
||||
#define FUNCTION_5 0x80
|
||||
#define FUNCTION_6 0xA0
|
||||
#define ANALOG 0xC0
|
||||
|
||||
//Interrupt Modes
|
||||
@ -68,22 +63,11 @@ extern "C" {
|
||||
#define ONLOW_WE 0x0C
|
||||
#define ONHIGH_WE 0x0D
|
||||
|
||||
typedef struct {
|
||||
uint8_t reg; /*!< GPIO register offset from DR_REG_IO_MUX_BASE */
|
||||
int8_t rtc; /*!< RTC GPIO number (-1 if not RTC GPIO pin) */
|
||||
int8_t adc; /*!< ADC Channel number (-1 if not ADC pin) */
|
||||
int8_t touch; /*!< Touch Channel number (-1 if not Touch pin) */
|
||||
} esp32_gpioMux_t;
|
||||
#define digitalPinIsValid(pin) GPIO_IS_VALID_GPIO(pin)
|
||||
#define digitalPinCanOutput(pin) GPIO_IS_VALID_OUTPUT_GPIO(pin)
|
||||
|
||||
extern const esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT];
|
||||
extern const int8_t esp32_adc2gpio[20];
|
||||
|
||||
#define digitalPinIsValid(pin) ((pin) < SOC_GPIO_PIN_COUNT && esp32_gpioMux[(pin)].reg)
|
||||
#define digitalPinCanOutput(pin) ((pin) < NUM_OUPUT_PINS && esp32_gpioMux[(pin)].reg)
|
||||
#define digitalPinToRtcPin(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].rtc:-1)
|
||||
#define digitalPinToAnalogChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].adc:-1)
|
||||
#define digitalPinToTouchChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].touch:-1)
|
||||
#define digitalPinToDacChannel(pin) (((pin) == PIN_DAC1)?0:((pin) == PIN_DAC2)?1:-1)
|
||||
#define digitalPinToRtcPin(pin) ((RTC_GPIO_IS_VALID_GPIO(pin))?rtc_io_number_get(pin):-1)
|
||||
#define digitalPinToDacChannel(pin) (((pin) == DAC_CHANNEL_1_GPIO_NUM)?0:((pin) == DAC_CHANNEL_2_GPIO_NUM)?1:-1)
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode);
|
||||
void digitalWrite(uint8_t pin, uint8_t val);
|
||||
@ -93,6 +77,10 @@ void attachInterrupt(uint8_t pin, void (*)(void), int mode);
|
||||
void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode);
|
||||
void detachInterrupt(uint8_t pin);
|
||||
|
||||
int8_t digitalPinToTouchChannel(uint8_t pin);
|
||||
int8_t digitalPinToAnalogChannel(uint8_t pin);
|
||||
int8_t analogChannelToDigitalPin(uint8_t channel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
23
cores/esp32/esp32-hal-i2c-slave.c
Executable file → Normal file
23
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;
|
||||
}
|
||||
@ -691,7 +695,6 @@ static void i2c_slave_isr_handler(void* arg)
|
||||
uint32_t activeInt = i2c_ll_get_intsts_mask(i2c->dev);
|
||||
i2c_ll_clr_intsts_mask(i2c->dev, activeInt);
|
||||
uint8_t rx_fifo_len = i2c_ll_get_rxfifo_cnt(i2c->dev);
|
||||
uint8_t tx_fifo_len = SOC_I2C_FIFO_LEN - i2c_ll_get_txfifo_len(i2c->dev);
|
||||
bool slave_rw = i2c_ll_slave_rw(i2c->dev);
|
||||
|
||||
if(activeInt & I2C_RXFIFO_WM_INT_ENA){ // RX FiFo Full
|
||||
@ -715,10 +718,12 @@ static void i2c_slave_isr_handler(void* arg)
|
||||
}
|
||||
if(slave_rw){ // READ
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//SEND TX Event
|
||||
i2c_slave_queue_event_t event;
|
||||
event.event = I2C_SLAVE_EVT_TX;
|
||||
pxHigherPriorityTaskWoken |= i2c_slave_send_event(i2c, &event);
|
||||
if(i2c->dev->status_reg.scl_main_state_last == 6){
|
||||
//SEND TX Event
|
||||
i2c_slave_queue_event_t event;
|
||||
event.event = I2C_SLAVE_EVT_TX;
|
||||
pxHigherPriorityTaskWoken |= i2c_slave_send_event(i2c, &event);
|
||||
}
|
||||
#else
|
||||
//reset TX data
|
||||
i2c_ll_txfifo_rst(i2c->dev);
|
||||
|
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
|
||||
@ -314,6 +317,8 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency){
|
||||
hal.dev = I2C_LL_GET_HW(i2c_num);
|
||||
i2c_hal_set_bus_timing(&(hal), frequency, src_clk);
|
||||
bus[i2c_num].frequency = frequency;
|
||||
//Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2
|
||||
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -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
|
||||
#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 LEDC_MUTEX_LOCK()
|
||||
#define LEDC_MUTEX_UNLOCK()
|
||||
#ifdef SOC_LEDC_SUPPORT_HS_MODE
|
||||
#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1)
|
||||
#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_CHANNELS (SOC_LEDC_CHANNEL_NUM)
|
||||
#endif
|
||||
|
||||
//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_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,228 +51,103 @@ 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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint8_t channels_resolution[LEDC_CHANNELS] = {0};
|
||||
|
||||
//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)
|
||||
uint32_t ledcSetup(uint8_t chan, uint32_t freq, uint8_t bit_num)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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)
|
||||
uint32_t 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)
|
||||
uint32_t ledcWriteTone(uint8_t chan, uint32_t 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;
|
||||
|
||||
uint32_t res_freq = ledc_get_freq(group,timer);
|
||||
ledcWrite(chan, 0x1FF);
|
||||
return res_freq;
|
||||
}
|
||||
|
||||
double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
|
||||
uint32_t ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
|
||||
const uint16_t noteFrequencyBase[12] = {
|
||||
// C C# D Eb E F F# G G# A Bb B
|
||||
4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902
|
||||
@ -302,21 +156,27 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
|
||||
if(octave > 8 || note >= NOTE_MAX){
|
||||
return 0;
|
||||
}
|
||||
double noteFreq = (double)noteFrequencyBase[note] / (double)(1 << (8-octave));
|
||||
uint32_t noteFreq = (uint32_t)noteFrequencyBase[note] / (uint32_t)(1 << (8-octave));
|
||||
return ledcWriteTone(chan, noteFreq);
|
||||
}
|
||||
|
||||
void ledcAttachPin(uint8_t pin, uint8_t chan)
|
||||
{
|
||||
if(chan > 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)
|
||||
@ -324,23 +184,39 @@ void ledcDetachPin(uint8_t pin)
|
||||
pinMatrixOutDetach(pin, false, false);
|
||||
}
|
||||
|
||||
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
|
||||
uint32_t ledcChangeFrequency(uint8_t chan, uint32_t freq, uint8_t bit_num)
|
||||
{
|
||||
if (chan > 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--;
|
||||
|
@ -27,15 +27,15 @@ typedef enum {
|
||||
} note_t;
|
||||
|
||||
//channel 0-15 resolution 1-16bits freq limits depend on resolution
|
||||
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits);
|
||||
uint32_t ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
|
||||
void ledcWrite(uint8_t channel, uint32_t duty);
|
||||
double ledcWriteTone(uint8_t channel, double freq);
|
||||
double ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
|
||||
uint32_t ledcWriteTone(uint8_t channel, uint32_t freq);
|
||||
uint32_t ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
|
||||
uint32_t ledcRead(uint8_t channel);
|
||||
double ledcReadFreq(uint8_t channel);
|
||||
uint32_t ledcReadFreq(uint8_t channel);
|
||||
void ledcAttachPin(uint8_t pin, uint8_t channel);
|
||||
void ledcDetachPin(uint8_t pin);
|
||||
double ledcChangeFrequency(uint8_t channel, double freq, uint8_t resolution_bits);
|
||||
uint32_t ledcChangeFrequency(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -38,9 +38,11 @@ extern "C"
|
||||
#else
|
||||
#define ARDUHAL_LOG_LEVEL CORE_DEBUG_LEVEL
|
||||
#ifdef USE_ESP_IDF_LOG
|
||||
#ifndef LOG_LOCAL_LEVEL
|
||||
#define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ARDUHAL_LOG_COLORS
|
||||
#define CONFIG_ARDUHAL_LOG_COLORS 0
|
||||
@ -158,7 +160,7 @@ void log_print_buf(const uint8_t *b, size_t len);
|
||||
#define isr_log_e(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define log_buf_e(b,l) do{ARDUHAL_LOG_COLOR_PRINT(E);log_print_buf(b,l);ARDUHAL_LOG_COLOR_PRINT_END;}while(0)
|
||||
#else
|
||||
#define log_e(format, ...) do {log_to_esp(TAG, ESP_LOG_ERROR, format, ##__VA_ARGS__);}while(0)
|
||||
#define log_e(format, ...) do {ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, TAG, format, ##__VA_ARGS__);}while(0)
|
||||
#define isr_log_e(format, ...) do {ets_printf(LOG_FORMAT(E, format), esp_log_timestamp(), TAG, ##__VA_ARGS__);}while(0)
|
||||
#define log_buf_e(b,l) do {ESP_LOG_BUFFER_HEXDUMP(TAG, b, l, ESP_LOG_ERROR);}while(0)
|
||||
#endif
|
||||
@ -187,9 +189,9 @@ void log_print_buf(const uint8_t *b, size_t len);
|
||||
#include "esp_log.h"
|
||||
|
||||
#ifdef USE_ESP_IDF_LOG
|
||||
#ifndef TAG
|
||||
#define TAG "ARDUINO"
|
||||
#endif
|
||||
//#ifndef TAG
|
||||
//#define TAG "ARDUINO"
|
||||
//#endif
|
||||
//#define log_n(format, ...) myLog(ESP_LOG_NONE, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#ifdef CONFIG_ARDUHAL_ESP_LOG
|
||||
@ -204,16 +206,16 @@ void log_print_buf(const uint8_t *b, size_t len);
|
||||
#undef ESP_EARLY_LOGD
|
||||
#undef ESP_EARLY_LOGV
|
||||
|
||||
#define ESP_LOGE(tag, ...) log_e(__VA_ARGS__)
|
||||
#define ESP_LOGW(tag, ...) log_w(__VA_ARGS__)
|
||||
#define ESP_LOGI(tag, ...) log_i(__VA_ARGS__)
|
||||
#define ESP_LOGD(tag, ...) log_d(__VA_ARGS__)
|
||||
#define ESP_LOGV(tag, ...) log_v(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGE(tag, ...) isr_log_e(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGW(tag, ...) isr_log_w(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGI(tag, ...) isr_log_i(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGD(tag, ...) isr_log_d(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGV(tag, ...) isr_log_v(__VA_ARGS__)
|
||||
#define ESP_LOGE(tag, format, ...) log_e("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_LOGW(tag, format, ...) log_w("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_LOGI(tag, format, ...) log_i("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_LOGD(tag, format, ...) log_d("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_LOGV(tag, format, ...) log_v("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGE(tag, format, ...) isr_log_e("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGW(tag, format, ...) isr_log_w("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGI(tag, format, ...) isr_log_i("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGD(tag, format, ...) isr_log_d("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGV(tag, format, ...) isr_log_v("[%s] " format, tag, ##__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "esp32/rom/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/gpio.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/gpio.h"
|
||||
#else
|
||||
|
@ -41,6 +41,9 @@
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/rtc.h"
|
||||
#include "driver/temp_sensor.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/rtc.h"
|
||||
#include "driver/temp_sensor.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#include "driver/temp_sensor.h"
|
||||
@ -197,9 +200,14 @@ void initVariant() {}
|
||||
void init() __attribute__((weak));
|
||||
void init() {}
|
||||
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
bool verifyOta() __attribute__((weak));
|
||||
bool verifyOta() { return true; }
|
||||
|
||||
bool verifyRollbackLater() __attribute__((weak));
|
||||
bool verifyRollbackLater() { return false; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
//overwritten in esp32-hal-bt.c
|
||||
bool btInUse() __attribute__((weak));
|
||||
@ -209,15 +217,17 @@ bool btInUse(){ return false; }
|
||||
void initArduino()
|
||||
{
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
esp_ota_img_states_t ota_state;
|
||||
if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
|
||||
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
if (verifyOta()) {
|
||||
esp_ota_mark_app_valid_cancel_rollback();
|
||||
} else {
|
||||
log_e("OTA verification failed! Start rollback to the previous version ...");
|
||||
esp_ota_mark_app_invalid_rollback_and_reboot();
|
||||
if(!verifyRollbackLater()){
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
esp_ota_img_states_t ota_state;
|
||||
if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
|
||||
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
if (verifyOta()) {
|
||||
esp_ota_mark_app_valid_cancel_rollback();
|
||||
} else {
|
||||
log_e("OTA verification failed! Start rollback to the previous version ...");
|
||||
esp_ota_mark_app_invalid_rollback_and_reboot();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -232,7 +242,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 +251,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,82 +27,63 @@ 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();
|
||||
duty -= 128;
|
||||
|
||||
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)
|
||||
{
|
||||
pinMatrixOutDetach(pin, false, false);
|
||||
}
|
||||
}
|
@ -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,339 +13,223 @@
|
||||
// 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 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}, {0,1}, {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 number %u exceeds available number of Timers.", num);
|
||||
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);
|
||||
}
|
||||
|
||||
bool IRAM_ATTR timerFnWrapper(void *arg){
|
||||
void (*fn)(void) = arg;
|
||||
fn();
|
||||
|
||||
// some additional logic or handling may be required here to approriately yield or not
|
||||
return false;
|
||||
}
|
||||
|
||||
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...");
|
||||
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);
|
||||
log_w("EDGE timer interrupt is not supported! Setting to LEVEL...");
|
||||
}
|
||||
timer_isr_callback_add(timer->group, timer->num, timerFnWrapper, fn, 0);
|
||||
}
|
||||
|
||||
void timerDetachInterrupt(hw_timer_t *timer){
|
||||
timerAttachInterrupt(timer, NULL, false);
|
||||
timer_isr_callback_remove(timer->group, timer->num);
|
||||
}
|
||||
|
||||
uint64_t timerReadMicros(hw_timer_t *timer){
|
||||
@ -354,6 +238,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 +256,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) {
|
||||
@ -554,8 +646,9 @@ static void usb_device_task(void *param) {
|
||||
/*
|
||||
* PUBLIC API
|
||||
* */
|
||||
static const char *tinyusb_interface_names[USB_INTERFACE_MAX] = {"MSC", "DFU", "HID", "VENDOR", "CDC", "MIDI", "CUSTOM"};
|
||||
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
|
||||
const char *tinyusb_interface_names[USB_INTERFACE_MAX] = {"MSC", "DFU", "HID", "VENDOR", "CDC", "MIDI", "CUSTOM"};
|
||||
#endif
|
||||
static bool tinyusb_is_initialized = false;
|
||||
|
||||
esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb)
|
||||
@ -607,11 +700,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 +712,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
|
||||
return err;
|
||||
}
|
||||
|
||||
void usb_persist_restart(restart_type_t mode)
|
||||
{
|
||||
if (mode < RESTART_TYPE_MAX) {
|
||||
usb_persist_mode = mode;
|
||||
esp_restart();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t tinyusb_add_string_descriptor(const char * str){
|
||||
if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){
|
||||
return 0;
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#if CONFIG_TINYUSB_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -105,4 +104,3 @@ uint8_t tinyusb_get_free_out_endpoint(void);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_TINYUSB_ENABLED */
|
||||
#endif /* CONFIG_IDF_TARGET_ESP32S2 */
|
||||
|
@ -12,219 +12,268 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-touch.h"
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_attr.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#if SOC_TOUCH_SENSOR_NUM > 0
|
||||
|
||||
#include "driver/touch_sensor.h"
|
||||
#include "esp32-hal-touch.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_intr.h"
|
||||
#endif
|
||||
/*
|
||||
Internal Private Touch Data Structure and Functions
|
||||
*/
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
static uint16_t __touchSleepCycles = 0x1000;
|
||||
static uint16_t __touchMeasureCycles = 0x1000;
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
static uint16_t __touchSleepCycles = TOUCH_PAD_SLEEP_CYCLE_DEFAULT;
|
||||
static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT;
|
||||
#endif
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
static voidFuncPtr __touchInterruptHandlers[10] = {0,};
|
||||
static intr_handle_t touch_intr_handle = NULL;
|
||||
typedef void (*voidArgFuncPtr)(void *);
|
||||
|
||||
void ARDUINO_ISR_ATTR __touchISR(void * arg)
|
||||
typedef struct {
|
||||
voidFuncPtr fn;
|
||||
bool callWithArgs;
|
||||
void* arg;
|
||||
#if SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
|
||||
bool lastStatusIsPressed;
|
||||
#endif
|
||||
} TouchInterruptHandle_t;
|
||||
|
||||
static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = {0,};
|
||||
|
||||
static void ARDUINO_ISR_ATTR __touchISR(void * arg)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t pad_intr = READ_PERI_REG(SENS_SAR_TOUCH_CTRL2_REG) & 0x3ff;
|
||||
uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG);
|
||||
uint8_t i = 0;
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
uint32_t pad_intr = touch_pad_get_status();
|
||||
//clear interrupt
|
||||
WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, rtc_intr);
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR);
|
||||
|
||||
if (rtc_intr & RTC_CNTL_TOUCH_INT_ST) {
|
||||
for (i = 0; i < 10; ++i) {
|
||||
if ((pad_intr >> i) & 0x01) {
|
||||
if(__touchInterruptHandlers[i]){
|
||||
__touchInterruptHandlers[i]();
|
||||
touch_pad_clear_status();
|
||||
// call Pad ISR User callback
|
||||
for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||
if ((pad_intr >> i) & 0x01) {
|
||||
if(__touchInterruptHandlers[i].fn){
|
||||
// keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)"
|
||||
if (__touchInterruptHandlers[i].callWithArgs) {
|
||||
((voidArgFuncPtr)__touchInterruptHandlers[i].fn)(__touchInterruptHandlers[i].arg);
|
||||
} else {
|
||||
__touchInterruptHandlers[i].fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
touch_pad_intr_mask_t evt = touch_pad_read_intr_status_mask();
|
||||
uint8_t pad_num = touch_pad_get_current_meas_channel();
|
||||
if (evt & TOUCH_PAD_INTR_MASK_ACTIVE) {
|
||||
// touch has been pressed / touched
|
||||
__touchInterruptHandlers[pad_num].lastStatusIsPressed = true;
|
||||
}
|
||||
if (evt & TOUCH_PAD_INTR_MASK_INACTIVE) {
|
||||
// touch has been released / untouched
|
||||
__touchInterruptHandlers[pad_num].lastStatusIsPressed = false;
|
||||
}
|
||||
if(__touchInterruptHandlers[pad_num].fn){
|
||||
// keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)"
|
||||
if (__touchInterruptHandlers[pad_num].callWithArgs) {
|
||||
((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg);
|
||||
} else {
|
||||
__touchInterruptHandlers[pad_num].fn();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void __touchSetCycles(uint16_t measure, uint16_t sleep)
|
||||
|
||||
|
||||
static void __touchSetCycles(uint16_t measure, uint16_t sleep)
|
||||
{
|
||||
__touchSleepCycles = sleep;
|
||||
__touchMeasureCycles = measure;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//Touch pad SleepCycle Time
|
||||
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_SLEEP_CYCLES, __touchSleepCycles, SENS_TOUCH_SLEEP_CYCLES_S);
|
||||
//Touch Pad Measure Time
|
||||
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_MEAS_DELAY, __touchMeasureCycles, SENS_TOUCH_MEAS_DELAY_S);
|
||||
#else
|
||||
touch_pad_set_meas_time(sleep, measure);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __touchInit()
|
||||
|
||||
|
||||
static void __touchInit()
|
||||
{
|
||||
static bool initialized = false;
|
||||
if(initialized){
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS, 1, RTC_IO_TOUCH_XPD_BIAS_S);
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR);
|
||||
//clear touch enable
|
||||
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, 0x0);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_TOUCH_SLP_TIMER_EN);
|
||||
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles);
|
||||
esp_intr_alloc(ETS_RTC_CORE_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, __touchISR, NULL, &touch_intr_handle);
|
||||
#else
|
||||
touch_pad_init();
|
||||
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V5);
|
||||
touch_pad_set_idle_channel_connect(TOUCH_PAD_CONN_GND);
|
||||
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles);
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
err = touch_pad_init();
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
// the next two lines will drive the touch reading values -- both will return ESP_OK
|
||||
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V);
|
||||
touch_pad_set_meas_time(__touchMeasureCycles, __touchSleepCycles);
|
||||
// Touch Sensor Timer initiated
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK
|
||||
err = touch_pad_filter_start(10);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
// keep ISR activated - it can run all together (ISR + touchRead())
|
||||
err = touch_pad_isr_register(__touchISR, NULL);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
touch_pad_intr_enable(); // returns ESP_OK
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
err = touch_pad_init();
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
// the next lines will drive the touch reading values -- all os them return ESP_OK
|
||||
touch_pad_set_meas_time(__touchSleepCycles, __touchMeasureCycles);
|
||||
touch_pad_set_voltage(TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD);
|
||||
touch_pad_set_idle_channel_connect(TOUCH_PAD_IDLE_CH_CONNECT_DEFAULT);
|
||||
touch_pad_denoise_t denoise = {
|
||||
.grade = TOUCH_PAD_DENOISE_BIT4,
|
||||
.cap_level = TOUCH_PAD_DENOISE_CAP_L4,
|
||||
};
|
||||
touch_pad_denoise_set_config(&denoise);
|
||||
touch_pad_denoise_enable();
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
||||
touch_pad_fsm_start();
|
||||
// Touch Sensor Timer initiated
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK
|
||||
touch_pad_fsm_start(); // returns ESP_OK
|
||||
//ISR setup moved to __touchChannelInit
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
return;
|
||||
err:
|
||||
log_e(" Touch sensor initialization error.");
|
||||
initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t __touchRead(uint8_t pin)
|
||||
static void __touchChannelInit(int pad)
|
||||
{
|
||||
static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = { false };
|
||||
if(channels_initialized[pad]){
|
||||
return;
|
||||
}
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
// Initial no Threshold and setup
|
||||
__touchInterruptHandlers[pad].fn = NULL;
|
||||
touch_pad_config(pad, SOC_TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
// Initial no Threshold and setup
|
||||
__touchInterruptHandlers[pad].fn = NULL;
|
||||
touch_pad_config(pad); // returns ESP_OK
|
||||
// keep ISR activated - it can run all together (ISR + touchRead())
|
||||
esp_err_t err = touch_pad_isr_register(__touchISR, NULL, TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE);
|
||||
if (err != ESP_OK) {
|
||||
log_e(" Touch sensor initialization error.");
|
||||
return;
|
||||
}
|
||||
touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); // returns ESP_OK
|
||||
#endif
|
||||
|
||||
channels_initialized[pad] = true;
|
||||
delay(20); //delay needed before reading from touch channel after config
|
||||
}
|
||||
|
||||
static touch_value_t __touchRead(uint8_t pin)
|
||||
{
|
||||
int8_t pad = digitalPinToTouchChannel(pin);
|
||||
if(pad < 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
pinMode(pin, ANALOG);
|
||||
|
||||
__touchInit();
|
||||
__touchChannelInit(pad);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
|
||||
//Disable Intr & enable touch pad
|
||||
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG,
|
||||
(v0 & ~((1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | (1 << (pad + SENS_TOUCH_PAD_OUTEN1_S))))
|
||||
| (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
|
||||
touch_value_t touch_value;
|
||||
touch_pad_read_raw_data(pad, &touch_value);
|
||||
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
|
||||
|
||||
uint32_t rtc_tio_reg = RTC_IO_TOUCH_PAD0_REG + pad * 4;
|
||||
WRITE_PERI_REG(rtc_tio_reg, (READ_PERI_REG(rtc_tio_reg)
|
||||
& ~(RTC_IO_TOUCH_PAD0_DAC_M))
|
||||
| (7 << RTC_IO_TOUCH_PAD0_DAC_S)//Touch Set Slope
|
||||
| RTC_IO_TOUCH_PAD0_TIE_OPT_M //Enable Tie,Init Level
|
||||
| RTC_IO_TOUCH_PAD0_START_M //Enable Touch Pad IO
|
||||
| RTC_IO_TOUCH_PAD0_XPD_M); //Enable Touch Pad Power on
|
||||
|
||||
//force oneTime test start
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
|
||||
|
||||
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_XPD_WAIT, 10, SENS_TOUCH_XPD_WAIT_S);
|
||||
|
||||
while (GET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_DONE) == 0) {};
|
||||
|
||||
uint16_t touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (pad / 2) * 4) >> ((pad & 1) ? SENS_TOUCH_MEAS_OUT1_S : SENS_TOUCH_MEAS_OUT0_S);
|
||||
|
||||
//clear touch force ,select the Touch mode is Timer
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
|
||||
|
||||
//restore previous value
|
||||
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0);
|
||||
return touch_value;
|
||||
#else
|
||||
static uint32_t chan_mask = 0;
|
||||
uint32_t value = 0;
|
||||
if((chan_mask & (1 << pad)) == 0){
|
||||
if(touch_pad_set_thresh((touch_pad_t)pad, TOUCH_PAD_THRESHOLD_MAX) != ESP_OK){
|
||||
log_e("touch_pad_set_thresh failed");
|
||||
} else if(touch_pad_config((touch_pad_t)pad) != ESP_OK){
|
||||
log_e("touch_pad_config failed");
|
||||
} else {
|
||||
chan_mask |= (1 << pad);
|
||||
}
|
||||
}
|
||||
if((chan_mask & (1 << pad)) != 0) {
|
||||
if(touch_pad_read_raw_data((touch_pad_t)pad, &value) != ESP_OK){
|
||||
log_e("touch_pad_read_raw_data failed");
|
||||
}
|
||||
}
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold)
|
||||
static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Args, touch_value_t threshold, bool callWithArgs)
|
||||
{
|
||||
int8_t pad = digitalPinToTouchChannel(pin);
|
||||
if(pad < 0){
|
||||
return;
|
||||
}
|
||||
|
||||
pinMode(pin, ANALOG);
|
||||
|
||||
__touchInit();
|
||||
|
||||
__touchInterruptHandlers[pad] = userFunc;
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//clear touch force ,select the Touch mode is Timer
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
|
||||
|
||||
//interrupt when touch value < threshold
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL);
|
||||
//Intr will give ,when SET0 < threshold
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_1EN);
|
||||
//Enable Rtc Touch Module Intr,the Interrupt need Rtc out Enable
|
||||
SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_TOUCH_INT_ENA);
|
||||
|
||||
//set threshold
|
||||
uint8_t shift = (pad & 1) ? SENS_TOUCH_OUT_TH1_S : SENS_TOUCH_OUT_TH0_S;
|
||||
SET_PERI_REG_BITS((SENS_SAR_TOUCH_THRES1_REG + (pad / 2) * 4), SENS_TOUCH_OUT_TH0, threshold, shift);
|
||||
|
||||
uint32_t rtc_tio_reg = RTC_IO_TOUCH_PAD0_REG + pad * 4;
|
||||
WRITE_PERI_REG(rtc_tio_reg, (READ_PERI_REG(rtc_tio_reg)
|
||||
& ~(RTC_IO_TOUCH_PAD0_DAC_M))
|
||||
| (7 << RTC_IO_TOUCH_PAD0_DAC_S)//Touch Set Slope
|
||||
| RTC_IO_TOUCH_PAD0_TIE_OPT_M //Enable Tie,Init Level
|
||||
| RTC_IO_TOUCH_PAD0_START_M //Enable Touch Pad IO
|
||||
| RTC_IO_TOUCH_PAD0_XPD_M); //Enable Touch Pad Power on
|
||||
|
||||
//Enable Digital rtc control :work mode and out mode
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG,
|
||||
(1 << (pad + SENS_TOUCH_PAD_WORKEN_S)) | \
|
||||
(1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | \
|
||||
(1 << (pad + SENS_TOUCH_PAD_OUTEN1_S)));
|
||||
#else
|
||||
if (userFunc == NULL) {
|
||||
// dettach ISR User Call
|
||||
__touchInterruptHandlers[pad].fn = NULL;
|
||||
threshold = SOC_TOUCH_PAD_THRESHOLD_MAX; // deactivate the ISR with SOC_TOUCH_PAD_THRESHOLD_MAX
|
||||
} else {
|
||||
// attach ISR User Call
|
||||
__touchInit();
|
||||
#if SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
__touchChannelInit(pad);
|
||||
#endif
|
||||
__touchInterruptHandlers[pad].fn = userFunc;
|
||||
__touchInterruptHandlers[pad].callWithArgs = callWithArgs;
|
||||
__touchInterruptHandlers[pad].arg = Args;
|
||||
}
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
touch_pad_config(pad, threshold);
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||
touch_pad_set_thresh(pad, threshold);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern uint16_t touchRead(uint8_t pin) __attribute__ ((weak, alias("__touchRead")));
|
||||
extern void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold) __attribute__ ((weak, alias("__touchAttachInterrupt")));
|
||||
extern void touchSetCycles(uint16_t measure, uint16_t sleep) __attribute__ ((weak, alias("__touchSetCycles")));
|
||||
// it keeps backwards compatibility
|
||||
static void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold)
|
||||
{
|
||||
__touchConfigInterrupt(pin, userFunc, NULL, threshold, false);
|
||||
}
|
||||
|
||||
// new additional version of the API with User Args
|
||||
static void __touchAttachArgsInterrupt(uint8_t pin, void (*userFunc)(void), void *args, touch_value_t threshold)
|
||||
{
|
||||
__touchConfigInterrupt(pin, userFunc, args, threshold, true);
|
||||
}
|
||||
|
||||
// new additional API to dettach touch ISR
|
||||
static void __touchDettachInterrupt(uint8_t pin)
|
||||
{
|
||||
__touchConfigInterrupt(pin, NULL, NULL, 0, false); // userFunc as NULL acts as dettaching
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
External Public Touch API Functions
|
||||
*/
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
|
||||
void touchInterruptSetThresholdDirection(bool mustbeLower) {
|
||||
if (mustbeLower) {
|
||||
touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW);
|
||||
} else {
|
||||
touch_pad_set_trigger_mode(TOUCH_TRIGGER_ABOVE);
|
||||
}
|
||||
}
|
||||
#elif SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
|
||||
// returns true if touch pad has been and continues pressed and false otherwise
|
||||
bool touchInterruptGetLastStatus(uint8_t pin) {
|
||||
int8_t pad = digitalPinToTouchChannel(pin);
|
||||
if(pad < 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
return __touchInterruptHandlers[pad].lastStatusIsPressed;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern touch_value_t touchRead(uint8_t) __attribute__ ((weak, alias("__touchRead")));
|
||||
extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribute__ ((weak, alias("__touchAttachInterrupt")));
|
||||
extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__ ((weak, alias("__touchAttachArgsInterrupt")));
|
||||
extern void touchDetachInterrupt(uint8_t) __attribute__ ((weak, alias("__touchDettachInterrupt")));
|
||||
extern void touchSetCycles(uint16_t, uint16_t) __attribute__ ((weak, alias("__touchSetCycles")));
|
||||
|
||||
#endif // #if SOC_TOUCH_SENSOR_NUM > 0
|
||||
|
@ -24,8 +24,21 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#if SOC_TOUCH_SENSOR_NUM > 0
|
||||
|
||||
#if !defined(SOC_TOUCH_VERSION_1) && !defined(SOC_TOUCH_VERSION_2)
|
||||
#error Touch IDF driver Not supported!
|
||||
#endif
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||
typedef uint16_t touch_value_t;
|
||||
#elif SOC_TOUCH_VERSION_2 // ESP32S2 ESP32S3
|
||||
typedef uint32_t touch_value_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set cycles that measurement operation takes
|
||||
* The result from touchRead, threshold and detection
|
||||
@ -40,17 +53,44 @@ void touchSetCycles(uint16_t measure, uint16_t sleep);
|
||||
* You can use this method to chose a good threshold value
|
||||
* to use as value for touchAttachInterrupt
|
||||
* */
|
||||
uint16_t touchRead(uint8_t pin);
|
||||
touch_value_t touchRead(uint8_t pin);
|
||||
|
||||
/*
|
||||
* Set function to be called if touch pad value falls
|
||||
* below the given threshold. Use touchRead to determine
|
||||
* a proper threshold between touched and untouched state
|
||||
* Set function to be called if touch pad value falls (ESP32)
|
||||
* below the given threshold / rises (ESP32-S2/S3) by given increment (threshold).
|
||||
* Use touchRead to determine a proper threshold between touched and untouched state
|
||||
* */
|
||||
void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold);
|
||||
void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold);
|
||||
void touchAttachInterruptArg(uint8_t pin, void (*userFunc)(void*), void *arg, touch_value_t threshold);
|
||||
void touchDetachInterrupt(uint8_t pin);
|
||||
|
||||
/*
|
||||
* Specific functions to ESP32
|
||||
* Tells the driver if it shall activate the ISR if the sensor is Lower or Higher than the Threshold
|
||||
* Default if Lower.
|
||||
**/
|
||||
|
||||
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
|
||||
void touchInterruptSetThresholdDirection(bool mustbeLower);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Specific functions to ESP32-S2 and ESP32-S3
|
||||
* Returns true when the latest ISR status for the Touchpad is that it is touched (Active)
|
||||
* and false when the Touchpad is untoouched (Inactive)
|
||||
* This function can be used in conjunction with ISR User callback in order to take action
|
||||
* as soon as the touchpad is touched and/or released
|
||||
**/
|
||||
|
||||
#if SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
|
||||
// returns true if touch pad has been and continues pressed and false otherwise
|
||||
bool touchInterruptGetLastStatus(uint8_t pin);
|
||||
#endif
|
||||
|
||||
#endif // SOC_TOUCH_SENSOR_NUM > 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */
|
||||
|
@ -34,7 +34,7 @@ struct uart_struct_t {
|
||||
uint8_t num;
|
||||
bool has_peek;
|
||||
uint8_t peek_byte;
|
||||
|
||||
QueueHandle_t uart_event_queue; // export it by some uartGetEventQueue() function
|
||||
};
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
@ -43,12 +43,12 @@ struct uart_struct_t {
|
||||
#define UART_MUTEX_UNLOCK()
|
||||
|
||||
static uart_t _uart_bus_array[] = {
|
||||
{0, false, 0},
|
||||
{0, false, 0, NULL},
|
||||
#if SOC_UART_NUM > 1
|
||||
{1, false, 0},
|
||||
{1, false, 0, NULL},
|
||||
#endif
|
||||
#if SOC_UART_NUM > 2
|
||||
{2, false, 0},
|
||||
{2, false, 0, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -58,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));
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
// IDF uart_set_pin() will issue necessary Error Message and take care of all GPIO Number validation.
|
||||
uart_set_pin(uart->num, txPin, rxPin, rtsPin, ctsPin);
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -500,8 +538,6 @@ void uartStartDetectBaudrate(uart_t *uart) {
|
||||
return;
|
||||
}
|
||||
|
||||
uart_dev_t *hw = UART_LL_GET_HW(uart->num);
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
// ESP32-C3 requires further testing
|
||||
@ -515,8 +551,9 @@ 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
|
||||
uart_dev_t *hw = UART_LL_GET_HW(uart->num);
|
||||
hw->auto_baud.glitch_filt = 0x08;
|
||||
hw->auto_baud.en = 0;
|
||||
hw->auto_baud.en = 1;
|
||||
@ -533,7 +570,6 @@ uartDetectBaudrate(uart_t *uart)
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 requires further testing - Baud rate detection returns wrong values
|
||||
|
||||
static bool uartStateDetectingBaudrate = false;
|
||||
uart_dev_t *hw = UART_LL_GET_HW(uart->num);
|
||||
|
||||
if(!uartStateDetectingBaudrate) {
|
||||
uartStartDetectBaudrate(uart);
|
||||
@ -552,7 +588,9 @@ uartDetectBaudrate(uart_t *uart)
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
//hw->conf0.autobaud_en = 0;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#else
|
||||
uart_dev_t *hw = UART_LL_GET_HW(uart->num);
|
||||
hw->auto_baud.en = 0;
|
||||
#endif
|
||||
uartStateDetectingBaudrate = false; // Initialize for the next round
|
||||
|
@ -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 4
|
||||
|
||||
/**
|
||||
* 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
3
cores/esp32/libb64/cdecode.c
Executable file → Normal file
3
cores/esp32/libb64/cdecode.c
Executable file → Normal file
@ -40,6 +40,7 @@ static int base64_decode_block_signed(const int8_t* code_in, const int length_in
|
||||
fragment = (int8_t)base64_decode_value_signed(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar = (fragment & 0x03f) << 2;
|
||||
// fall through
|
||||
case step_b:
|
||||
do {
|
||||
if (codechar == code_in+length_in){
|
||||
@ -51,6 +52,7 @@ static int base64_decode_block_signed(const int8_t* code_in, const int length_in
|
||||
} while (fragment < 0);
|
||||
*plainchar++ |= (fragment & 0x030) >> 4;
|
||||
*plainchar = (fragment & 0x00f) << 4;
|
||||
// fall through
|
||||
case step_c:
|
||||
do {
|
||||
if (codechar == code_in+length_in){
|
||||
@ -62,6 +64,7 @@ static int base64_decode_block_signed(const int8_t* code_in, const int length_in
|
||||
} while (fragment < 0);
|
||||
*plainchar++ |= (fragment & 0x03c) >> 2;
|
||||
*plainchar = (fragment & 0x003) << 6;
|
||||
// fall through
|
||||
case step_d:
|
||||
do {
|
||||
if (codechar == code_in+length_in){
|
||||
|
0
cores/esp32/libb64/cdecode.h
Executable file → Normal file
0
cores/esp32/libb64/cdecode.h
Executable file → Normal file
2
cores/esp32/libb64/cencode.c
Executable file → Normal file
2
cores/esp32/libb64/cencode.c
Executable file → Normal file
@ -44,6 +44,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
|
||||
result = (fragment & 0x0fc) >> 2;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x003) << 4;
|
||||
// fall through
|
||||
case step_B:
|
||||
if (plainchar == plaintextend) {
|
||||
state_in->result = result;
|
||||
@ -54,6 +55,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
|
||||
result |= (fragment & 0x0f0) >> 4;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x00f) << 2;
|
||||
// fall through
|
||||
case step_C:
|
||||
if (plainchar == plaintextend) {
|
||||
state_in->result = result;
|
||||
|
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
|
||||
|
@ -67,6 +67,31 @@ char* ltoa(long value, char* result, int base) {
|
||||
return result;
|
||||
}
|
||||
|
||||
char* lltoa (long long val, char* result, int base) {
|
||||
if(base < 2 || base > 16) {
|
||||
*result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char* out = result;
|
||||
long long quotient = val > 0 ? val : -val;
|
||||
|
||||
do {
|
||||
const long long tmp = quotient / base;
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
++out;
|
||||
quotient = tmp;
|
||||
} while(quotient);
|
||||
|
||||
// Apply negative sign
|
||||
if(val < 0)
|
||||
*out++ = '-';
|
||||
|
||||
reverse(result, out);
|
||||
*out = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char* ultoa(unsigned long value, char* result, int base) {
|
||||
if(base < 2 || base > 16) {
|
||||
*result = 0;
|
||||
@ -88,7 +113,28 @@ char* ultoa(unsigned long value, char* result, int base) {
|
||||
return result;
|
||||
}
|
||||
|
||||
char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
|
||||
char* ulltoa (unsigned long long val, char* result, int base) {
|
||||
if(base < 2 || base > 16) {
|
||||
*result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char* out = result;
|
||||
unsigned long long quotient = val;
|
||||
|
||||
do {
|
||||
const unsigned long long tmp = quotient / base;
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
++out;
|
||||
quotient = tmp;
|
||||
} while(quotient);
|
||||
|
||||
reverse(result, out);
|
||||
*out = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char * dtostrf(double number, signed int width, unsigned int prec, char *s) {
|
||||
bool negative = false;
|
||||
|
||||
if (isnan(number)) {
|
||||
@ -117,7 +163,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;
|
||||
|
||||
@ -160,3 +206,5 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
|
||||
*out = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,11 +35,15 @@ char* itoa (int val, char *s, int radix);
|
||||
|
||||
char* ltoa (long val, char *s, int radix);
|
||||
|
||||
char* lltoa (long long val, char* s, int radix);
|
||||
|
||||
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* ulltoa (unsigned long long val, char* s, int radix);
|
||||
|
||||
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 |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user