forked from espressif/arduino-esp32
Compare commits
210 Commits
Author | SHA1 | Date | |
---|---|---|---|
142fceb856 | |||
ba591fd958 | |||
4453ca5493 | |||
ce2cd111a1 | |||
5f6d093d4a | |||
51bf1832b8 | |||
384dbc2081 | |||
f2cfe78705 | |||
45583af189 | |||
f60cd8a069 | |||
5fa0c2010e | |||
adfaaecc65 | |||
0dd517dc9f | |||
823fe77e41 | |||
a9d33de70e | |||
d7ffd573d0 | |||
b88a70a0bd | |||
f3bdfb31f9 | |||
d8a99ed449 | |||
0a1ba74b60 | |||
1aa16104ff | |||
22c51579da | |||
f0636d515f | |||
b3c203db26 | |||
323bbbf63b | |||
02f4178b72 | |||
e1c9606531 | |||
fb60efd592 | |||
12045d335b | |||
45b7fa05b6 | |||
d3340837c7 | |||
6cfe4613e4 | |||
7dc8ca4e1e | |||
d4e20294e5 | |||
f1acc432af | |||
6fe1c4c5d6 | |||
5d6b9d0939 | |||
6b72fee59b | |||
a1409ef90d | |||
ab197e12a9 | |||
1e388a24ce | |||
7c9b837cdb | |||
5c5a112ffa | |||
31510f4e17 | |||
aa783e6ac4 | |||
9d188f5c67 | |||
51040cc4eb | |||
c26e3f4299 | |||
ab34321a16 | |||
8ee5f0a11e | |||
3f79097d5f | |||
e03a9f5c53 | |||
528c071299 | |||
7b89b39e10 | |||
905f8f2991 | |||
c25feca639 | |||
6014ff433f | |||
77e95311e0 | |||
8fe0efe8c0 | |||
0b10c8b79e | |||
d977359e34 | |||
ba8024c0d2 | |||
e87b87d04c | |||
9b9744f25f | |||
68daea4a4a | |||
52e018198b | |||
883241229e | |||
9b00d4ae6b | |||
66596fa581 | |||
02a3a71e7c | |||
3a7dfa14db | |||
96f8f5e3ef | |||
4da1051266 | |||
7d4992a811 | |||
95b8e7e42b | |||
e8d6050a7b | |||
683dbf3b1b | |||
c2e5957f35 | |||
eae67a9fb4 | |||
52575d63f4 | |||
d1f0d6c0fc | |||
bf58ab65e9 | |||
c280225738 | |||
4f7e88a177 | |||
b254765ef8 | |||
8899de760a | |||
524279d468 | |||
f319804521 | |||
2884215f85 | |||
a57cac63e4 | |||
de6994187d | |||
491444c15a | |||
a135169176 | |||
b5f3d6c836 | |||
d5e8c9dddc | |||
65cfab7868 | |||
4517b9c8fc | |||
dad946a641 | |||
7c58696223 | |||
02a70bbd21 | |||
50e9772ecf | |||
01303b700d | |||
4900979906 | |||
c7cc5c90eb | |||
70b7c3afcb | |||
e83a9b5f60 | |||
7be846cb23 | |||
2c7052a64c | |||
c99f594b63 | |||
05d8cddee7 | |||
c4954dd582 | |||
4cbb7389db | |||
ab6e010c20 | |||
7eec41dcb5 | |||
9dbc908784 | |||
9b066ea61c | |||
bb4d9027dd | |||
1046f59f6b | |||
6591f5bd4c | |||
0ea485e518 | |||
3a96fc0e4a | |||
5be3ff74ea | |||
dafdc05249 | |||
ef35baffb0 | |||
7a6dae02aa | |||
9f08cf4767 | |||
96a5ddcd0e | |||
9fe34f6553 | |||
cbeb7c4df8 | |||
754ceddf48 | |||
39a2080922 | |||
9555ed4b76 | |||
0d665d7e55 | |||
bb7df04446 | |||
ce68d72157 | |||
6a7bcabd6b | |||
a61609376a | |||
4a1cbeb69b | |||
a5932064f9 | |||
a45790b20e | |||
0b4516eef5 | |||
cbfcfbf970 | |||
c9b0dc99d3 | |||
a134088a0b | |||
78b2df74f5 | |||
77756d8a06 | |||
c6e30e0027 | |||
41d972564c | |||
a0beb81a4c | |||
460af2e1a5 | |||
48a722aae8 | |||
702db50627 | |||
1ac3aefa61 | |||
e84e9c153e | |||
1d3ff0520a | |||
b3b3403296 | |||
c014eaf352 | |||
5ae3886c66 | |||
1bbe61ab6f | |||
841599c248 | |||
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
|
132
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
Normal file
132
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
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.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 @@
|
|||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
*By completing this PR sufficiently, you help us to review this Pull Request quicker and also help improve the quality of Release Notes*
|
||||||
This entire section can be deleted if all items are checked.
|
|
||||||
|
|
||||||
*By completing this PR sufficiently, you help us to improve the quality of Release Notes*
|
|
||||||
|
|
||||||
### Checklist
|
### 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")
|
*This entire section above can be deleted if all items are checked.*
|
||||||
2. [ ] Please provide related links (eg. Issue, other Project, submodule PR..)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
## Summary
|
-----------
|
||||||
Please describe your proposed PR and what it contains.
|
## Description of Change
|
||||||
|
Please describe your proposed Pull Request and it's impact.
|
||||||
|
|
||||||
## Impact
|
## Tests scenarios
|
||||||
Please describe impact of your PR and it's function.
|
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
|
#!/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
|
# 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
|
# 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"
|
export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32"
|
||||||
if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
|
if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
|
||||||
echo "Installing ESP32 Arduino Core ..."
|
echo "Installing ESP32 Arduino Core ..."
|
||||||
script_init_path="$PWD"
|
script_init_path="$PWD"
|
||||||
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif"
|
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif"
|
||||||
cd "$ARDUINO_USR_PATH/hardware/espressif"
|
cd "$ARDUINO_USR_PATH/hardware/espressif"
|
||||||
|
|
||||||
echo "Installing Python Serial ..."
|
echo "Installing Python Serial ..."
|
||||||
pip install pyserial > /dev/null
|
pip install pyserial > /dev/null
|
||||||
|
|
||||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||||
echo "Installing Python Requests ..."
|
echo "Installing Python Requests ..."
|
||||||
pip install requests > /dev/null
|
pip install requests > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
|
if [ ! -z "$GITHUB_REPOSITORY" ]; then
|
||||||
echo "Linking Core..."
|
echo "Linking Core..."
|
||||||
ln -s $GITHUB_WORKSPACE esp32
|
ln -s $GITHUB_WORKSPACE esp32
|
||||||
else
|
else
|
||||||
echo "Cloning Core Repository..."
|
echo "Cloning Core Repository..."
|
||||||
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
|
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#echo "Updating Submodules ..."
|
#echo "Updating Submodules ..."
|
||||||
cd esp32
|
cd esp32
|
||||||
#git submodule update --init --recursive > /dev/null 2>&1
|
#git submodule update --init --recursive > /dev/null 2>&1
|
||||||
|
|
||||||
echo "Installing Platform Tools ..."
|
echo "Installing Platform Tools ..."
|
||||||
cd tools && python get.py
|
cd tools && python get.py
|
||||||
cd $script_init_path
|
cd $script_init_path
|
||||||
|
|
||||||
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"
|
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
258
.github/scripts/install-arduino-ide.sh
vendored
258
.github/scripts/install-arduino-ide.sh
vendored
@ -6,46 +6,43 @@
|
|||||||
|
|
||||||
OSBITS=`arch`
|
OSBITS=`arch`
|
||||||
if [[ "$OSTYPE" == "linux"* ]]; then
|
if [[ "$OSTYPE" == "linux"* ]]; then
|
||||||
export OS_IS_LINUX="1"
|
export OS_IS_LINUX="1"
|
||||||
ARCHIVE_FORMAT="tar.xz"
|
ARCHIVE_FORMAT="tar.xz"
|
||||||
if [[ "$OSBITS" == "i686" ]]; then
|
if [[ "$OSBITS" == "i686" ]]; then
|
||||||
OS_NAME="linux32"
|
OS_NAME="linux32"
|
||||||
elif [[ "$OSBITS" == "x86_64" ]]; then
|
elif [[ "$OSBITS" == "x86_64" ]]; then
|
||||||
OS_NAME="linux64"
|
OS_NAME="linux64"
|
||||||
elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then
|
elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then
|
||||||
OS_NAME="linuxarm"
|
OS_NAME="linuxarm"
|
||||||
else
|
else
|
||||||
OS_NAME="$OSTYPE-$OSBITS"
|
OS_NAME="$OSTYPE-$OSBITS"
|
||||||
echo "Unknown OS '$OS_NAME'"
|
echo "Unknown OS '$OS_NAME'"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
export OS_IS_MACOS="1"
|
export OS_IS_MACOS="1"
|
||||||
ARCHIVE_FORMAT="zip"
|
ARCHIVE_FORMAT="zip"
|
||||||
OS_NAME="macosx"
|
OS_NAME="macosx"
|
||||||
elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
|
elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
|
||||||
export OS_IS_WINDOWS="1"
|
export OS_IS_WINDOWS="1"
|
||||||
ARCHIVE_FORMAT="zip"
|
ARCHIVE_FORMAT="zip"
|
||||||
OS_NAME="windows"
|
OS_NAME="windows"
|
||||||
else
|
else
|
||||||
OS_NAME="$OSTYPE-$OSBITS"
|
OS_NAME="$OSTYPE-$OSBITS"
|
||||||
echo "Unknown OS '$OS_NAME'"
|
echo "Unknown OS '$OS_NAME'"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
export OS_NAME
|
export OS_NAME
|
||||||
|
|
||||||
ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
|
|
||||||
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
|
|
||||||
|
|
||||||
if [ "$OS_IS_MACOS" == "1" ]; then
|
if [ "$OS_IS_MACOS" == "1" ]; then
|
||||||
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java"
|
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java"
|
||||||
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
|
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
|
||||||
elif [ "$OS_IS_WINDOWS" == "1" ]; then
|
elif [ "$OS_IS_WINDOWS" == "1" ]; then
|
||||||
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
|
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
|
||||||
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
|
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
|
||||||
else
|
else
|
||||||
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
|
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
|
||||||
export ARDUINO_USR_PATH="$HOME/Arduino"
|
export ARDUINO_USR_PATH="$HOME/Arduino"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Updated as of Nov 3rd 2020
|
# 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-"
|
#ARDUINO_IDE_URL="https://www.arduino.cc/download.php?f=/arduino-nightly-"
|
||||||
|
|
||||||
if [ ! -d "$ARDUINO_IDE_PATH" ]; then
|
if [ ! -d "$ARDUINO_IDE_PATH" ]; then
|
||||||
echo "Installing Arduino IDE on $OS_NAME ..."
|
echo "Installing Arduino IDE on $OS_NAME ..."
|
||||||
echo "Downloading '$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
|
echo "Downloading '$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
|
||||||
if [ "$OS_IS_LINUX" == "1" ]; then
|
if [ "$OS_IS_LINUX" == "1" ]; then
|
||||||
wget -O "arduino.$ARCHIVE_FORMAT" "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
|
wget -O "arduino.$ARCHIVE_FORMAT" "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
|
||||||
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
|
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
|
||||||
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
|
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
|
||||||
mv arduino-nightly "$ARDUINO_IDE_PATH"
|
mv arduino-nightly "$ARDUINO_IDE_PATH"
|
||||||
else
|
else
|
||||||
curl -o "arduino.$ARCHIVE_FORMAT" -L "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
|
curl -o "arduino.$ARCHIVE_FORMAT" -L "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
|
||||||
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
|
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
|
||||||
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
|
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
|
||||||
if [ "$OS_IS_MACOS" == "1" ]; then
|
if [ "$OS_IS_MACOS" == "1" ]; then
|
||||||
mv "Arduino.app" "/Applications/Arduino.app"
|
mv "Arduino.app" "/Applications/Arduino.app"
|
||||||
else
|
else
|
||||||
mv arduino-nightly "$ARDUINO_IDE_PATH"
|
mv arduino-nightly "$ARDUINO_IDE_PATH"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
rm -rf "arduino.$ARCHIVE_FORMAT"
|
rm -rf "arduino.$ARCHIVE_FORMAT"
|
||||||
|
|
||||||
mkdir -p "$ARDUINO_USR_PATH/libraries"
|
mkdir -p "$ARDUINO_USR_PATH/libraries"
|
||||||
mkdir -p "$ARDUINO_USR_PATH/hardware"
|
mkdir -p "$ARDUINO_USR_PATH/hardware"
|
||||||
|
|
||||||
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
|
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
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
|
#!/bin/bash
|
||||||
|
|
||||||
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
|
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"
|
TOOLCHAIN_VERSION="8.4.0+2021r2-patch3"
|
||||||
XTENSA32S2_TOOLCHAIN_VERSION="8.4.0+2021r1"
|
|
||||||
RISCV_TOOLCHAIN_VERSION="8.4.0+2021r1"
|
|
||||||
ESPTOOLPY_VERSION="~1.30100.0"
|
ESPTOOLPY_VERSION="~1.30100.0"
|
||||||
ESPRESSIF_ORGANIZATION_NAME="espressif"
|
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-xtensa-esp32s2']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
|
||||||
replace_script+="data['packages']['toolchain-riscv32-esp']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
|
replace_script+="data['packages']['toolchain-riscv32-esp']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
|
||||||
# Update versions to use the upstream
|
# Update versions to use the upstream
|
||||||
replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$XTENSA32_TOOLCHAIN_VERSION';"
|
replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$TOOLCHAIN_VERSION';"
|
||||||
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$XTENSA32S2_TOOLCHAIN_VERSION';"
|
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$TOOLCHAIN_VERSION';"
|
||||||
replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$RISCV_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)
|
# esptool.py may require an upstream version (for now platformio is the owner)
|
||||||
replace_script+="data['packages']['tool-esptoolpy']['version']='$ESPTOOLPY_VERSION';"
|
replace_script+="data['packages']['tool-esptoolpy']['version']='$ESPTOOLPY_VERSION';"
|
||||||
# Save results
|
# 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"
|
python -c "$replace_script"
|
||||||
|
|
||||||
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
|
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
|
||||||
echo "Linking Core..."
|
echo "Linking Core..."
|
||||||
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
|
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
|
||||||
else
|
else
|
||||||
echo "Cloning Core Repository ..."
|
echo "Cloning Core Repository ..."
|
||||||
git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
|
git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "PlatformIO for ESP32 has been installed"
|
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"
|
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"
|
local examples="$1"
|
||||||
rm -rf sketches.txt
|
rm -rf sketches.txt
|
||||||
if [ ! -d "$examples" ]; then
|
if [ ! -d "$examples" ]; then
|
||||||
@ -82,7 +82,7 @@ function count_sketches() # count_sketches <examples-path>
|
|||||||
local sketchname=$(basename $sketch)
|
local sketchname=$(basename $sketch)
|
||||||
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
|
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
|
||||||
continue
|
continue
|
||||||
fi;
|
fi
|
||||||
if [[ -f "$sketchdir/.test.skip" ]]; then
|
if [[ -f "$sketchdir/.test.skip" ]]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
@ -92,8 +92,7 @@ function count_sketches() # count_sketches <examples-path>
|
|||||||
return $sketchnum
|
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
|
if [ "$#" -lt 3 ]; then
|
||||||
echo "ERROR: Illegal number of parameters"
|
echo "ERROR: Illegal number of parameters"
|
||||||
echo "USAGE: build_pio_sketches <board> <options> <examples-path> [<chunk> <total-chunks>]"
|
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 name=$(basename "$file")
|
||||||
local size=`get_file_size "$file"`
|
local size=`get_file_size "$file"`
|
||||||
local upload_res=`git_upload_to_pages "$path" "$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' ($?)"
|
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
165
.github/scripts/on-push.sh
vendored
165
.github/scripts/on-push.sh
vendored
@ -2,103 +2,118 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ ! -z "$TRAVIS_TAG" ]; then
|
export ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
|
||||||
echo "Skipping Test: Tagged build"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -z "$GITHUB_WORKSPACE" ]; then
|
function build(){
|
||||||
export TRAVIS_BUILD_DIR="$GITHUB_WORKSPACE"
|
local target=$1
|
||||||
export TRAVIS_REPO_SLUG="$GITHUB_REPOSITORY"
|
local fqbn=$2
|
||||||
elif [ ! -z "$TRAVIS_BUILD_DIR" ]; then
|
local chunk_index=$3
|
||||||
export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR"
|
local chunks_cnt=$4
|
||||||
export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG"
|
local sketches=$5
|
||||||
else
|
|
||||||
export GITHUB_WORKSPACE="$PWD"
|
local BUILD_SKETCH="${SCRIPTS_DIR}/sketch_utils.sh build"
|
||||||
export GITHUB_REPOSITORY="espressif/arduino-esp32"
|
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
|
fi
|
||||||
|
|
||||||
CHUNK_INDEX=$1
|
CHUNK_INDEX=$1
|
||||||
CHUNKS_CNT=$2
|
CHUNKS_CNT=$2
|
||||||
BUILD_PIO=0
|
BUILD_PIO=0
|
||||||
if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then
|
if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then
|
||||||
CHUNK_INDEX=0
|
CHUNK_INDEX=0
|
||||||
CHUNKS_CNT=1
|
CHUNKS_CNT=1
|
||||||
elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ] && [ "$CHUNKS_CNT" -ge 2 ]; then
|
elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ] && [ "$CHUNKS_CNT" -ge 2 ]; then
|
||||||
CHUNK_INDEX=$CHUNKS_CNT
|
CHUNK_INDEX=$CHUNKS_CNT
|
||||||
elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
|
elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
|
||||||
BUILD_PIO=1
|
BUILD_PIO=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#echo "Updating submodules ..."
|
#echo "Updating submodules ..."
|
||||||
#git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
|
#git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
|
||||||
|
|
||||||
|
SCRIPTS_DIR="./.github/scripts"
|
||||||
if [ "$BUILD_PIO" -eq 0 ]; then
|
if [ "$BUILD_PIO" -eq 0 ]; then
|
||||||
# ArduinoIDE ESP32 Test
|
source ${SCRIPTS_DIR}/install-arduino-ide.sh
|
||||||
TARGET="esp32"
|
source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
|
||||||
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
|
|
||||||
|
|
||||||
# ArduinoIDE ESP32S2 Test
|
FQBN_ESP32="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
|
||||||
TARGET="esp32s2"
|
FQBN_ESP32S2="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
|
||||||
FQBN="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
|
FQBN_ESP32S3="espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
|
||||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
FQBN_ESP32C3="espressif:esp32:esp32c3:PartitionScheme=huge_app"
|
||||||
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
|
|
||||||
|
|
||||||
# ArduinoIDE ESP32C3 Test
|
SKETCHES_ESP32="\
|
||||||
TARGET="esp32c3"
|
$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\
|
||||||
FQBN="espressif:esp32:esp32c3:PartitionScheme=huge_app"
|
$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino\
|
||||||
if [ "$OS_IS_WINDOWS" == "1" ]; then
|
$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\
|
||||||
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
|
SKETCHES_ESP32XX="\
|
||||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
|
$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\
|
||||||
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
|
$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino\
|
||||||
else
|
"
|
||||||
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
|
|
||||||
fi
|
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
|
else
|
||||||
source ./.github/scripts/install-platformio-esp32.sh
|
source ${SCRIPTS_DIR}/install-platformio-esp32.sh
|
||||||
# PlatformIO ESP32 Test
|
# PlatformIO ESP32 Test
|
||||||
BOARD="esp32dev"
|
BOARD="esp32dev"
|
||||||
OPTIONS="board_build.partitions = huge_app.csv"
|
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/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/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/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/BLE/examples/BLE_server/BLE_server.ino" && \
|
||||||
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
|
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
|
||||||
|
|
||||||
# PlatformIO ESP32 Test
|
# PlatformIO ESP32 Test
|
||||||
# OPTIONS="board_build.mcu = esp32s2"
|
# 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/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/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
|
||||||
|
|
||||||
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s2" --project-option="board_build.partitions = huge_app.csv"
|
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s2" --project-option="board_build.partitions = huge_app.csv"
|
||||||
|
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32c3" --project-option="board_build.partitions = huge_app.csv"
|
||||||
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
|
|
||||||
|
echo "Hacking in S3 support ..."
|
||||||
|
replace_script="import json; import os;"
|
||||||
|
replace_script+="fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+');"
|
||||||
|
replace_script+="data=json.load(fp);"
|
||||||
|
replace_script+="data['packages']['toolchain-xtensa-esp32']['optional']=True;"
|
||||||
|
replace_script+="data['packages']['toolchain-xtensa-esp32s3']['optional']=False;"
|
||||||
|
replace_script+="data['packages']['tool-esptoolpy']['owner']='tasmota';"
|
||||||
|
replace_script+="data['packages']['tool-esptoolpy']['version']='https://github.com/tasmota/esptool/releases/download/v3.3/esptool-3.3.zip';"
|
||||||
|
replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close()"
|
||||||
|
python -c "$replace_script"
|
||||||
|
|
||||||
|
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s3" --project-option="board_build.partitions = huge_app.csv"
|
||||||
|
|
||||||
|
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
|
||||||
fi
|
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"
|
PACKAGE_JSON_REL="package_esp32_index.json"
|
||||||
|
|
||||||
echo "Event: $GITHUB_EVENT_NAME, Repo: $GITHUB_REPOSITORY, Path: $GITHUB_WORKSPACE, Ref: $GITHUB_REF"
|
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"
|
echo "Tag: $RELEASE_TAG, Draft: $draft, Pre-Release: $RELEASE_PRE"
|
||||||
|
|
||||||
function get_file_size(){
|
function get_file_size(){
|
||||||
@ -60,7 +60,7 @@ function git_safe_upload_asset(){
|
|||||||
local name=$(basename "$file")
|
local name=$(basename "$file")
|
||||||
local size=`get_file_size "$file"`
|
local size=`get_file_size "$file"`
|
||||||
local upload_res=`git_upload_asset "$file"`
|
local upload_res=`git_upload_asset "$file"`
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -112,7 +112,7 @@ function git_safe_upload_to_pages(){
|
|||||||
local name=$(basename "$file")
|
local name=$(basename "$file")
|
||||||
local size=`get_file_size "$file"`
|
local size=`get_file_size "$file"`
|
||||||
local upload_res=`git_upload_to_pages "$path" "$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' ($?)"
|
>&2 echo "ERROR: Failed to upload '$name' ($?)"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -131,7 +131,7 @@ function merge_package_json(){
|
|||||||
local jsonOut=$2
|
local jsonOut=$2
|
||||||
local old_json=$OUTPUT_DIR/oldJson.json
|
local old_json=$OUTPUT_DIR/oldJson.json
|
||||||
local merged_json=$OUTPUT_DIR/mergedJson.json
|
local merged_json=$OUTPUT_DIR/mergedJson.json
|
||||||
|
|
||||||
echo "Downloading previous JSON $jsonLink ..."
|
echo "Downloading previous JSON $jsonLink ..."
|
||||||
curl -L -o "$old_json" "https://github.com/$GITHUB_REPOSITORY/releases/download/$jsonLink?access_token=$GITHUB_TOKEN" 2>/dev/null
|
curl -L -o "$old_json" "https://github.com/$GITHUB_REPOSITORY/releases/download/$jsonLink?access_token=$GITHUB_TOKEN" 2>/dev/null
|
||||||
if [ $? -ne 0 ]; then echo "ERROR: Download Failed! $?"; exit 1; fi
|
if [ $? -ne 0 ]; then echo "ERROR: Download Failed! $?"; exit 1; fi
|
||||||
@ -140,7 +140,7 @@ function merge_package_json(){
|
|||||||
set +e
|
set +e
|
||||||
stdbuf -oL python "$PACKAGE_JSON_MERGE" "$jsonOut" "$old_json" > "$merged_json"
|
stdbuf -oL python "$PACKAGE_JSON_MERGE" "$jsonOut" "$old_json" > "$merged_json"
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
set -v
|
set -v
|
||||||
if [ ! -s $merged_json ]; then
|
if [ ! -s $merged_json ]; then
|
||||||
rm -f "$merged_json"
|
rm -f "$merged_json"
|
||||||
@ -172,6 +172,7 @@ mkdir -p "$PKG_DIR/tools"
|
|||||||
# Copy all core files to the package folder
|
# Copy all core files to the package folder
|
||||||
echo "Copying files for packaging ..."
|
echo "Copying files for packaging ..."
|
||||||
cp -f "$GITHUB_WORKSPACE/boards.txt" "$PKG_DIR/"
|
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 -f "$GITHUB_WORKSPACE/programmers.txt" "$PKG_DIR/"
|
||||||
cp -Rf "$GITHUB_WORKSPACE/cores" "$PKG_DIR/"
|
cp -Rf "$GITHUB_WORKSPACE/cores" "$PKG_DIR/"
|
||||||
cp -Rf "$GITHUB_WORKSPACE/libraries" "$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`
|
relNotesRaw=`git -C "$GITHUB_WORKSPACE" show -s --format=%b $RELEASE_TAG`
|
||||||
readarray -t msgArray <<<"$relNotesRaw"
|
readarray -t msgArray <<<"$relNotesRaw"
|
||||||
arrLen=${#msgArray[@]}
|
arrLen=${#msgArray[@]}
|
||||||
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
|
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
|
||||||
ind=3
|
ind=3
|
||||||
while [ $ind -lt $arrLen ]; do
|
while [ $ind -lt $arrLen ]; do
|
||||||
if [ $ind -eq 3 ]; then
|
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:]]*//')"
|
oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')"
|
||||||
if [ ${#oneLine} -gt 0 ]; then
|
if [ ${#oneLine} -gt 0 ]; then
|
||||||
if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi
|
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+="$oneLine"
|
||||||
releaseNotes+=$'\r\n'
|
releaseNotes+=$'\r\n'
|
||||||
fi
|
fi
|
||||||
@ -368,9 +369,9 @@ done
|
|||||||
rm -f $commitFile
|
rm -f $commitFile
|
||||||
|
|
||||||
# Prepend the original release body
|
# Prepend the original release body
|
||||||
if [ "${RELEASE_BODY: -1}" == $'\r' ]; then
|
if [ "${RELEASE_BODY: -1}" == $'\r' ]; then
|
||||||
RELEASE_BODY="${RELEASE_BODY:0:-1}"
|
RELEASE_BODY="${RELEASE_BODY:0:-1}"
|
||||||
else
|
else
|
||||||
RELEASE_BODY="$RELEASE_BODY"
|
RELEASE_BODY="$RELEASE_BODY"
|
||||||
fi
|
fi
|
||||||
RELEASE_BODY+=$'\r\n'
|
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
|
name: Build GitHub Pages
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- name: Copy Files
|
- name: Copy Files
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
121
.github/workflows/hil.yml
vendored
Normal file
121
.github/workflows/hil.yml
vendored
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
name: Run tests in hardware
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, reopened, synchronize, labeled]
|
||||||
|
|
||||||
|
schedule:
|
||||||
|
- cron: '0 2 * * *'
|
||||||
|
|
||||||
|
env:
|
||||||
|
MAX_CHUNKS: 15
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: hil-${{github.event.pull_request.number || github.ref}}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
gen_chunks:
|
||||||
|
if: |
|
||||||
|
contains(github.event.pull_request.labels.*.name, 'hil_test') ||
|
||||||
|
github.event_name == 'schedule'
|
||||||
|
name: Generate Chunks matrix
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
chunks: ${{ steps.gen-chunks.outputs.chunks }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Generate Chunks matrix
|
||||||
|
id: gen-chunks
|
||||||
|
run: |
|
||||||
|
set +e
|
||||||
|
bash .github/scripts/sketch_utils.sh count tests
|
||||||
|
sketches=$((? - 1))
|
||||||
|
if [[ $sketches -gt ${{env.MAX_CHUNKS}} ]]; then
|
||||||
|
$sketches=${{env.MAX_CHUNKS}}
|
||||||
|
fi
|
||||||
|
set -e
|
||||||
|
rm sketches.txt
|
||||||
|
CHUNKS=$(jq -c -n '$ARGS.positional' --args `seq 0 1 $sketches`)
|
||||||
|
echo "::set-output name=chunks::${CHUNKS}"
|
||||||
|
|
||||||
|
Build:
|
||||||
|
needs: gen_chunks
|
||||||
|
name: ${{matrix.chip}}-Build#${{matrix.chunks}}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
|
||||||
|
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Build sketches
|
||||||
|
run: |
|
||||||
|
bash .github/scripts/tests_build.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
|
||||||
|
- name: Upload ${{matrix.chip}}-${{matrix.chunks}} artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
|
||||||
|
path: |
|
||||||
|
tests/*/build/*.bin
|
||||||
|
tests/*/build/*.json
|
||||||
|
Test:
|
||||||
|
needs: [gen_chunks, Build]
|
||||||
|
name: ${{matrix.chip}}-Test#${{matrix.chunks}}
|
||||||
|
runs-on:
|
||||||
|
- ESP32
|
||||||
|
- ESP32-S2
|
||||||
|
- ESP32-S3
|
||||||
|
- ESP32-C3
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
|
||||||
|
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
|
||||||
|
container:
|
||||||
|
image: python:3.10.1-bullseye
|
||||||
|
options: --privileged
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Download ${{matrix.chip}}-${{matrix.chunks}} artifacts
|
||||||
|
uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
|
||||||
|
path: tests/
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install -U pip
|
||||||
|
pip install -r tests/requirements.txt
|
||||||
|
|
||||||
|
- name: Run Tests
|
||||||
|
run: |
|
||||||
|
bash .github/scripts/tests_run.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
|
||||||
|
|
||||||
|
- name: Upload test result artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: test_results-${{matrix.chip}}-${{matrix.chunks}}
|
||||||
|
path: tests/*/*.xml
|
||||||
|
|
||||||
|
event_file:
|
||||||
|
name: "Event File"
|
||||||
|
if: ${{ always() }}
|
||||||
|
needs: Test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Event File
|
||||||
|
path: ${{github.event_path}}
|
38
.github/workflows/publish.yml
vendored
Normal file
38
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: Unit Test Results
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: [Run tests in hardware]
|
||||||
|
branches-ignore: [master]
|
||||||
|
|
||||||
|
types:
|
||||||
|
- completed
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
unit-test-results:
|
||||||
|
name: Unit Test Results
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: |
|
||||||
|
github.event.workflow_run.event == 'pull_request' &&
|
||||||
|
(github.event.workflow_run.conclusion == 'success' ||
|
||||||
|
github.event.workflow_run.conclusion == 'failure')
|
||||||
|
steps:
|
||||||
|
- name: Download and Extract Artifacts
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
run: |
|
||||||
|
mkdir -p artifacts && cd artifacts
|
||||||
|
artifacts_url=${{ github.event.workflow_run.artifacts_url }}
|
||||||
|
gh api "$artifacts_url" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact
|
||||||
|
do
|
||||||
|
IFS=$'\t' read name url <<< "$artifact"
|
||||||
|
gh api $url > "$name.zip"
|
||||||
|
unzip -d "$name" "$name.zip"
|
||||||
|
done
|
||||||
|
- name: Publish Unit Test Results
|
||||||
|
uses: EnricoMi/publish-unit-test-result-action@v1
|
||||||
|
with:
|
||||||
|
commit: ${{ github.event.workflow_run.head_sha }}
|
||||||
|
event_file: artifacts/Event File/event.json
|
||||||
|
event_name: ${{ github.event.workflow_run.event }}
|
||||||
|
files: "artifacts/**/*.xml"
|
69
.github/workflows/push.yml
vendored
69
.github/workflows/push.yml
vendored
@ -1,14 +1,26 @@
|
|||||||
name: ESP32 Arduino CI
|
name: ESP32 Arduino CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- release/*
|
- release/*
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: build-${{github.event.pull_request.number || github.ref}}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
|
cmake-check:
|
||||||
|
name: Check cmake file
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: bash ./.github/scripts/check-cmakelists.sh
|
||||||
|
|
||||||
# Ubuntu
|
# Ubuntu
|
||||||
build-arduino-linux:
|
build-arduino-linux:
|
||||||
name: Arduino ${{ matrix.chunk }} on ubuntu-latest
|
name: Arduino ${{ matrix.chunk }} on ubuntu-latest
|
||||||
@ -16,12 +28,22 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-python@v1
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
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
|
- name: Build Sketches
|
||||||
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} 15
|
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} 15
|
||||||
|
|
||||||
@ -32,10 +54,10 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-latest, macOS-latest]
|
os: [windows-latest, macOS-latest]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-python@v1
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
- name: Build Sketches
|
- name: Build Sketches
|
||||||
@ -48,11 +70,38 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-python@v1
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
- name: Build Sketches
|
- name: Build Sketches
|
||||||
run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO
|
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
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@v1
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
- name: Build Release
|
- name: Build Release
|
||||||
|
27
.github/workflows/test_selfhosted_runner.yml
vendored
27
.github/workflows/test_selfhosted_runner.yml
vendored
@ -1,27 +0,0 @@
|
|||||||
name: Test Github action on self hosted RPI runnes
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Dummy test - self hosted GHR
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
- name: Check out repo
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Test message 1
|
|
||||||
run: echo "This is test message"
|
|
||||||
- name: Test message 2
|
|
||||||
run: echo "This is test message2"
|
|
||||||
- name: List directory
|
|
||||||
run: ls
|
|
||||||
- name: Create copy of README
|
|
||||||
run: cp README.md README2.md
|
|
||||||
- name: Read README2
|
|
||||||
run: cat README2.md
|
|
||||||
- name: Delete README2
|
|
||||||
run: rm README2.md
|
|
19
.github/workflows/upload-idf-component.yml
vendored
Normal file
19
.github/workflows/upload-idf-component.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
name: Push components to https://components.espressif.com
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
|
jobs:
|
||||||
|
upload_components:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: "recursive"
|
||||||
|
|
||||||
|
- name: Upload components to the component registry
|
||||||
|
uses: espressif/github-actions/upload_components@master
|
||||||
|
with:
|
||||||
|
name: arduino-esp32
|
||||||
|
namespace: espressif
|
||||||
|
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
tools/xtensa-esp32-elf
|
tools/xtensa-esp32-elf
|
||||||
tools/xtensa-esp32s2-elf
|
tools/xtensa-esp32s2-elf
|
||||||
|
tools/xtensa-esp32s3-elf
|
||||||
tools/riscv32-esp-elf
|
tools/riscv32-esp-elf
|
||||||
tools/dist
|
tools/dist
|
||||||
tools/esptool
|
tools/esptool
|
||||||
@ -22,3 +23,6 @@ boards.sloeber.txt
|
|||||||
# Ignore docs build (Sphinx)
|
# Ignore docs build (Sphinx)
|
||||||
docs/build
|
docs/build
|
||||||
docs/source/_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/stdlib_noniso.c
|
||||||
cores/esp32/Stream.cpp
|
cores/esp32/Stream.cpp
|
||||||
cores/esp32/StreamString.cpp
|
cores/esp32/StreamString.cpp
|
||||||
|
cores/esp32/Tone.cpp
|
||||||
cores/esp32/HWCDC.cpp
|
cores/esp32/HWCDC.cpp
|
||||||
cores/esp32/USB.cpp
|
cores/esp32/USB.cpp
|
||||||
cores/esp32/USBCDC.cpp
|
cores/esp32/USBCDC.cpp
|
||||||
@ -86,6 +87,7 @@ set(LIBRARY_SRCS
|
|||||||
libraries/HTTPClient/src/HTTPClient.cpp
|
libraries/HTTPClient/src/HTTPClient.cpp
|
||||||
libraries/HTTPUpdate/src/HTTPUpdate.cpp
|
libraries/HTTPUpdate/src/HTTPUpdate.cpp
|
||||||
libraries/LittleFS/src/LittleFS.cpp
|
libraries/LittleFS/src/LittleFS.cpp
|
||||||
|
libraries/I2S/src/I2S.cpp
|
||||||
libraries/NetBIOS/src/NetBIOS.cpp
|
libraries/NetBIOS/src/NetBIOS.cpp
|
||||||
libraries/Preferences/src/Preferences.cpp
|
libraries/Preferences/src/Preferences.cpp
|
||||||
libraries/RainMaker/src/RMaker.cpp
|
libraries/RainMaker/src/RMaker.cpp
|
||||||
@ -115,6 +117,7 @@ set(LIBRARY_SRCS
|
|||||||
libraries/WebServer/src/Parsing.cpp
|
libraries/WebServer/src/Parsing.cpp
|
||||||
libraries/WebServer/src/detail/mimetable.cpp
|
libraries/WebServer/src/detail/mimetable.cpp
|
||||||
libraries/WiFiClientSecure/src/ssl_client.cpp
|
libraries/WiFiClientSecure/src/ssl_client.cpp
|
||||||
|
libraries/WiFiClientSecure/src/esp_crt_bundle.c
|
||||||
libraries/WiFiClientSecure/src/WiFiClientSecure.cpp
|
libraries/WiFiClientSecure/src/WiFiClientSecure.cpp
|
||||||
libraries/WiFi/src/WiFiAP.cpp
|
libraries/WiFi/src/WiFiAP.cpp
|
||||||
libraries/WiFi/src/WiFiClient.cpp
|
libraries/WiFi/src/WiFiClient.cpp
|
||||||
@ -161,7 +164,6 @@ set(BLE_SRCS
|
|||||||
libraries/BLE/src/GeneralUtils.cpp
|
libraries/BLE/src/GeneralUtils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
set(includedirs
|
set(includedirs
|
||||||
variants/${IDF_TARGET}/
|
variants/${IDF_TARGET}/
|
||||||
cores/esp32/
|
cores/esp32/
|
||||||
@ -173,11 +175,13 @@ set(includedirs
|
|||||||
libraries/EEPROM/src
|
libraries/EEPROM/src
|
||||||
libraries/ESP32/src
|
libraries/ESP32/src
|
||||||
libraries/ESPmDNS/src
|
libraries/ESPmDNS/src
|
||||||
|
libraries/Ethernet/src
|
||||||
libraries/FFat/src
|
libraries/FFat/src
|
||||||
libraries/FS/src
|
libraries/FS/src
|
||||||
libraries/HTTPClient/src
|
libraries/HTTPClient/src
|
||||||
libraries/HTTPUpdate/src
|
libraries/HTTPUpdate/src
|
||||||
libraries/LittleFS/src
|
libraries/LittleFS/src
|
||||||
|
libraries/I2S/src
|
||||||
libraries/NetBIOS/src
|
libraries/NetBIOS/src
|
||||||
libraries/Preferences/src
|
libraries/Preferences/src
|
||||||
libraries/RainMaker/src
|
libraries/RainMaker/src
|
||||||
@ -198,7 +202,7 @@ set(includedirs
|
|||||||
|
|
||||||
set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS})
|
set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS})
|
||||||
set(priv_includes cores/esp32/libb64)
|
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)
|
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})
|
idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires})
|
||||||
@ -233,7 +237,9 @@ function(maybe_add_component component_name)
|
|||||||
endif()
|
endif()
|
||||||
endfunction()
|
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(esp_rainmaker)
|
||||||
maybe_add_component(qrcode)
|
maybe_add_component(qrcode)
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
BOOT_APP_BIN_ROOT := $(call dequote,$(COMPONENT_PATH))
|
|
||||||
|
|
||||||
ifndef CONFIG_PARTITION_TABLE_CUSTOM
|
|
||||||
PARTITION_TABLE_CSV_PATH = $(call dequote,$(abspath $(BOOT_APP_BIN_ROOT)/$(subst $(quote),,tools/partitions/$(CONFIG_ARDUHAL_PARTITION_SCHEME).csv)))
|
|
||||||
endif
|
|
||||||
|
|
||||||
CPPFLAGS += -DARDUINO=10800 -DESP32=1 -DARDUINO_ARCH_ESP32=1 -DBOARD_HAS_PSRAM
|
|
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)
|
 [](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
|
## Contents
|
||||||
|
|
||||||
- [Development Status](#development-status)
|
- [Development Status](#development-status)
|
||||||
- [Decoding Exceptions](#decoding-exceptions)
|
- [Development Planning](#development-planning)
|
||||||
- [Issue/Bug report template](#issuebug-report-template)
|
- [Documentation](#documentation)
|
||||||
|
- [Supported Chips](#supported-chips)
|
||||||
|
- [Decoding exceptions](#decoding-exceptions)
|
||||||
|
- [Issue/Bug report template](#issuebug-report-template)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
|
||||||
### Development Status
|
### 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/)
|
Latest Development 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
|
### 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)
|
* [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)
|
* [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)
|
* [FAQ](https://docs.espressif.com/projects/arduino-esp32/en/latest/faq.html)
|
||||||
* [Troubleshooting](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.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
|
### Decoding exceptions
|
||||||
|
|
||||||
You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder) to get meaningful call trace.
|
You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder) to get meaningful call trace.
|
||||||
|
|
||||||
### Issue/Bug report template
|
### 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+).
|
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
|
### Contributing
|
||||||
|
|
||||||
|
5071
boards.txt
5071
boards.txt
File diff suppressed because it is too large
Load Diff
36
component.mk
36
component.mk
@ -1,36 +0,0 @@
|
|||||||
ARDUINO_ALL_LIBRARIES := $(patsubst $(COMPONENT_PATH)/libraries/%,%,$(wildcard $(COMPONENT_PATH)/libraries/*))
|
|
||||||
|
|
||||||
# Macro returns non-empty if Arduino library $(1) should be included in the build
|
|
||||||
# (either because selective compilation is of, or this library is enabled
|
|
||||||
define ARDUINO_LIBRARY_ENABLED
|
|
||||||
$(if $(CONFIG_ARDUINO_SELECTIVE_COMPILATION),$(CONFIG_ARDUINO_SELECTIVE_$(1)),y)
|
|
||||||
endef
|
|
||||||
|
|
||||||
ARDUINO_ENABLED_LIBRARIES := $(foreach LIBRARY,$(sort $(ARDUINO_ALL_LIBRARIES)),$(if $(call ARDUINO_LIBRARY_ENABLED,$(LIBRARY)),$(LIBRARY)))
|
|
||||||
|
|
||||||
$(info Arduino libraries in build: $(ARDUINO_ENABLED_LIBRARIES))
|
|
||||||
|
|
||||||
# Expand all subdirs under $(1)
|
|
||||||
define EXPAND_SUBDIRS
|
|
||||||
$(sort $(dir $(wildcard $(1)/* $(1)/*/* $(1)/*/*/* $(1)/*/*/*/* $(1)/*/*/*/*/*)))
|
|
||||||
endef
|
|
||||||
|
|
||||||
# Macro returns SRCDIRS for library
|
|
||||||
define ARDUINO_LIBRARY_GET_SRCDIRS
|
|
||||||
$(if $(wildcard $(COMPONENT_PATH)/libraries/$(1)/src/.), \
|
|
||||||
$(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)/src), \
|
|
||||||
$(filter-out $(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)/examples), \
|
|
||||||
$(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)) \
|
|
||||||
) \
|
|
||||||
)
|
|
||||||
endef
|
|
||||||
|
|
||||||
# Make a list of all srcdirs in enabled libraries
|
|
||||||
ARDUINO_LIBRARY_SRCDIRS := $(patsubst $(COMPONENT_PATH)/%,%,$(foreach LIBRARY,$(ARDUINO_ENABLED_LIBRARIES),$(call ARDUINO_LIBRARY_GET_SRCDIRS,$(LIBRARY))))
|
|
||||||
|
|
||||||
#$(info Arduino libraries src dirs: $(ARDUINO_LIBRARY_SRCDIRS))
|
|
||||||
|
|
||||||
COMPONENT_ADD_INCLUDEDIRS := cores/esp32 variants/esp32 $(ARDUINO_LIBRARY_SRCDIRS)
|
|
||||||
COMPONENT_PRIV_INCLUDEDIRS := cores/esp32/libb64
|
|
||||||
COMPONENT_SRCDIRS := cores/esp32/libb64 cores/esp32 variants/esp32 $(ARDUINO_LIBRARY_SRCDIRS)
|
|
||||||
CXXFLAGS += -fno-rtti
|
|
@ -166,6 +166,7 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
|||||||
#include "Udp.h"
|
#include "Udp.h"
|
||||||
#include "HardwareSerial.h"
|
#include "HardwareSerial.h"
|
||||||
#include "Esp.h"
|
#include "Esp.h"
|
||||||
|
#include "esp32/spiram.h"
|
||||||
|
|
||||||
using std::abs;
|
using std::abs;
|
||||||
using std::isinf;
|
using std::isinf;
|
||||||
@ -179,6 +180,12 @@ uint16_t makeWord(uint8_t h, uint8_t l);
|
|||||||
|
|
||||||
#define word(...) makeWord(__VA_ARGS__)
|
#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 pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||||
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||||
|
|
||||||
@ -188,6 +195,10 @@ extern "C" void configTime(long gmtOffset_sec, int daylightOffset_sec,
|
|||||||
extern "C" void configTzTime(const char* tz,
|
extern "C" void configTzTime(const char* tz,
|
||||||
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);
|
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
|
// WMath prototypes
|
||||||
long random(long);
|
long random(long);
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
@ -40,6 +40,10 @@ extern "C" {
|
|||||||
#include "esp32s2/rom/spi_flash.h"
|
#include "esp32s2/rom/spi_flash.h"
|
||||||
#include "soc/efuse_reg.h"
|
#include "soc/efuse_reg.h"
|
||||||
#define ESP_FLASH_IMAGE_BASE 0x1000
|
#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
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#include "esp32c3/rom/spi_flash.h"
|
#include "esp32c3/rom/spi_flash.h"
|
||||||
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32c3 is located at 0x0000
|
#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
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
#include "USB.h"
|
#include "USB.h"
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
|
||||||
#include "esp32-hal.h"
|
#include "esp32-hal.h"
|
||||||
#include "HWCDC.h"
|
#include "HWCDC.h"
|
||||||
@ -167,19 +167,21 @@ void HWCDC::begin(unsigned long baud)
|
|||||||
setRxBufferSize(256);//default if not preset
|
setRxBufferSize(256);//default if not preset
|
||||||
setTxBufferSize(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);
|
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){
|
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");
|
isr_log_e("HW USB CDC failed to init interrupts");
|
||||||
end();
|
end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
usb_serial_jtag_ll_txfifo_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWCDC::end()
|
void HWCDC::end()
|
||||||
{
|
{
|
||||||
//Disable tx/rx interrupt.
|
//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);
|
esp_intr_free(intr_handle);
|
||||||
intr_handle = NULL;
|
intr_handle = NULL;
|
||||||
if(tx_lock != 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;
|
HWCDC Serial;
|
||||||
#else
|
#else
|
||||||
HWCDC USBSerial;
|
HWCDC USBSerial;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_TINYUSB_CDC_ENABLED */
|
#endif /* CONFIG_TINYUSB_CDC_ENABLED */
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "esp_event.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;
|
extern HWCDC Serial;
|
||||||
#else
|
#else
|
||||||
extern HWCDC USBSerial;
|
extern HWCDC USBSerial;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_IDF_TARGET_ESP32C3 */
|
#endif /* CONFIG_IDF_TARGET_ESP32C3 */
|
||||||
|
@ -6,11 +6,13 @@
|
|||||||
#include "pins_arduino.h"
|
#include "pins_arduino.h"
|
||||||
#include "HardwareSerial.h"
|
#include "HardwareSerial.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
|
||||||
#ifndef SOC_RX0
|
#ifndef SOC_RX0
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#define SOC_RX0 3
|
#define SOC_RX0 3
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
#define SOC_RX0 44
|
#define SOC_RX0 44
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#define SOC_RX0 20
|
#define SOC_RX0 20
|
||||||
@ -20,7 +22,7 @@
|
|||||||
#ifndef SOC_TX0
|
#ifndef SOC_TX0
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#define SOC_TX0 1
|
#define SOC_TX0 1
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
#define SOC_TX0 43
|
#define SOC_TX0 43
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#define SOC_TX0 21
|
#define SOC_TX0 21
|
||||||
@ -39,6 +41,8 @@ void serialEvent(void) {}
|
|||||||
#define RX1 18
|
#define RX1 18
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#define RX1 18
|
#define RX1 18
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#define RX1 15
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -49,6 +53,8 @@ void serialEvent(void) {}
|
|||||||
#define TX1 17
|
#define TX1 17
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#define TX1 19
|
#define TX1 19
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#define TX1 16
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -60,12 +66,16 @@ void serialEvent1(void) {}
|
|||||||
#ifndef RX2
|
#ifndef RX2
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#define RX2 16
|
#define RX2 16
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#define RX2 19
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TX2
|
#ifndef TX2
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
#define TX2 17
|
#define TX2 17
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#define TX2 20
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -76,8 +86,6 @@ void serialEvent2(void) {}
|
|||||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
||||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||||
HardwareSerial Serial0(0);
|
HardwareSerial Serial0(0);
|
||||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
|
||||||
HardwareSerial Serial0(0);
|
|
||||||
#else
|
#else
|
||||||
HardwareSerial Serial(0);
|
HardwareSerial Serial(0);
|
||||||
#endif
|
#endif
|
||||||
@ -92,8 +100,6 @@ void serialEventRun(void)
|
|||||||
{
|
{
|
||||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||||
if(Serial0.available()) serialEvent();
|
if(Serial0.available()) serialEvent();
|
||||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
|
||||||
if(Serial0.available()) serialEvent();
|
|
||||||
#else
|
#else
|
||||||
if(Serial.available()) serialEvent();
|
if(Serial.available()) serialEvent();
|
||||||
#endif
|
#endif
|
||||||
@ -106,8 +112,167 @@ void serialEventRun(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
|
#define HSERIAL_MUTEX_LOCK() do {} while (xSemaphoreTake(_lock, portMAX_DELAY) != pdPASS)
|
||||||
|
#define HSERIAL_MUTEX_UNLOCK() xSemaphoreGive(_lock)
|
||||||
|
#else
|
||||||
|
#define HSERIAL_MUTEX_LOCK()
|
||||||
|
#define HSERIAL_MUTEX_UNLOCK()
|
||||||
|
#endif
|
||||||
|
|
||||||
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL), _rxBufferSize(256) {}
|
HardwareSerial::HardwareSerial(int uart_nr) :
|
||||||
|
_uart_nr(uart_nr),
|
||||||
|
_uart(NULL),
|
||||||
|
_rxBufferSize(256),
|
||||||
|
_txBufferSize(0),
|
||||||
|
_onReceiveCB(NULL),
|
||||||
|
_onReceiveErrorCB(NULL),
|
||||||
|
_onReceiveTimeout(true),
|
||||||
|
_rxTimeout(10),
|
||||||
|
_eventTask(NULL)
|
||||||
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
|
,_lock(NULL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
|
if(_lock == NULL){
|
||||||
|
_lock = xSemaphoreCreateMutex();
|
||||||
|
if(_lock == NULL){
|
||||||
|
log_e("xSemaphoreCreateMutex failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
HardwareSerial::~HardwareSerial()
|
||||||
|
{
|
||||||
|
end();
|
||||||
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
|
if(_lock != NULL){
|
||||||
|
vSemaphoreDelete(_lock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HardwareSerial::_createEventTask(void *args)
|
||||||
|
{
|
||||||
|
// Creating UART event Task
|
||||||
|
xTaskCreate(_uartEventTask, "uart_event_task", 2048, this, configMAX_PRIORITIES - 1, &_eventTask);
|
||||||
|
if (_eventTask == NULL) {
|
||||||
|
log_e(" -- UART%d Event Task not Created!", _uart_nr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HardwareSerial::_destroyEventTask(void)
|
||||||
|
{
|
||||||
|
if (_eventTask != NULL) {
|
||||||
|
vTaskDelete(_eventTask);
|
||||||
|
_eventTask = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HardwareSerial::onReceiveError(OnReceiveErrorCb function)
|
||||||
|
{
|
||||||
|
HSERIAL_MUTEX_LOCK();
|
||||||
|
// function may be NULL to cancel onReceive() from its respective task
|
||||||
|
_onReceiveErrorCB = function;
|
||||||
|
// this can be called after Serial.begin(), therefore it shall create the event task
|
||||||
|
if (function != NULL && _uart != NULL && _eventTask == NULL) {
|
||||||
|
_createEventTask(this);
|
||||||
|
}
|
||||||
|
HSERIAL_MUTEX_UNLOCK();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout)
|
||||||
|
{
|
||||||
|
HSERIAL_MUTEX_LOCK();
|
||||||
|
// function may be NULL to cancel onReceive() from its respective task
|
||||||
|
_onReceiveCB = function;
|
||||||
|
// When Rx timeout is Zero (disabled), there is only one possible option that is callback when FIFO reaches 120 bytes
|
||||||
|
_onReceiveTimeout = _rxTimeout > 0 ? onlyOnTimeout : false;
|
||||||
|
|
||||||
|
// this can be called after Serial.begin(), therefore it shall create the event task
|
||||||
|
if (function != NULL && _uart != NULL && _eventTask == NULL) {
|
||||||
|
_createEventTask(this); // Create event task
|
||||||
|
}
|
||||||
|
HSERIAL_MUTEX_UNLOCK();
|
||||||
|
}
|
||||||
|
|
||||||
|
// timout is calculates in time to receive UART symbols at the UART baudrate.
|
||||||
|
// the estimation is about 11 bits per symbol (SERIAL_8N1)
|
||||||
|
void HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
|
||||||
|
{
|
||||||
|
HSERIAL_MUTEX_LOCK();
|
||||||
|
|
||||||
|
// Zero disables timeout, thus, onReceive callback will only be called when RX FIFO reaches 120 bytes
|
||||||
|
// Any non-zero value will activate onReceive callback based on UART baudrate with about 11 bits per symbol
|
||||||
|
_rxTimeout = symbols_timeout;
|
||||||
|
if (!symbols_timeout) _onReceiveTimeout = false; // only when RX timeout is disabled, we also must disable this flag
|
||||||
|
|
||||||
|
if(_uart != NULL) uart_set_rx_timeout(_uart_nr, _rxTimeout); // Set new timeout
|
||||||
|
|
||||||
|
HSERIAL_MUTEX_UNLOCK();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HardwareSerial::eventQueueReset()
|
||||||
|
{
|
||||||
|
QueueHandle_t uartEventQueue = NULL;
|
||||||
|
if (_uart == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uartGetEventQueue(_uart, &uartEventQueue);
|
||||||
|
if (uartEventQueue != NULL) {
|
||||||
|
xQueueReset(uartEventQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HardwareSerial::_uartEventTask(void *args)
|
||||||
|
{
|
||||||
|
HardwareSerial *uart = (HardwareSerial *)args;
|
||||||
|
uart_event_t event;
|
||||||
|
QueueHandle_t uartEventQueue = NULL;
|
||||||
|
uartGetEventQueue(uart->_uart, &uartEventQueue);
|
||||||
|
if (uartEventQueue != NULL) {
|
||||||
|
for(;;) {
|
||||||
|
//Waiting for UART event.
|
||||||
|
if(xQueueReceive(uartEventQueue, (void * )&event, (portTickType)portMAX_DELAY)) {
|
||||||
|
switch(event.type) {
|
||||||
|
case UART_DATA:
|
||||||
|
if(uart->_onReceiveCB && uart->available() > 0 &&
|
||||||
|
((uart->_onReceiveTimeout && event.timeout_flag) || !uart->_onReceiveTimeout) )
|
||||||
|
uart->_onReceiveCB();
|
||||||
|
break;
|
||||||
|
case UART_FIFO_OVF:
|
||||||
|
log_w("UART%d FIFO Overflow. Consider adding Hardware Flow Control to your Application.", uart->_uart_nr);
|
||||||
|
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_FIFO_OVF_ERROR);
|
||||||
|
break;
|
||||||
|
case UART_BUFFER_FULL:
|
||||||
|
log_w("UART%d Buffer Full. Consider increasing your buffer size of your Application.", uart->_uart_nr);
|
||||||
|
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_BUFFER_FULL_ERROR);
|
||||||
|
break;
|
||||||
|
case UART_BREAK:
|
||||||
|
log_w("UART%d RX break.", uart->_uart_nr);
|
||||||
|
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_BREAK_ERROR);
|
||||||
|
break;
|
||||||
|
case UART_PARITY_ERR:
|
||||||
|
log_w("UART%d parity error.", uart->_uart_nr);
|
||||||
|
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_PARITY_ERROR);
|
||||||
|
break;
|
||||||
|
case UART_FRAME_ERR:
|
||||||
|
log_w("UART%d frame error.", uart->_uart_nr);
|
||||||
|
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_FRAME_ERROR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log_w("UART%d unknown event type %d.", uart->_uart_nr, event.type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd)
|
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd)
|
||||||
{
|
{
|
||||||
@ -115,29 +280,54 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
|
|||||||
log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1);
|
log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1);
|
||||||
return;
|
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) {
|
if(_uart) {
|
||||||
// in this case it is a begin() over a previous begin() - maybe to change baud rate
|
// in this case it is a begin() over a previous begin() - maybe to change baud rate
|
||||||
// thus do not disable debug output
|
// thus do not disable debug output
|
||||||
end(false);
|
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) {
|
if (!baud) {
|
||||||
// using baud rate as zero, forces it to try to detect the current baud rate in place
|
// using baud rate as zero, forces it to try to detect the current baud rate in place
|
||||||
uartStartDetectBaudrate(_uart);
|
uartStartDetectBaudrate(_uart);
|
||||||
@ -151,12 +341,24 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
|
|||||||
|
|
||||||
if(detectedBaudRate) {
|
if(detectedBaudRate) {
|
||||||
delay(100); // Give some time...
|
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 {
|
} else {
|
||||||
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
|
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
|
||||||
_uart = NULL;
|
_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)
|
void HardwareSerial::updateBaudRate(unsigned long baud)
|
||||||
@ -164,14 +366,21 @@ void HardwareSerial::updateBaudRate(unsigned long baud)
|
|||||||
uartSetBaudRate(_uart, baud);
|
uartSetBaudRate(_uart, baud);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HardwareSerial::end(bool turnOffDebug)
|
void HardwareSerial::end(bool fullyTerminate)
|
||||||
{
|
{
|
||||||
if(turnOffDebug && uartGetDebug() == _uart_nr) {
|
// default Serial.end() will completely disable HardwareSerial,
|
||||||
uartSetDebug(0);
|
// 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);
|
delay(10);
|
||||||
uartEnd(_uart);
|
uartEnd(_uart);
|
||||||
_uart = 0;
|
_uart = 0;
|
||||||
|
_destroyEventTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HardwareSerial::setDebugOutput(bool en)
|
void HardwareSerial::setDebugOutput(bool en)
|
||||||
@ -267,9 +476,16 @@ void HardwareSerial::setRxInvert(bool invert)
|
|||||||
uartSetRxInvert(_uart, 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) {
|
size_t HardwareSerial::setRxBufferSize(size_t new_size) {
|
||||||
@ -280,10 +496,26 @@ size_t HardwareSerial::setRxBufferSize(size_t new_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (new_size <= SOC_UART_FIFO_LEN) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_rxBufferSize = new_size;
|
_rxBufferSize = new_size;
|
||||||
return _rxBufferSize;
|
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
|
#define HardwareSerial_h
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <functional>
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
#include "esp32-hal.h"
|
#include "esp32-hal.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "HWCDC.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
|
class HardwareSerial: public Stream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HardwareSerial(int uart_nr);
|
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 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);
|
void updateBaudRate(unsigned long baud);
|
||||||
int available(void);
|
int available(void);
|
||||||
int availableForWrite(void);
|
int availableForWrite(void);
|
||||||
@ -103,13 +145,34 @@ public:
|
|||||||
void setDebugOutput(bool);
|
void setDebugOutput(bool);
|
||||||
|
|
||||||
void setRxInvert(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 setRxBufferSize(size_t new_size);
|
||||||
|
size_t setTxBufferSize(size_t new_size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int _uart_nr;
|
int _uart_nr;
|
||||||
uart_t* _uart;
|
uart_t* _uart;
|
||||||
size_t _rxBufferSize;
|
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));
|
extern void serialEventRun(void) __attribute__((weak));
|
||||||
@ -119,10 +182,10 @@ extern void serialEventRun(void) __attribute__((weak));
|
|||||||
#define ARDUINO_USB_CDC_ON_BOOT 0
|
#define ARDUINO_USB_CDC_ON_BOOT 0
|
||||||
#endif
|
#endif
|
||||||
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
|
||||||
|
#if !ARDUINO_USB_MODE
|
||||||
#include "USB.h"
|
#include "USB.h"
|
||||||
#include "USBCDC.h"
|
#include "USBCDC.h"
|
||||||
extern HardwareSerial Serial0;
|
#endif
|
||||||
#elif ARDUINO_HW_CDC_ON_BOOT
|
|
||||||
extern HardwareSerial Serial0;
|
extern HardwareSerial Serial0;
|
||||||
#else
|
#else
|
||||||
extern HardwareSerial Serial;
|
extern HardwareSerial Serial;
|
||||||
|
@ -120,3 +120,6 @@ bool IPAddress::fromString(const char *address)
|
|||||||
_address.bytes[3] = acc;
|
_address.bytes[3] = acc;
|
||||||
return true;
|
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;
|
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
|
#endif
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <MD5Builder.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)) :
|
return (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) :
|
||||||
(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)
|
void MD5Builder::begin(void)
|
||||||
{
|
{
|
||||||
memset(_buf, 0x00, 16);
|
memset(_buf, 0x00, ESP_ROM_MD5_DIGEST_LEN);
|
||||||
MD5Init(&_ctx);
|
esp_rom_md5_init(&_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MD5Builder::add(uint8_t * data, uint16_t len)
|
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)
|
void MD5Builder::addHexString(const char * data)
|
||||||
@ -82,7 +82,7 @@ bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update MD5 with buffer payload
|
// Update MD5 with buffer payload
|
||||||
MD5Update(&_ctx, buf, numBytesRead);
|
esp_rom_md5_update(&_ctx, buf, numBytesRead);
|
||||||
|
|
||||||
// update available number of bytes
|
// update available number of bytes
|
||||||
maxLengthLeft -= numBytesRead;
|
maxLengthLeft -= numBytesRead;
|
||||||
@ -94,24 +94,24 @@ bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
|
|||||||
|
|
||||||
void MD5Builder::calculate(void)
|
void MD5Builder::calculate(void)
|
||||||
{
|
{
|
||||||
MD5Final(_buf, &_ctx);
|
esp_rom_md5_final(_buf, &_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MD5Builder::getBytes(uint8_t * output)
|
void MD5Builder::getBytes(uint8_t * output)
|
||||||
{
|
{
|
||||||
memcpy(output, _buf, 16);
|
memcpy(output, _buf, ESP_ROM_MD5_DIGEST_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MD5Builder::getChars(char * output)
|
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]);
|
sprintf(output + (i * 2), "%02x", _buf[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String MD5Builder::toString(void)
|
String MD5Builder::toString(void)
|
||||||
{
|
{
|
||||||
char out[33];
|
char out[(ESP_ROM_MD5_DIGEST_LEN * 2) + 1];
|
||||||
getChars(out);
|
getChars(out);
|
||||||
return String(out);
|
return String(out);
|
||||||
}
|
}
|
||||||
|
@ -23,25 +23,13 @@
|
|||||||
#include <Stream.h>
|
#include <Stream.h>
|
||||||
|
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
#include "esp_rom_md5.h"
|
||||||
#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
|
|
||||||
|
|
||||||
class MD5Builder
|
class MD5Builder
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
struct MD5Context _ctx;
|
md5_context_t _ctx;
|
||||||
uint8_t _buf[16];
|
uint8_t _buf[ESP_ROM_MD5_DIGEST_LEN];
|
||||||
public:
|
public:
|
||||||
void begin(void);
|
void begin(void);
|
||||||
void add(uint8_t * data, uint16_t len);
|
void add(uint8_t * data, uint16_t len);
|
||||||
|
@ -108,6 +108,9 @@ public:
|
|||||||
size_t println(const Printable&);
|
size_t println(const Printable&);
|
||||||
size_t println(struct tm * timeinfo, const char * format = NULL);
|
size_t println(struct tm * timeinfo, const char * format = NULL);
|
||||||
size_t println(void);
|
size_t println(void);
|
||||||
|
|
||||||
|
virtual void flush() { /* Empty implementation for backward compatibility */ }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,7 +48,6 @@ public:
|
|||||||
virtual int available() = 0;
|
virtual int available() = 0;
|
||||||
virtual int read() = 0;
|
virtual int read() = 0;
|
||||||
virtual int peek() = 0;
|
virtual int peek() = 0;
|
||||||
virtual void flush() = 0;
|
|
||||||
|
|
||||||
Stream():_startMillis(0)
|
Stream():_startMillis(0)
|
||||||
{
|
{
|
||||||
|
131
cores/esp32/Tone.cpp
Normal file
131
cores/esp32/Tone.cpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "esp32-hal-ledc.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
|
static TaskHandle_t _tone_task = NULL;
|
||||||
|
static QueueHandle_t _tone_queue = NULL;
|
||||||
|
static uint8_t _channel = 0;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
TONE_START,
|
||||||
|
TONE_END,
|
||||||
|
TONE_SET_CHANNEL
|
||||||
|
} tone_cmd_t;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
tone_cmd_t tone_cmd;
|
||||||
|
uint8_t pin;
|
||||||
|
unsigned int frequency;
|
||||||
|
unsigned long duration;
|
||||||
|
uint8_t channel;
|
||||||
|
} tone_msg_t;
|
||||||
|
|
||||||
|
static void tone_task(void*){
|
||||||
|
tone_msg_t tone_msg;
|
||||||
|
while(1){
|
||||||
|
xQueueReceive(_tone_queue, &tone_msg, portMAX_DELAY);
|
||||||
|
switch(tone_msg.tone_cmd){
|
||||||
|
case TONE_START:
|
||||||
|
log_d("Task received from queue TONE_START: _pin=%d, frequency=%u Hz, duration=%u ms", tone_msg.pin, tone_msg.frequency, tone_msg.duration);
|
||||||
|
|
||||||
|
log_d("Setup LED controll on channel %d", _channel);
|
||||||
|
// ledcSetup(_channel, tone_msg.frequency, 11);
|
||||||
|
// ledcAttachPin(tone_msg.pin, _channel);
|
||||||
|
// ledcWrite(_channel, 1024);
|
||||||
|
ledcWriteTone(_channel, tone_msg.frequency);
|
||||||
|
ledcAttachPin(tone_msg.pin, _channel);
|
||||||
|
|
||||||
|
if(tone_msg.duration){
|
||||||
|
delay(tone_msg.duration);
|
||||||
|
ledcDetachPin(tone_msg.pin);
|
||||||
|
ledcWriteTone(_channel, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TONE_END:
|
||||||
|
log_d("Task received from queue TONE_END: pin=%d", tone_msg.pin);
|
||||||
|
ledcDetachPin(tone_msg.pin);
|
||||||
|
ledcWriteTone(_channel, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TONE_SET_CHANNEL:
|
||||||
|
log_d("Task received from queue TONE_SET_CHANNEL: channel=%d", tone_msg.channel);
|
||||||
|
_channel = tone_msg.channel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: ; // do nothing
|
||||||
|
} // switch
|
||||||
|
} // infinite loop
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tone_init(){
|
||||||
|
if(_tone_queue == NULL){
|
||||||
|
log_v("Creating tone queue");
|
||||||
|
_tone_queue = xQueueCreate(128, sizeof(tone_msg_t));
|
||||||
|
if(_tone_queue == NULL){
|
||||||
|
log_e("Could not create tone queue");
|
||||||
|
return 0; // ERR
|
||||||
|
}
|
||||||
|
log_v("Tone queue created");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_tone_task == NULL){
|
||||||
|
log_v("Creating tone task");
|
||||||
|
xTaskCreate(
|
||||||
|
tone_task, // Function to implement the task
|
||||||
|
"toneTask", // Name of the task
|
||||||
|
3500, // Stack size in words
|
||||||
|
NULL, // Task input parameter
|
||||||
|
1, // Priority of the task
|
||||||
|
&_tone_task // Task handle.
|
||||||
|
);
|
||||||
|
if(_tone_task == NULL){
|
||||||
|
log_e("Could not create tone task");
|
||||||
|
return 0; // ERR
|
||||||
|
}
|
||||||
|
log_v("Tone task created");
|
||||||
|
}
|
||||||
|
return 1; // OK
|
||||||
|
}
|
||||||
|
|
||||||
|
void setToneChannel(uint8_t channel){
|
||||||
|
log_d("channel=%d", channel);
|
||||||
|
if(tone_init()){
|
||||||
|
tone_msg_t tone_msg = {
|
||||||
|
.tone_cmd = TONE_SET_CHANNEL,
|
||||||
|
.channel = channel
|
||||||
|
};
|
||||||
|
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void noTone(uint8_t _pin){
|
||||||
|
log_d("noTone was called");
|
||||||
|
if(tone_init()){
|
||||||
|
tone_msg_t tone_msg = {
|
||||||
|
.tone_cmd = TONE_END,
|
||||||
|
.pin = _pin
|
||||||
|
};
|
||||||
|
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parameters:
|
||||||
|
// _pin - pin number which will output the signal
|
||||||
|
// frequency - PWM frequency in Hz
|
||||||
|
// duration - time in ms - how long will the signal be outputted.
|
||||||
|
// If not provided, or 0 you must manually call noTone to end output
|
||||||
|
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration){
|
||||||
|
log_d("_pin=%d, frequency=%u Hz, duration=%u ms", _pin, frequency, duration);
|
||||||
|
if(tone_init()){
|
||||||
|
tone_msg_t tone_msg = {
|
||||||
|
.tone_cmd = TONE_START,
|
||||||
|
.pin = _pin,
|
||||||
|
.frequency = frequency,
|
||||||
|
.duration = duration
|
||||||
|
};
|
||||||
|
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
#include "esp32-hal.h"
|
#include "esp32-hal.h"
|
||||||
#include "esp32-hal-tinyusb.h"
|
#include "esp32-hal-tinyusb.h"
|
||||||
#include "common/tusb_common.h"
|
#include "common/tusb_common.h"
|
||||||
|
#include "StreamString.h"
|
||||||
|
|
||||||
#ifndef USB_VID
|
#ifndef USB_VID
|
||||||
#define USB_VID USB_ESPRESSIF_VID
|
#define USB_VID USB_ESPRESSIF_VID
|
||||||
@ -33,8 +34,12 @@
|
|||||||
#define USB_PRODUCT ARDUINO_BOARD
|
#define USB_PRODUCT ARDUINO_BOARD
|
||||||
#endif
|
#endif
|
||||||
#ifndef USB_SERIAL
|
#ifndef USB_SERIAL
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#define USB_SERIAL "__MAC__"
|
||||||
|
#else
|
||||||
#define USB_SERIAL "0"
|
#define USB_SERIAL "0"
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#ifndef USB_WEBUSB_ENABLED
|
#ifndef USB_WEBUSB_ENABLED
|
||||||
#define USB_WEBUSB_ENABLED false
|
#define USB_WEBUSB_ENABLED false
|
||||||
#endif
|
#endif
|
||||||
@ -155,6 +160,15 @@ ESPUSB::~ESPUSB(){
|
|||||||
|
|
||||||
bool ESPUSB::begin(){
|
bool ESPUSB::begin(){
|
||||||
if(!_started){
|
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 = {
|
tinyusb_device_config_t tinyusb_device_config = {
|
||||||
.vid = vid,
|
.vid = vid,
|
||||||
.pid = pid,
|
.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){
|
size_t USBCDC::setRxBufferSize(size_t rx_queue_len){
|
||||||
if(rx_queue){
|
size_t currentQueueSize = rx_queue ?
|
||||||
if(!rx_queue_len){
|
uxQueueSpacesAvailable(rx_queue) + uxQueueMessagesWaiting(rx_queue) : 0;
|
||||||
vQueueDelete(rx_queue);
|
|
||||||
rx_queue = NULL;
|
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;
|
return rx_queue_len;
|
||||||
}
|
}
|
||||||
@ -133,7 +159,8 @@ void USBCDC::begin(unsigned long baud)
|
|||||||
if(tx_lock == NULL) {
|
if(tx_lock == NULL) {
|
||||||
tx_lock = xSemaphoreCreateMutex();
|
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;
|
devices[itf] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +171,7 @@ void USBCDC::end()
|
|||||||
setRxBufferSize(0);
|
setRxBufferSize(0);
|
||||||
if(tx_lock != NULL) {
|
if(tx_lock != NULL) {
|
||||||
vSemaphoreDelete(tx_lock);
|
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(){
|
void USBCDC::_onRX(){
|
||||||
|
arduino_usb_cdc_event_data_t p;
|
||||||
uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE+1];
|
uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE+1];
|
||||||
uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE);
|
uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE);
|
||||||
for(uint32_t i=0; i<count; i++){
|
for(uint32_t i=0; i<count; i++){
|
||||||
if(rx_queue == NULL || !xQueueSend(rx_queue, buf+i, 0)){
|
if(rx_queue == NULL || !xQueueSend(rx_queue, buf+i, 10)) {
|
||||||
return;
|
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;
|
if (count) {
|
||||||
p.rx.len = 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);
|
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(){
|
void USBCDC::_onTX(){
|
||||||
@ -412,7 +446,7 @@ USBCDC::operator bool() const
|
|||||||
return connected;
|
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);
|
USBCDC Serial(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ typedef enum {
|
|||||||
ARDUINO_USB_CDC_LINE_CODING_EVENT,
|
ARDUINO_USB_CDC_LINE_CODING_EVENT,
|
||||||
ARDUINO_USB_CDC_RX_EVENT,
|
ARDUINO_USB_CDC_RX_EVENT,
|
||||||
ARDUINO_USB_CDC_TX_EVENT,
|
ARDUINO_USB_CDC_TX_EVENT,
|
||||||
|
ARDUINO_USB_CDC_RX_OVERFLOW_EVENT,
|
||||||
ARDUINO_USB_CDC_MAX_EVENT,
|
ARDUINO_USB_CDC_MAX_EVENT,
|
||||||
} arduino_usb_cdc_event_t;
|
} arduino_usb_cdc_event_t;
|
||||||
|
|
||||||
@ -50,6 +51,9 @@ typedef union {
|
|||||||
struct {
|
struct {
|
||||||
size_t len;
|
size_t len;
|
||||||
} rx;
|
} rx;
|
||||||
|
struct {
|
||||||
|
size_t dropped_bytes;
|
||||||
|
} rx_overflow;
|
||||||
} arduino_usb_cdc_event_data_t;
|
} arduino_usb_cdc_event_data_t;
|
||||||
|
|
||||||
class USBCDC: public Stream
|
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;
|
extern USBCDC Serial;
|
||||||
#endif
|
#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) {
|
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 run = in_max - in_min;
|
||||||
const long divisor = in_max - in_min;
|
if(run == 0){
|
||||||
const long delta = x - in_min;
|
log_e("map(): Invalid input range, min == max");
|
||||||
if(divisor == 0){
|
return -1; // AVR returns -1, SAM returns 0
|
||||||
log_e("Invalid map 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)
|
uint16_t makeWord(uint16_t w)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "WString.h"
|
#include "WString.h"
|
||||||
#include "stdlib_noniso.h"
|
#include "stdlib_noniso.h"
|
||||||
|
#include "esp32-hal-log.h"
|
||||||
|
|
||||||
/*********************************************/
|
/*********************************************/
|
||||||
/* Constructors */
|
/* Constructors */
|
||||||
@ -112,16 +113,28 @@ String::String(unsigned long value, unsigned char base) {
|
|||||||
*this = buf;
|
*this = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(float value, unsigned char decimalPlaces) {
|
String::String(float value, unsigned int decimalPlaces) {
|
||||||
init();
|
init();
|
||||||
char buf[33];
|
char *buf = (char*)malloc(decimalPlaces + 42);
|
||||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
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();
|
init();
|
||||||
char buf[33];
|
char *buf = (char*)malloc(decimalPlaces + 312);
|
||||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
if (buf) {
|
||||||
|
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
*this = "nan";
|
||||||
|
log_e("No enought memory for the operation.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String::~String() {
|
String::~String() {
|
||||||
@ -761,8 +774,10 @@ void String::replace(const String& find, const String& replace) {
|
|||||||
}
|
}
|
||||||
if(size == len())
|
if(size == len())
|
||||||
return;
|
return;
|
||||||
if(size > capacity() && !changeBuffer(size))
|
if(size > capacity() && !changeBuffer(size)) {
|
||||||
return; // XXX: tell user!
|
log_w("String.Replace() Insufficient space to replace string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
int index = len() - 1;
|
int index = len() - 1;
|
||||||
while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
||||||
readFrom = wbuffer() + index + find.len();
|
readFrom = wbuffer() + index + find.len();
|
||||||
|
@ -71,8 +71,8 @@ class String {
|
|||||||
explicit String(unsigned int, unsigned char base = 10);
|
explicit String(unsigned int, unsigned char base = 10);
|
||||||
explicit String(long, unsigned char base = 10);
|
explicit String(long, unsigned char base = 10);
|
||||||
explicit String(unsigned long, unsigned char base = 10);
|
explicit String(unsigned long, unsigned char base = 10);
|
||||||
explicit String(float, unsigned char decimalPlaces = 2);
|
explicit String(float, unsigned int decimalPlaces = 2);
|
||||||
explicit String(double, unsigned char decimalPlaces = 2);
|
explicit String(double, unsigned int decimalPlaces = 2);
|
||||||
~String(void);
|
~String(void);
|
||||||
|
|
||||||
// memory management
|
// memory management
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
|
|
||||||
cbuf *next;
|
cbuf *next;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
inline char* wrap_if_bufend(char* ptr) const
|
inline char* wrap_if_bufend(char* ptr) const
|
||||||
{
|
{
|
||||||
return (ptr == _bufend) ? _buf : ptr;
|
return (ptr == _bufend) ? _buf : ptr;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
#include "esp32/rom/ets_sys.h"
|
#include "esp32/rom/ets_sys.h"
|
||||||
#include "esp_intr_alloc.h"
|
#include "esp_intr_alloc.h"
|
||||||
|
#include "soc/dac_channel.h"
|
||||||
#define DEFAULT_VREF 1100
|
#define DEFAULT_VREF 1100
|
||||||
static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL};
|
static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL};
|
||||||
static uint16_t __analogVRef = 0;
|
static uint16_t __analogVRef = 0;
|
||||||
@ -35,6 +36,11 @@ static uint8_t __analogVRefPin = 0;
|
|||||||
#include "esp32s2/rom/ets_sys.h"
|
#include "esp32s2/rom/ets_sys.h"
|
||||||
#include "soc/sens_reg.h"
|
#include "soc/sens_reg.h"
|
||||||
#include "soc/rtc_io_reg.h"
|
#include "soc/rtc_io_reg.h"
|
||||||
|
#include "soc/dac_channel.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#include "esp32s3/rom/ets_sys.h"
|
||||||
|
#include "soc/sens_reg.h"
|
||||||
|
#include "soc/rtc_io_reg.h"
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#include "esp32c3/rom/ets_sys.h"
|
#include "esp32c3/rom/ets_sys.h"
|
||||||
#else
|
#else
|
||||||
@ -141,10 +147,10 @@ bool __adcAttachPin(uint8_t pin){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
#if SOC_DAC_SUPPORTED
|
||||||
else if(pin == 25){
|
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
|
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
|
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);//stop dac2
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
#include "freertos/xtensa_timer.h"
|
#include "freertos/xtensa_timer.h"
|
||||||
#include "esp32s2/rom/rtc.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
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#include "esp32c3/rom/rtc.h"
|
#include "esp32c3/rom/rtc.h"
|
||||||
#else
|
#else
|
||||||
@ -144,7 +147,7 @@ bool removeApbChangeCallback(void * arg, apb_change_cb_t cb){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t calculateApb(rtc_cpu_freq_config_t * conf){
|
static uint32_t calculateApb(rtc_cpu_freq_config_t * conf){
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
return APB_CLK_FREQ;
|
return APB_CLK_FREQ;
|
||||||
#else
|
#else
|
||||||
if(conf->freq_mhz >= 80){
|
if(conf->freq_mhz >= 80){
|
||||||
@ -228,6 +231,8 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
|
|||||||
//Update FreeRTOS Tick Divisor
|
//Update FreeRTOS Tick Divisor
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3
|
||||||
|
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
|
||||||
#else
|
#else
|
||||||
uint32_t fcpu = (conf.freq_mhz >= 80)?(conf.freq_mhz * MHZ):(apb);
|
uint32_t fcpu = (conf.freq_mhz >= 80)?(conf.freq_mhz * MHZ):(apb);
|
||||||
_xt_tick_divisor = fcpu / XT_TICK_PER_SEC;
|
_xt_tick_divisor = fcpu / XT_TICK_PER_SEC;
|
||||||
|
@ -13,51 +13,37 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "esp32-hal.h"
|
#include "esp32-hal.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#ifndef SOC_DAC_SUPPORTED
|
||||||
#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
|
|
||||||
#define NODAC
|
#define NODAC
|
||||||
#else
|
#else
|
||||||
#error Target CONFIG_IDF_TARGET is not supported
|
#include "soc/dac_channel.h"
|
||||||
#endif
|
#include "driver/dac_common.h"
|
||||||
|
|
||||||
#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"
|
|
||||||
|
|
||||||
void ARDUINO_ISR_ATTR __dacWrite(uint8_t pin, uint8_t value)
|
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
|
return;//not dac pin
|
||||||
}
|
}
|
||||||
pinMode(pin, ANALOG);
|
|
||||||
uint8_t channel = pin - DAC1;
|
uint8_t channel = pin - DAC_CHANNEL_1_GPIO_NUM;
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
dac_output_enable(channel);
|
||||||
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
|
dac_output_voltage(channel, value);
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
|
||||||
SENS.sar_dac_ctrl1.dac_clkgate_en = 1;
|
}
|
||||||
#endif
|
|
||||||
RTCIO.pad_dac[channel].dac_xpd_force = 1;
|
void ARDUINO_ISR_ATTR __dacDisable(uint8_t pin)
|
||||||
RTCIO.pad_dac[channel].xpd_dac = 1;
|
{
|
||||||
if (channel == 0) {
|
if(pin < DAC_CHANNEL_1_GPIO_NUM || pin > DAC_CHANNEL_2_GPIO_NUM){
|
||||||
SENS.sar_dac_ctrl2.dac_cw_en1 = 0;
|
return;//not dac pin
|
||||||
} else if (channel == 1) {
|
|
||||||
SENS.sar_dac_ctrl2.dac_cw_en2 = 0;
|
|
||||||
}
|
}
|
||||||
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 dacWrite(uint8_t pin, uint8_t value) __attribute__ ((weak, alias("__dacWrite")));
|
||||||
|
extern void dacDisable(uint8_t pin) __attribute__ ((weak, alias("__dacDisable")));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,6 +28,7 @@ extern "C" {
|
|||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
void dacWrite(uint8_t pin, uint8_t value);
|
void dacWrite(uint8_t pin, uint8_t value);
|
||||||
|
void dacDisable(uint8_t pin);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -13,138 +13,70 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "esp32-hal-gpio.h"
|
#include "esp32-hal-gpio.h"
|
||||||
#include "pins_arduino.h"
|
#include "hal/gpio_hal.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "soc/soc_caps.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"
|
|
||||||
|
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
// It fixes lack of pin definition for S3 and for any future SoC
|
||||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
// this function works for ESP32, ESP32-S2 and ESP32-S3 - including the C3, it will return -1 for any pin
|
||||||
#include "esp32/rom/ets_sys.h"
|
#if SOC_TOUCH_SENSOR_NUM > 0
|
||||||
#include "esp32/rom/gpio.h"
|
#include "soc/touch_sensor_periph.h"
|
||||||
#include "esp_intr_alloc.h"
|
|
||||||
#include "soc/rtc_io_reg.h"
|
int8_t digitalPinToTouchChannel(uint8_t pin)
|
||||||
#define GPIO_FUNC 2
|
{
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
int8_t ret = -1;
|
||||||
#include "esp32s2/rom/ets_sys.h"
|
if (pin < SOC_GPIO_PIN_COUNT) {
|
||||||
#include "esp32s2/rom/gpio.h"
|
for (uint8_t i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||||
#include "esp_intr_alloc.h"
|
if (touch_sensor_channel_io_map[i] == pin) {
|
||||||
#include "soc/periph_defs.h"
|
ret = i;
|
||||||
#include "soc/rtc_io_reg.h"
|
break;
|
||||||
#define GPIO_FUNC 1
|
}
|
||||||
#else
|
}
|
||||||
#define USE_ESP_IDF_GPIO 1
|
}
|
||||||
#endif
|
return ret;
|
||||||
#else // ESP32 Before IDF 4.0
|
}
|
||||||
#include "rom/ets_sys.h"
|
#else
|
||||||
#include "rom/gpio.h"
|
// No Touch Sensor available
|
||||||
#include "esp_intr.h"
|
int8_t digitalPinToTouchChannel(uint8_t pin)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#ifdef SOC_ADC_SUPPORTED
|
||||||
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};
|
#include "soc/adc_periph.h"
|
||||||
#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
|
|
||||||
|
|
||||||
const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT]={
|
int8_t digitalPinToAnalogChannel(uint8_t pin)
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
{
|
||||||
{0x44, 11, 11, 1},
|
uint8_t channel = 0;
|
||||||
{0x88, -1, -1, -1},
|
if (pin < SOC_GPIO_PIN_COUNT) {
|
||||||
{0x40, 12, 12, 2},
|
for (uint8_t i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
|
||||||
{0x84, -1, -1, -1},
|
for (uint8_t j = 0; j < SOC_ADC_MAX_CHANNEL_NUM; j++) {
|
||||||
{0x48, 10, 10, 0},
|
if (adc_channel_io_map[i][j] == pin) {
|
||||||
{0x6c, -1, -1, -1},
|
return channel;
|
||||||
{0x60, -1, -1, -1},
|
}
|
||||||
{0x64, -1, -1, -1},
|
channel++;
|
||||||
{0x68, -1, -1, -1},
|
}
|
||||||
{0x54, -1, -1, -1},
|
}
|
||||||
{0x58, -1, -1, -1},
|
}
|
||||||
{0x5c, -1, -1, -1},
|
return -1;
|
||||||
{0x34, 15, 15, 5},
|
}
|
||||||
{0x38, 14, 14, 4},
|
|
||||||
{0x30, 16, 16, 6},
|
int8_t analogChannelToDigitalPin(uint8_t channel)
|
||||||
{0x3c, 13, 13, 3},
|
{
|
||||||
{0x4c, -1, -1, -1},
|
if (channel >= (SOC_ADC_PERIPH_NUM * SOC_ADC_MAX_CHANNEL_NUM)) {
|
||||||
{0x50, -1, -1, -1},
|
return -1;
|
||||||
{0x70, -1, -1, -1},
|
}
|
||||||
{0x74, -1, -1, -1},
|
uint8_t adc_unit = (channel / SOC_ADC_MAX_CHANNEL_NUM);
|
||||||
{0x78, -1, -1, -1},
|
uint8_t adc_chan = (channel % SOC_ADC_MAX_CHANNEL_NUM);
|
||||||
{0x7c, -1, -1, -1},
|
return adc_channel_io_map[adc_unit][adc_chan];
|
||||||
{0x80, -1, -1, -1},
|
}
|
||||||
{0x8c, -1, -1, -1},
|
#else
|
||||||
{0, -1, -1, -1},
|
// No Analog channels availible
|
||||||
{0x24, 6, 18, -1}, //DAC1
|
int8_t analogChannelToDigitalPin(uint8_t channel)
|
||||||
{0x28, 7, 19, -1}, //DAC2
|
{
|
||||||
{0x2c, 17, 17, 7},
|
return -1;
|
||||||
{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}
|
|
||||||
#endif
|
#endif
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*voidFuncPtr)(void);
|
typedef void (*voidFuncPtr)(void);
|
||||||
typedef void (*voidFuncPtrArg)(void*);
|
typedef void (*voidFuncPtrArg)(void*);
|
||||||
@ -159,8 +91,8 @@ static InterruptHandle_t __pinInterruptHandlers[SOC_GPIO_PIN_COUNT] = {0,};
|
|||||||
|
|
||||||
extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
|
extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
|
||||||
{
|
{
|
||||||
#if USE_ESP_IDF_GPIO
|
|
||||||
if (!GPIO_IS_VALID_GPIO(pin)) {
|
if (!GPIO_IS_VALID_GPIO(pin)) {
|
||||||
|
log_e("Invalid pin selected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gpio_config_t conf = {
|
gpio_config_t conf = {
|
||||||
@ -182,157 +114,23 @@ extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
|
|||||||
conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gpio_config(&conf);
|
if(gpio_config(&conf) != ESP_OK)
|
||||||
|
{
|
||||||
if(mode == SPECIAL){
|
log_e("GPIO config failed");
|
||||||
#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)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t rtc_io = esp32_gpioMux[pin].rtc;
|
|
||||||
uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
|
|
||||||
if(mode == ANALOG) {
|
|
||||||
if(!rtc_reg) {
|
|
||||||
return;//not rtc pin
|
|
||||||
}
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
|
||||||
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
|
|
||||||
#endif
|
|
||||||
SET_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, (rtc_io_desc[rtc_io].mux));
|
|
||||||
SET_PERI_REG_BITS(rtc_io_desc[rtc_io].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0, rtc_io_desc[rtc_io].func);
|
|
||||||
|
|
||||||
RTCIO.pin[rtc_io].pad_driver = 0;//OD = 1
|
|
||||||
RTCIO.enable_w1tc.w1tc = (1U << rtc_io);
|
|
||||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].ie);
|
|
||||||
|
|
||||||
if (rtc_io_desc[rtc_io].pullup) {
|
|
||||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pullup);
|
|
||||||
}
|
|
||||||
if (rtc_io_desc[rtc_io].pulldown) {
|
|
||||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pulldown);
|
|
||||||
}
|
|
||||||
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = ((uint32_t)GPIO_FUNC << MCU_SEL_S) | ((uint32_t)2 << FUN_DRV_S) | FUN_IE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//RTC pins PULL settings
|
|
||||||
if(rtc_reg) {
|
|
||||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
|
|
||||||
if(mode & PULLUP) {
|
|
||||||
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[rtc_io].pullup) & ~(rtc_io_desc[rtc_io].pulldown);
|
|
||||||
} else if(mode & PULLDOWN) {
|
|
||||||
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[rtc_io].pulldown) & ~(rtc_io_desc[rtc_io].pullup);
|
|
||||||
} else {
|
|
||||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t pinFunction = 0, pinControl = 0;
|
|
||||||
|
|
||||||
if(mode & INPUT) {
|
|
||||||
if(pin < 32) {
|
|
||||||
GPIO.enable_w1tc = ((uint32_t)1 << pin);
|
|
||||||
} else {
|
|
||||||
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
|
||||||
}
|
|
||||||
} else if(mode & OUTPUT) {
|
|
||||||
if(pin >= NUM_OUPUT_PINS){
|
|
||||||
return;
|
|
||||||
} else if(pin < 32) {
|
|
||||||
GPIO.enable_w1ts = ((uint32_t)1 << pin);
|
|
||||||
} else {
|
|
||||||
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mode & PULLUP) {
|
|
||||||
pinFunction |= FUN_PU;
|
|
||||||
} else if(mode & PULLDOWN) {
|
|
||||||
pinFunction |= FUN_PD;
|
|
||||||
}
|
|
||||||
|
|
||||||
pinFunction |= ((uint32_t)2 << FUN_DRV_S);//what are the drivers?
|
|
||||||
pinFunction |= FUN_IE;//input enable but required for output as well?
|
|
||||||
|
|
||||||
if(mode & (INPUT | OUTPUT)) {
|
|
||||||
pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
|
|
||||||
} else if(mode == SPECIAL) {
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
pinFunction |= ((uint32_t)(((pin)==RX||(pin)==TX)?0:1) << MCU_SEL_S);
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
|
||||||
pinFunction |= ((uint32_t)(((pin)==RX||(pin)==TX)?0:2) << MCU_SEL_S);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
pinFunction |= ((uint32_t)(mode >> 5) << MCU_SEL_S);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
|
|
||||||
|
|
||||||
if(mode & OPEN_DRAIN) {
|
|
||||||
pinControl = (1 << GPIO_PIN0_PAD_DRIVER_S);
|
|
||||||
}
|
|
||||||
|
|
||||||
GPIO.pin[pin].val = pinControl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val)
|
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);
|
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)
|
extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin)
|
||||||
{
|
{
|
||||||
#if USE_ESP_IDF_GPIO
|
|
||||||
return gpio_get_level((gpio_num_t)pin);
|
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) {
|
static void ARDUINO_ISR_ATTR __onPinInterrupt(void * arg) {
|
||||||
InterruptHandle_t * isr = (InterruptHandle_t*)arg;
|
InterruptHandle_t * isr = (InterruptHandle_t*)arg;
|
||||||
if(isr->fn) {
|
if(isr->fn) {
|
||||||
@ -343,49 +141,6 @@ static void ARDUINO_ISR_ATTR __onPinInterrupt(void * arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static intr_handle_t gpio_intr_handle = NULL;
|
|
||||||
|
|
||||||
static void ARDUINO_ISR_ATTR __onPinInterrupt()
|
|
||||||
{
|
|
||||||
uint32_t gpio_intr_status_l=0;
|
|
||||||
uint32_t gpio_intr_status_h=0;
|
|
||||||
|
|
||||||
gpio_intr_status_l = GPIO.status;
|
|
||||||
gpio_intr_status_h = GPIO.status1.val;
|
|
||||||
GPIO.status_w1tc = gpio_intr_status_l;//Clear intr for gpio0-gpio31
|
|
||||||
GPIO.status1_w1tc.val = gpio_intr_status_h;//Clear intr for gpio32-39
|
|
||||||
|
|
||||||
uint8_t pin=0;
|
|
||||||
if(gpio_intr_status_l) {
|
|
||||||
do {
|
|
||||||
if(gpio_intr_status_l & ((uint32_t)1 << pin)) {
|
|
||||||
if(__pinInterruptHandlers[pin].fn) {
|
|
||||||
if(__pinInterruptHandlers[pin].arg){
|
|
||||||
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
|
|
||||||
} else {
|
|
||||||
__pinInterruptHandlers[pin].fn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(++pin<32);
|
|
||||||
}
|
|
||||||
if(gpio_intr_status_h) {
|
|
||||||
pin=32;
|
|
||||||
do {
|
|
||||||
if(gpio_intr_status_h & ((uint32_t)1 << (pin - 32))) {
|
|
||||||
if(__pinInterruptHandlers[pin].fn) {
|
|
||||||
if(__pinInterruptHandlers[pin].arg){
|
|
||||||
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
|
|
||||||
} else {
|
|
||||||
__pinInterruptHandlers[pin].fn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(++pin<GPIO_PIN_COUNT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void cleanupFunctional(void* arg);
|
extern void cleanupFunctional(void* arg);
|
||||||
|
|
||||||
@ -394,13 +149,8 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc,
|
|||||||
static bool interrupt_initialized = false;
|
static bool interrupt_initialized = false;
|
||||||
|
|
||||||
if(!interrupt_initialized) {
|
if(!interrupt_initialized) {
|
||||||
#if USE_ESP_IDF_GPIO
|
|
||||||
esp_err_t err = gpio_install_isr_service((int)ARDUINO_ISR_FLAG);
|
esp_err_t err = gpio_install_isr_service((int)ARDUINO_ISR_FLAG);
|
||||||
interrupt_initialized = (err == ESP_OK) || (err == ESP_ERR_INVALID_STATE);
|
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) {
|
if(!interrupt_initialized) {
|
||||||
log_e("GPIO ISR Service Failed To Start");
|
log_e("GPIO ISR Service Failed To Start");
|
||||||
@ -416,27 +166,18 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc,
|
|||||||
__pinInterruptHandlers[pin].arg = arg;
|
__pinInterruptHandlers[pin].arg = arg;
|
||||||
__pinInterruptHandlers[pin].functional = functional;
|
__pinInterruptHandlers[pin].functional = functional;
|
||||||
|
|
||||||
#if USE_ESP_IDF_GPIO
|
|
||||||
gpio_set_intr_type((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
|
gpio_set_intr_type((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
|
||||||
if(intr_type & 0x8){
|
if(intr_type & 0x8){
|
||||||
gpio_wakeup_enable((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
|
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_isr_handler_add((gpio_num_t)pin, __onPinInterrupt, &__pinInterruptHandlers[pin]);
|
||||||
gpio_intr_enable((gpio_num_t)pin);
|
|
||||||
#else
|
|
||||||
esp_intr_disable(gpio_intr_handle);
|
//FIX interrupts on peripherals outputs (eg. LEDC,...)
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
//Enable input in GPIO register
|
||||||
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU
|
gpio_hal_context_t gpiohal;
|
||||||
#endif
|
gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
|
||||||
GPIO.pin[pin].int_ena = 1;
|
gpio_hal_input_enable(&gpiohal, pin);
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type)
|
extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type)
|
||||||
@ -450,13 +191,9 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
|
|||||||
|
|
||||||
extern void __detachInterrupt(uint8_t pin)
|
extern void __detachInterrupt(uint8_t pin)
|
||||||
{
|
{
|
||||||
#if USE_ESP_IDF_GPIO
|
gpio_isr_handler_remove((gpio_num_t)pin); //remove handle and disable isr for pin
|
||||||
gpio_intr_disable((gpio_num_t)pin);
|
|
||||||
gpio_isr_handler_remove((gpio_num_t)pin);
|
|
||||||
gpio_wakeup_disable((gpio_num_t)pin);
|
gpio_wakeup_disable((gpio_num_t)pin);
|
||||||
#else
|
|
||||||
esp_intr_disable(gpio_intr_handle);
|
|
||||||
#endif
|
|
||||||
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg)
|
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg)
|
||||||
{
|
{
|
||||||
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
||||||
@ -465,13 +202,7 @@ extern void __detachInterrupt(uint8_t pin)
|
|||||||
__pinInterruptHandlers[pin].arg = NULL;
|
__pinInterruptHandlers[pin].arg = NULL;
|
||||||
__pinInterruptHandlers[pin].functional = false;
|
__pinInterruptHandlers[pin].functional = false;
|
||||||
|
|
||||||
#if USE_ESP_IDF_GPIO
|
|
||||||
gpio_set_intr_type((gpio_num_t)pin, GPIO_INTR_DISABLE);
|
gpio_set_intr_type((gpio_num_t)pin, GPIO_INTR_DISABLE);
|
||||||
#else
|
|
||||||
GPIO.pin[pin].int_ena = 0;
|
|
||||||
GPIO.pin[pin].int_type = 0;
|
|
||||||
esp_intr_enable(gpio_intr_handle);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -481,4 +212,3 @@ extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")
|
|||||||
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
|
extern void 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 attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
|
||||||
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
|
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
|
||||||
|
|
||||||
|
@ -42,20 +42,15 @@ extern "C" {
|
|||||||
|
|
||||||
//GPIO FUNCTIONS
|
//GPIO FUNCTIONS
|
||||||
#define INPUT 0x01
|
#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 PULLUP 0x04
|
||||||
#define INPUT_PULLUP 0x05
|
#define INPUT_PULLUP 0x05
|
||||||
#define PULLDOWN 0x08
|
#define PULLDOWN 0x08
|
||||||
#define INPUT_PULLDOWN 0x09
|
#define INPUT_PULLDOWN 0x09
|
||||||
#define OPEN_DRAIN 0x10
|
#define OPEN_DRAIN 0x10
|
||||||
#define OUTPUT_OPEN_DRAIN 0x12
|
#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
|
#define ANALOG 0xC0
|
||||||
|
|
||||||
//Interrupt Modes
|
//Interrupt Modes
|
||||||
@ -68,22 +63,11 @@ extern "C" {
|
|||||||
#define ONLOW_WE 0x0C
|
#define ONLOW_WE 0x0C
|
||||||
#define ONHIGH_WE 0x0D
|
#define ONHIGH_WE 0x0D
|
||||||
|
|
||||||
typedef struct {
|
#define digitalPinIsValid(pin) GPIO_IS_VALID_GPIO(pin)
|
||||||
uint8_t reg; /*!< GPIO register offset from DR_REG_IO_MUX_BASE */
|
#define digitalPinCanOutput(pin) GPIO_IS_VALID_OUTPUT_GPIO(pin)
|
||||||
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;
|
|
||||||
|
|
||||||
extern const esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT];
|
#define digitalPinToRtcPin(pin) ((RTC_GPIO_IS_VALID_GPIO(pin))?rtc_io_number_get(pin):-1)
|
||||||
extern const int8_t esp32_adc2gpio[20];
|
#define digitalPinToDacChannel(pin) (((pin) == DAC_CHANNEL_1_GPIO_NUM)?0:((pin) == DAC_CHANNEL_2_GPIO_NUM)?1:-1)
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
void pinMode(uint8_t pin, uint8_t mode);
|
void pinMode(uint8_t pin, uint8_t mode);
|
||||||
void digitalWrite(uint8_t pin, uint8_t val);
|
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 attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode);
|
||||||
void detachInterrupt(uint8_t pin);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
22
cores/esp32/esp32-hal-i2c-slave.c
Executable file → Normal file
22
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)
|
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;
|
return hw->sr.stretch_cause;
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
return hw->status_reg.stretch_cause;
|
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)
|
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;
|
return hw->sr.slave_addressed;
|
||||||
#else
|
#else
|
||||||
return hw->status_reg.slave_addressed;
|
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
|
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;
|
return hw->sr.slave_rw;
|
||||||
#else
|
#else
|
||||||
return hw->status_reg.slave_rw;
|
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_slave_init(i2c->dev);
|
||||||
i2c_ll_set_fifo_mode(i2c->dev, true);
|
i2c_ll_set_fifo_mode(i2c->dev, true);
|
||||||
i2c_ll_set_slave_addr(i2c->dev, slaveID, false);
|
i2c_ll_set_slave_addr(i2c->dev, slaveID, false);
|
||||||
i2c_ll_set_tout(i2c->dev, 32000);
|
i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT);
|
||||||
i2c_slave_set_frequency(i2c, frequency);
|
i2c_slave_set_frequency(i2c, frequency);
|
||||||
|
|
||||||
if (!i2c_slave_check_line_state(sda, scl)) {
|
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];
|
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
|
||||||
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
if(!i2c->lock){
|
if(!i2c->lock){
|
||||||
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
|
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
I2C_SLAVE_MUTEX_LOCK();
|
I2C_SLAVE_MUTEX_LOCK();
|
||||||
i2c_slave_free_resources(i2c);
|
i2c_slave_free_resources(i2c);
|
||||||
I2C_SLAVE_MUTEX_UNLOCK();
|
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;
|
size_t to_queue = 0, to_fifo = 0;
|
||||||
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
|
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
|
||||||
|
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||||
if(!i2c->lock){
|
if(!i2c->lock){
|
||||||
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
|
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(!i2c->tx_queue){
|
if(!i2c->tx_queue){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -715,10 +719,12 @@ static void i2c_slave_isr_handler(void* arg)
|
|||||||
}
|
}
|
||||||
if(slave_rw){ // READ
|
if(slave_rw){ // READ
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
//SEND TX Event
|
if(i2c->dev->status_reg.scl_main_state_last == 6){
|
||||||
i2c_slave_queue_event_t event;
|
//SEND TX Event
|
||||||
event.event = I2C_SLAVE_EVT_TX;
|
i2c_slave_queue_event_t event;
|
||||||
pxHigherPriorityTaskWoken |= i2c_slave_send_event(i2c, &event);
|
event.event = I2C_SLAVE_EVT_TX;
|
||||||
|
pxHigherPriorityTaskWoken |= i2c_slave_send_event(i2c, &event);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
//reset TX data
|
//reset TX data
|
||||||
i2c_ll_txfifo_rst(i2c->dev);
|
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/soc_caps.h"
|
||||||
#include "soc/i2c_periph.h"
|
#include "soc/i2c_periph.h"
|
||||||
#include "hal/i2c_hal.h"
|
#include "hal/i2c_hal.h"
|
||||||
|
#include "hal/i2c_ll.h"
|
||||||
#include "driver/i2c.h"
|
#include "driver/i2c.h"
|
||||||
|
|
||||||
typedef volatile struct {
|
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 {
|
} else {
|
||||||
bus[i2c_num].initialized = true;
|
bus[i2c_num].initialized = true;
|
||||||
bus[i2c_num].frequency = frequency;
|
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
|
#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);
|
hal.dev = I2C_LL_GET_HW(i2c_num);
|
||||||
i2c_hal_set_bus_timing(&(hal), frequency, src_clk);
|
i2c_hal_set_bus_timing(&(hal), frequency, src_clk);
|
||||||
bus[i2c_num].frequency = frequency;
|
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:
|
end:
|
||||||
|
@ -13,46 +13,25 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "esp32-hal.h"
|
#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/soc_caps.h"
|
||||||
#include "soc/ledc_reg.h"
|
#include "driver/ledc.h"
|
||||||
#include "soc/ledc_struct.h"
|
|
||||||
#include "driver/periph_ctrl.h"
|
|
||||||
|
|
||||||
#include "esp_system.h"
|
#ifdef SOC_LEDC_SUPPORT_HS_MODE
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1)
|
||||||
#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()
|
|
||||||
#else
|
#else
|
||||||
#define LEDC_MUTEX_LOCK() do {} while (xSemaphoreTake(_ledc_sys_lock, portMAX_DELAY) != pdPASS)
|
#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM)
|
||||||
#define LEDC_MUTEX_UNLOCK() xSemaphoreGive(_ledc_sys_lock)
|
|
||||||
xSemaphoreHandle _ledc_sys_lock = NULL;
|
|
||||||
#endif
|
#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 Chan to Group/Channel/Timer Mapping
|
||||||
** ledc: 0 => Group: 0, Channel: 0, Timer: 0
|
** 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: 14 => Group: 1, Channel: 6, Timer: 3
|
||||||
** ledc: 15 => Group: 1, Channel: 7, 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){
|
uint8_t channels_resolution[LEDC_CHANNELS] = {0};
|
||||||
if(ev_type == APB_AFTER_CHANGE && old_apb != new_apb){
|
|
||||||
uint16_t iarg = *(uint16_t*)arg;
|
|
||||||
uint8_t chan = 0;
|
|
||||||
old_apb /= 1000000;
|
|
||||||
new_apb /= 1000000;
|
|
||||||
while(iarg){ // run though all active channels, adjusting timing configurations
|
|
||||||
if(iarg & 1) {// this channel is active
|
|
||||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
|
||||||
if(LEDC_TIMER(group, timer).conf.tick_sel){
|
|
||||||
LEDC_MUTEX_LOCK();
|
|
||||||
uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider;
|
|
||||||
uint32_t div_num = (new_apb * old_div) / old_apb;
|
|
||||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V){
|
|
||||||
div_num = ((REF_CLK_FREQ /1000000) * old_div) / old_apb;
|
|
||||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
|
|
||||||
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
|
|
||||||
}
|
|
||||||
LEDC_TIMER(group, timer).conf.tick_sel = 0;
|
|
||||||
} else if(div_num < 256) {
|
|
||||||
div_num = 256;//highest clock possible
|
|
||||||
}
|
|
||||||
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
|
|
||||||
LEDC_MUTEX_UNLOCK();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log_d("using REF_CLK chan=%d",chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iarg = iarg >> 1;
|
|
||||||
chan++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//uint32_t frequency = (80MHz or 1MHz)/((div_num / 256.0)*(1 << bit_num));
|
uint32_t ledcSetup(uint8_t chan, uint32_t freq, uint8_t bit_num)
|
||||||
static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, bool apb_clk)
|
|
||||||
{
|
{
|
||||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
|
||||||
static bool tHasStarted = false;
|
log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
|
||||||
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) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
|
|
||||||
_ledcSetupChannel(chan, LOW);
|
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||||
return res_freq;
|
|
||||||
|
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)
|
void ledcWrite(uint8_t chan, uint32_t duty)
|
||||||
{
|
{
|
||||||
if(chan > LAST_CHAN) {
|
if(chan >= LEDC_CHANNELS){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t group=(chan/8), channel=(chan%8);
|
uint8_t group=(chan/8), channel=(chan%8);
|
||||||
LEDC_MUTEX_LOCK();
|
|
||||||
LEDC_CHAN(group, channel).duty.duty = duty << 4;//25 bit (21.4)
|
//Fixing if all bits in resolution is set = LEDC FULL ON
|
||||||
if(duty) {
|
uint32_t max_duty = (1 << channels_resolution[chan]) - 1;
|
||||||
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(duty == max_duty){
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
duty = max_duty + 1;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
LEDC_MUTEX_UNLOCK();
|
|
||||||
|
ledc_set_duty(group, channel, duty);
|
||||||
|
ledc_update_duty(group, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ledcRead(uint8_t chan)
|
uint32_t ledcRead(uint8_t chan)
|
||||||
{
|
{
|
||||||
if(chan > LAST_CHAN) {
|
if(chan >= LEDC_CHANNELS){
|
||||||
return 0;
|
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)){
|
if(!ledcRead(chan)){
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!freq) {
|
if(!freq){
|
||||||
ledcWrite(chan, 0);
|
ledcWrite(chan, 0);
|
||||||
return 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);
|
ledcWrite(chan, 0x1FF);
|
||||||
return res_freq;
|
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] = {
|
const uint16_t noteFrequencyBase[12] = {
|
||||||
// C C# D Eb E F F# G G# A Bb B
|
// C C# D Eb E F F# G G# A Bb B
|
||||||
4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902
|
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){
|
if(octave > 8 || note >= NOTE_MAX){
|
||||||
return 0;
|
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);
|
return ledcWriteTone(chan, noteFreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ledcAttachPin(uint8_t pin, uint8_t chan)
|
void ledcAttachPin(uint8_t pin, uint8_t chan)
|
||||||
{
|
{
|
||||||
if(chan > LAST_CHAN) {
|
if(chan >= LEDC_CHANNELS){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pinMode(pin, OUTPUT);
|
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
|
||||||
pinMatrixOutAttach(pin, LEDC_LS_SIG_OUT0_IDX + chan, false, false);
|
ledc_channel_config_t ledc_channel = {
|
||||||
#else
|
.speed_mode = group,
|
||||||
pinMatrixOutAttach(pin, ((chan/8)?LEDC_LS_SIG_OUT0_IDX:LEDC_HS_SIG_OUT0_IDX) + (chan%8), false, false);
|
.channel = channel,
|
||||||
#endif
|
.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)
|
void ledcDetachPin(uint8_t pin)
|
||||||
@ -324,23 +184,39 @@ void ledcDetachPin(uint8_t pin)
|
|||||||
pinMatrixOutDetach(pin, false, false);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
|
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||||
return res_freq;
|
|
||||||
|
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 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) {
|
void analogWrite(uint8_t pin, int value) {
|
||||||
// Use ledc hardware for internal pins
|
// Use ledc hardware for internal pins
|
||||||
if (pin < SOC_GPIO_PIN_COUNT) {
|
if (pin < SOC_GPIO_PIN_COUNT) {
|
||||||
if (pin_to_channel[pin] == 0) {
|
if (pin_to_channel[pin] == 0) {
|
||||||
if (!cnt_channel) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
pin_to_channel[pin] = cnt_channel--;
|
pin_to_channel[pin] = cnt_channel--;
|
||||||
|
@ -27,15 +27,15 @@ typedef enum {
|
|||||||
} note_t;
|
} note_t;
|
||||||
|
|
||||||
//channel 0-15 resolution 1-16bits freq limits depend on resolution
|
//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);
|
void ledcWrite(uint8_t channel, uint32_t duty);
|
||||||
double ledcWriteTone(uint8_t channel, double freq);
|
uint32_t ledcWriteTone(uint8_t channel, uint32_t freq);
|
||||||
double ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
|
uint32_t ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
|
||||||
uint32_t ledcRead(uint8_t channel);
|
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 ledcAttachPin(uint8_t pin, uint8_t channel);
|
||||||
void ledcDetachPin(uint8_t pin);
|
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
|
#ifdef __cplusplus
|
||||||
|
@ -38,9 +38,11 @@ extern "C"
|
|||||||
#else
|
#else
|
||||||
#define ARDUHAL_LOG_LEVEL CORE_DEBUG_LEVEL
|
#define ARDUHAL_LOG_LEVEL CORE_DEBUG_LEVEL
|
||||||
#ifdef USE_ESP_IDF_LOG
|
#ifdef USE_ESP_IDF_LOG
|
||||||
|
#ifndef LOG_LOCAL_LEVEL
|
||||||
#define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL
|
#define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_ARDUHAL_LOG_COLORS
|
#ifndef CONFIG_ARDUHAL_LOG_COLORS
|
||||||
#define CONFIG_ARDUHAL_LOG_COLORS 0
|
#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 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)
|
#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
|
#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 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)
|
#define log_buf_e(b,l) do {ESP_LOG_BUFFER_HEXDUMP(TAG, b, l, ESP_LOG_ERROR);}while(0)
|
||||||
#endif
|
#endif
|
||||||
@ -187,9 +189,9 @@ void log_print_buf(const uint8_t *b, size_t len);
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
#ifdef USE_ESP_IDF_LOG
|
#ifdef USE_ESP_IDF_LOG
|
||||||
#ifndef TAG
|
//#ifndef TAG
|
||||||
#define TAG "ARDUINO"
|
//#define TAG "ARDUINO"
|
||||||
#endif
|
//#endif
|
||||||
//#define log_n(format, ...) myLog(ESP_LOG_NONE, format, ##__VA_ARGS__)
|
//#define log_n(format, ...) myLog(ESP_LOG_NONE, format, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#ifdef CONFIG_ARDUHAL_ESP_LOG
|
#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_LOGD
|
||||||
#undef ESP_EARLY_LOGV
|
#undef ESP_EARLY_LOGV
|
||||||
|
|
||||||
#define ESP_LOGE(tag, ...) log_e(__VA_ARGS__)
|
#define ESP_LOGE(tag, format, ...) log_e("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_LOGW(tag, ...) log_w(__VA_ARGS__)
|
#define ESP_LOGW(tag, format, ...) log_w("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_LOGI(tag, ...) log_i(__VA_ARGS__)
|
#define ESP_LOGI(tag, format, ...) log_i("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_LOGD(tag, ...) log_d(__VA_ARGS__)
|
#define ESP_LOGD(tag, format, ...) log_d("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_LOGV(tag, ...) log_v(__VA_ARGS__)
|
#define ESP_LOGV(tag, format, ...) log_v("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_EARLY_LOGE(tag, ...) isr_log_e(__VA_ARGS__)
|
#define ESP_EARLY_LOGE(tag, format, ...) isr_log_e("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_EARLY_LOGW(tag, ...) isr_log_w(__VA_ARGS__)
|
#define ESP_EARLY_LOGW(tag, format, ...) isr_log_w("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_EARLY_LOGI(tag, ...) isr_log_i(__VA_ARGS__)
|
#define ESP_EARLY_LOGI(tag, format, ...) isr_log_i("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_EARLY_LOGD(tag, ...) isr_log_d(__VA_ARGS__)
|
#define ESP_EARLY_LOGD(tag, format, ...) isr_log_d("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#define ESP_EARLY_LOGV(tag, ...) isr_log_v(__VA_ARGS__)
|
#define ESP_EARLY_LOGV(tag, format, ...) isr_log_v("[%s] " format, tag, ##__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "esp32/rom/gpio.h"
|
#include "esp32/rom/gpio.h"
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
#include "esp32s2/rom/gpio.h"
|
#include "esp32s2/rom/gpio.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#include "esp32s3/rom/gpio.h"
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#include "esp32c3/rom/gpio.h"
|
#include "esp32c3/rom/gpio.h"
|
||||||
#else
|
#else
|
||||||
|
@ -41,6 +41,9 @@
|
|||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
#include "esp32s2/rom/rtc.h"
|
#include "esp32s2/rom/rtc.h"
|
||||||
#include "driver/temp_sensor.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
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#include "esp32c3/rom/rtc.h"
|
#include "esp32c3/rom/rtc.h"
|
||||||
#include "driver/temp_sensor.h"
|
#include "driver/temp_sensor.h"
|
||||||
@ -232,7 +235,7 @@ void initArduino()
|
|||||||
#endif
|
#endif
|
||||||
esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL);
|
esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL);
|
||||||
esp_err_t err = nvs_flash_init();
|
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);
|
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
|
||||||
if (partition != NULL) {
|
if (partition != NULL) {
|
||||||
err = esp_partition_erase_range(partition, 0, partition->size);
|
err = esp_partition_erase_range(partition, 0, partition->size);
|
||||||
@ -241,6 +244,8 @@ void initArduino()
|
|||||||
} else {
|
} else {
|
||||||
log_e("Failed to format the broken NVS partition!");
|
log_e("Failed to format the broken NVS partition!");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log_e("Could not find NVS partition");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(err) {
|
if(err) {
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
#include "esp32s2/spiram.h"
|
#include "esp32s2/spiram.h"
|
||||||
#include "esp32s2/rom/cache.h"
|
#include "esp32s2/rom/cache.h"
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#include "esp32s3/spiram.h"
|
||||||
|
#include "esp32s3/rom/cache.h"
|
||||||
#else
|
#else
|
||||||
#error Target CONFIG_IDF_TARGET is not supported
|
#error Target CONFIG_IDF_TARGET is not supported
|
||||||
#endif
|
#endif
|
||||||
@ -35,6 +38,13 @@
|
|||||||
static volatile bool spiramDetected = false;
|
static volatile bool spiramDetected = false;
|
||||||
static volatile bool spiramFailed = 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(){
|
bool psramInit(){
|
||||||
if (spiramDetected) {
|
if (spiramDetected) {
|
||||||
return true;
|
return true;
|
||||||
@ -60,13 +70,16 @@ bool psramInit(){
|
|||||||
spiramFailed = true;
|
spiramFailed = true;
|
||||||
log_w("PSRAM init failed!");
|
log_w("PSRAM init failed!");
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
pinMatrixOutDetach(16, false, false);
|
if (pkg_ver != EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||||
pinMatrixOutDetach(17, false, false);
|
pinMatrixOutDetach(16, false, false);
|
||||||
|
pinMatrixOutDetach(17, false, false);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
esp_spiram_init_cache();
|
esp_spiram_init_cache();
|
||||||
if (!esp_spiram_test()) {
|
//testSPIRAM() allows user to bypass SPI RAM test routine
|
||||||
|
if (!testSPIRAM()) {
|
||||||
spiramFailed = true;
|
spiramFailed = true;
|
||||||
log_e("PSRAM test failed!");
|
log_e("PSRAM test failed!");
|
||||||
return false;
|
return false;
|
||||||
@ -76,12 +89,12 @@ bool psramInit(){
|
|||||||
log_e("PSRAM could not be added to the heap!");
|
log_e("PSRAM could not be added to the heap!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#if CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL && !CONFIG_ARDUINO_ISR_IRAM
|
#if CONFIG_SPIRAM_USE_MALLOC && !CONFIG_ARDUINO_ISR_IRAM
|
||||||
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* CONFIG_SPIRAM_BOOT_INIT */
|
||||||
|
log_i("PSRAM enabled");
|
||||||
spiramDetected = true;
|
spiramDetected = true;
|
||||||
log_d("PSRAM enabled");
|
|
||||||
return true;
|
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_FLAG_ERROR (4)
|
||||||
#define RMT_FLAGS_ALL (RMT_FLAG_TX_DONE | RMT_FLAG_RX_DONE | RMT_FLAG_ERROR)
|
#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;
|
struct rmt_obj_s;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -54,6 +57,13 @@ typedef struct {
|
|||||||
};
|
};
|
||||||
} rmt_data_t;
|
} rmt_data_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints object information
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void _rmtDumpStatus(rmt_obj_t* rmt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the object
|
* Initialize the object
|
||||||
*
|
*
|
||||||
@ -69,10 +79,17 @@ float rmtSetTick(rmt_obj_t* rmt, float tick);
|
|||||||
/**
|
/**
|
||||||
* Sending data in one-go mode or continual mode
|
* Sending data in one-go mode or continual mode
|
||||||
* (more data being send while updating buffers in interrupts)
|
* (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);
|
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
|
* Loop data up to the reserved memsize continuously
|
||||||
*
|
*
|
||||||
|
@ -12,38 +12,14 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "esp32-hal.h"
|
#include "esp32-hal.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "freertos/task.h"
|
#include "driver/sigmadelta.h"
|
||||||
#include "freertos/semphr.h"
|
|
||||||
#include "esp32-hal-matrix.h"
|
|
||||||
#include "soc/gpio_sd_reg.h"
|
|
||||||
#include "soc/gpio_sd_struct.h"
|
|
||||||
|
|
||||||
#include "esp_system.h"
|
static uint8_t duty_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0};
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
static uint32_t prescaler_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0};
|
||||||
#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 void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
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){
|
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;
|
uint32_t iarg = (uint32_t)arg;
|
||||||
uint8_t channel = iarg;
|
uint8_t channel = iarg;
|
||||||
if(ev_type == APB_BEFORE_CHANGE){
|
if(ev_type == APB_AFTER_CHANGE){
|
||||||
SIGMADELTA.cg.clk_en = 0;
|
|
||||||
} else {
|
|
||||||
old_apb /= 1000000;
|
old_apb /= 1000000;
|
||||||
new_apb /= 1000000;
|
new_apb /= 1000000;
|
||||||
SD_MUTEX_LOCK();
|
uint32_t old_prescale = prescaler_set[channel] + 1;
|
||||||
uint32_t old_prescale = SIGMADELTA.channel[channel].prescale + 1;
|
uint32_t new_prescale = ((new_apb * old_prescale) / old_apb) - 1;
|
||||||
SIGMADELTA.channel[channel].prescale = ((new_apb * old_prescale) / old_apb) - 1;
|
sigmadelta_set_prescale(channel,new_prescale);
|
||||||
SIGMADELTA.cg.clk_en = 0;
|
prescaler_set[channel] = new_prescale;
|
||||||
SIGMADELTA.cg.clk_en = 1;
|
|
||||||
SD_MUTEX_UNLOCK();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
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 apb_freq = getApbFrequency();
|
||||||
uint32_t prescale = (apb_freq/(freq*256)) - 1;
|
uint32_t prescale = (apb_freq/(freq*256)) - 1;
|
||||||
if(prescale > 0xFF) {
|
if(prescale > 0xFF) {
|
||||||
prescale = 0xFF;
|
prescale = 0xFF;
|
||||||
}
|
}
|
||||||
SD_MUTEX_LOCK();
|
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
sigmadelta_config_t sigmadelta_cfg = {
|
||||||
SIGMADELTA.misc.function_clk_en = 1;
|
.channel = channel,
|
||||||
#endif
|
.sigmadelta_prescale = prescale,
|
||||||
SIGMADELTA.channel[channel].prescale = prescale;
|
.sigmadelta_duty = 0,
|
||||||
SIGMADELTA.cg.clk_en = 0;
|
.sigmadelta_gpio = pin,
|
||||||
SIGMADELTA.cg.clk_en = 1;
|
};
|
||||||
SD_MUTEX_UNLOCK();
|
sigmadelta_config(&sigmadelta_cfg);
|
||||||
|
|
||||||
|
prescaler_set[channel] = prescale;
|
||||||
uint32_t iarg = channel;
|
uint32_t iarg = channel;
|
||||||
addApbChangeCallback((void*)iarg, _on_apb_change);
|
addApbChangeCallback((void*)iarg, _on_apb_change);
|
||||||
|
|
||||||
return apb_freq/((prescale + 1) * 256);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
duty -= 128;
|
duty -= 128;
|
||||||
SD_MUTEX_LOCK();
|
|
||||||
SIGMADELTA.channel[channel].duty = duty;
|
sigmadelta_set_duty(channel,duty);
|
||||||
SD_MUTEX_UNLOCK();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
SD_MUTEX_LOCK();
|
return duty_set[channel]+128;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sigmaDeltaDetachPin(uint8_t pin)
|
void sigmaDeltaDetachPin(uint8_t pin)
|
||||||
{
|
{
|
||||||
pinMatrixOutDetach(pin, false, false);
|
pinMatrixOutDetach(pin, false, false);
|
||||||
}
|
}
|
@ -23,10 +23,9 @@ extern "C" {
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
//channel 0-7 freq 1220-312500 duty 0-255
|
//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);
|
void sigmaDeltaWrite(uint8_t channel, uint8_t duty);
|
||||||
uint8_t sigmaDeltaRead(uint8_t channel);
|
uint8_t sigmaDeltaRead(uint8_t channel);
|
||||||
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel);
|
|
||||||
void sigmaDeltaDetachPin(uint8_t pin);
|
void sigmaDeltaDetachPin(uint8_t pin);
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +37,11 @@
|
|||||||
#include "esp32s2/rom/ets_sys.h"
|
#include "esp32s2/rom/ets_sys.h"
|
||||||
#include "esp32s2/rom/gpio.h"
|
#include "esp32s2/rom/gpio.h"
|
||||||
#include "esp_intr_alloc.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
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
#include "esp32c3/rom/ets_sys.h"
|
#include "esp32c3/rom/ets_sys.h"
|
||||||
#include "esp32c3/rom/gpio.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_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_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
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
// ESP32S2
|
// ESP32C3
|
||||||
#define SPI_COUNT (1)
|
#define SPI_COUNT (1)
|
||||||
|
|
||||||
#define SPI_CLK_IDX(p) FSPICLK_OUT_IDX
|
#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_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_SS_IDX(p, n) SPI_SPI_SS_IDX(n)
|
||||||
|
|
||||||
#define SPI_INTR_SOURCE(u) ETS_SPI2_INTR_SOURCE
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// ESP32
|
// ESP32
|
||||||
#define SPI_COUNT (4)
|
#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_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_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
|
#endif
|
||||||
|
|
||||||
#if CONFIG_DISABLE_HAL_LOCKS
|
#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_SPI1_BASE), 0},
|
||||||
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1},
|
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1},
|
||||||
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2}
|
{(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
|
#else
|
||||||
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0},
|
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0},
|
||||||
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1},
|
{(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_SPI1_BASE), NULL, 0},
|
||||||
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1},
|
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1},
|
||||||
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2}
|
{(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
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
{(volatile spi_dev_t *)(&GPSPI2), NULL, FSPI}
|
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0}
|
||||||
#else
|
#else
|
||||||
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0},
|
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0},
|
||||||
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1},
|
{(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!");
|
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||||
return;
|
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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi->num == HSPI) {
|
if(spi->num == HSPI) {
|
||||||
sck = 14;
|
sck = 14;
|
||||||
@ -182,6 +208,13 @@ void spiAttachMISO(spi_t * spi, int8_t miso)
|
|||||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||||
return;
|
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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi->num == HSPI) {
|
if(spi->num == HSPI) {
|
||||||
miso = 12;
|
miso = 12;
|
||||||
@ -207,13 +240,20 @@ void spiAttachMOSI(spi_t * spi, int8_t mosi)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(mosi < 0) {
|
if(mosi < 0) {
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
if(spi->num == FSPI) {
|
if(spi->num == FSPI) {
|
||||||
mosi = 35;
|
mosi = 35;
|
||||||
} else {
|
} else {
|
||||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||||
return;
|
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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi->num == HSPI) {
|
if(spi->num == HSPI) {
|
||||||
mosi = 13;
|
mosi = 13;
|
||||||
@ -237,13 +277,20 @@ void spiDetachSCK(spi_t * spi, int8_t sck)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(sck < 0) {
|
if(sck < 0) {
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
if(spi->num == FSPI) {
|
if(spi->num == FSPI) {
|
||||||
sck = 36;
|
sck = 36;
|
||||||
} else {
|
} else {
|
||||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||||
return;
|
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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi->num == HSPI) {
|
if(spi->num == HSPI) {
|
||||||
sck = 14;
|
sck = 14;
|
||||||
@ -267,13 +314,20 @@ void spiDetachMISO(spi_t * spi, int8_t miso)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(miso < 0) {
|
if(miso < 0) {
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
if(spi->num == FSPI) {
|
if(spi->num == FSPI) {
|
||||||
miso = 37;
|
miso = 37;
|
||||||
} else {
|
} else {
|
||||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||||
return;
|
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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi->num == HSPI) {
|
if(spi->num == HSPI) {
|
||||||
miso = 12;
|
miso = 12;
|
||||||
@ -297,13 +351,20 @@ void spiDetachMOSI(spi_t * spi, int8_t mosi)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(mosi < 0) {
|
if(mosi < 0) {
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
if(spi->num == FSPI) {
|
if(spi->num == FSPI) {
|
||||||
mosi = 35;
|
mosi = 35;
|
||||||
} else {
|
} else {
|
||||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||||
return;
|
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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi->num == HSPI) {
|
if(spi->num == HSPI) {
|
||||||
mosi = 13;
|
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!");
|
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||||
return;
|
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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi->num == HSPI) {
|
if(spi->num == HSPI) {
|
||||||
ss = 15;
|
ss = 15;
|
||||||
@ -369,6 +437,13 @@ void spiDetachSS(spi_t * spi, int8_t ss)
|
|||||||
log_e("HSPI Does not have default pins on ESP32S2!");
|
log_e("HSPI Does not have default pins on ESP32S2!");
|
||||||
return;
|
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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi->num == HSPI) {
|
if(spi->num == HSPI) {
|
||||||
ss = 15;
|
ss = 15;
|
||||||
@ -392,7 +467,7 @@ void spiEnableSSPins(spi_t * spi, uint8_t cs_mask)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SPI_MUTEX_LOCK();
|
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);
|
spi->dev->misc.val &= ~(cs_mask & SPI_CS_MASK_ALL);
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL);
|
spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL);
|
||||||
@ -406,7 +481,7 @@ void spiDisableSSPins(spi_t * spi, uint8_t cs_mask)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SPI_MUTEX_LOCK();
|
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);
|
spi->dev->misc.val |= (cs_mask & SPI_CS_MASK_ALL);
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL);
|
spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL);
|
||||||
@ -442,7 +517,7 @@ void spiSSSet(spi_t * spi)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SPI_MUTEX_LOCK();
|
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;
|
spi->dev->misc.cs_keep_active = 1;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.cs_keep_active = 1;
|
spi->dev->pin.cs_keep_active = 1;
|
||||||
@ -456,7 +531,7 @@ void spiSSClear(spi_t * spi)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SPI_MUTEX_LOCK();
|
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;
|
spi->dev->misc.cs_keep_active = 0;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.cs_keep_active = 0;
|
spi->dev->pin.cs_keep_active = 0;
|
||||||
@ -487,7 +562,7 @@ uint8_t spiGetDataMode(spi_t * spi)
|
|||||||
if(!spi) {
|
if(!spi) {
|
||||||
return 0;
|
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;
|
bool idleEdge = spi->dev->misc.ck_idle_edge;
|
||||||
#else
|
#else
|
||||||
bool idleEdge = spi->dev->pin.ck_idle_edge;
|
bool idleEdge = spi->dev->pin.ck_idle_edge;
|
||||||
@ -513,7 +588,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
|
|||||||
SPI_MUTEX_LOCK();
|
SPI_MUTEX_LOCK();
|
||||||
switch (dataMode) {
|
switch (dataMode) {
|
||||||
case SPI_MODE1:
|
case SPI_MODE1:
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||||
spi->dev->misc.ck_idle_edge = 0;
|
spi->dev->misc.ck_idle_edge = 0;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.ck_idle_edge = 0;
|
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;
|
spi->dev->user.ck_out_edge = 1;
|
||||||
break;
|
break;
|
||||||
case SPI_MODE2:
|
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;
|
spi->dev->misc.ck_idle_edge = 1;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.ck_idle_edge = 1;
|
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;
|
spi->dev->user.ck_out_edge = 1;
|
||||||
break;
|
break;
|
||||||
case SPI_MODE3:
|
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;
|
spi->dev->misc.ck_idle_edge = 1;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.ck_idle_edge = 1;
|
spi->dev->pin.ck_idle_edge = 1;
|
||||||
@ -538,7 +613,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
|
|||||||
break;
|
break;
|
||||||
case SPI_MODE0:
|
case SPI_MODE0:
|
||||||
default:
|
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;
|
spi->dev->misc.ck_idle_edge = 0;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.ck_idle_edge = 0;
|
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)
|
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;
|
spi->dev->slave.trans_done = 0;
|
||||||
#endif
|
#endif
|
||||||
spi->dev->slave.val = 0;
|
spi->dev->slave.val = 0;
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||||
spi->dev->misc.val = 0;
|
spi->dev->misc.val = 0;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.val = 0;
|
spi->dev->pin.val = 0;
|
||||||
@ -599,7 +674,7 @@ static void spiInitBus(spi_t * spi)
|
|||||||
spi->dev->user.val = 0;
|
spi->dev->user.val = 0;
|
||||||
spi->dev->user1.val = 0;
|
spi->dev->user1.val = 0;
|
||||||
spi->dev->ctrl.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->ctrl1.val = 0;
|
||||||
spi->dev->ctrl2.val = 0;
|
spi->dev->ctrl2.val = 0;
|
||||||
#else
|
#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_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN);
|
||||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST);
|
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST);
|
||||||
}
|
}
|
||||||
|
#elif CONFIG_IDF_TARGET_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
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
if(spi_num == HSPI) {
|
if(spi_num == HSPI) {
|
||||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN);
|
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();
|
SPI_MUTEX_LOCK();
|
||||||
spiInitBus(spi);
|
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.clk_en = 1;
|
||||||
spi->dev->clk_gate.mst_clk_sel = 1;
|
spi->dev->clk_gate.mst_clk_sel = 1;
|
||||||
spi->dev->clk_gate.mst_clk_active = 1;
|
spi->dev->clk_gate.mst_clk_active = 1;
|
||||||
@ -707,7 +790,7 @@ void spiWaitReady(spi_t * spi)
|
|||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S2
|
||||||
#define usr_mosi_dbitlen usr_mosi_bit_len
|
#define usr_mosi_dbitlen usr_mosi_bit_len
|
||||||
#define usr_miso_dbitlen usr_miso_bit_len
|
#define usr_miso_dbitlen usr_miso_bit_len
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
#define usr_mosi_dbitlen ms_data_bitlen
|
#define usr_mosi_dbitlen ms_data_bitlen
|
||||||
#define usr_miso_dbitlen ms_data_bitlen
|
#define usr_miso_dbitlen ms_data_bitlen
|
||||||
#define mosi_dlen ms_dlen
|
#define mosi_dlen ms_dlen
|
||||||
@ -725,13 +808,13 @@ void spiWrite(spi_t * spi, const uint32_t *data, uint8_t len)
|
|||||||
}
|
}
|
||||||
SPI_MUTEX_LOCK();
|
SPI_MUTEX_LOCK();
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
|
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;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
for(i=0; i<len; i++) {
|
for(i=0; i<len; i++) {
|
||||||
spi->dev->data_buf[i] = data[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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -755,7 +838,7 @@ void spiTransfer(spi_t * spi, uint32_t *data, uint8_t len)
|
|||||||
for(i=0; i<len; i++) {
|
for(i=0; i<len; i++) {
|
||||||
spi->dev->data_buf[i] = data[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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -774,11 +857,11 @@ void spiWriteByte(spi_t * spi, uint8_t data)
|
|||||||
}
|
}
|
||||||
SPI_MUTEX_LOCK();
|
SPI_MUTEX_LOCK();
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -796,7 +879,7 @@ uint8_t spiTransferByte(spi_t * spi, uint8_t data)
|
|||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -827,11 +910,11 @@ void spiWriteWord(spi_t * spi, uint16_t data)
|
|||||||
}
|
}
|
||||||
SPI_MUTEX_LOCK();
|
SPI_MUTEX_LOCK();
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -852,7 +935,7 @@ uint16_t spiTransferWord(spi_t * spi, uint16_t data)
|
|||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -876,11 +959,11 @@ void spiWriteLong(spi_t * spi, uint32_t data)
|
|||||||
}
|
}
|
||||||
SPI_MUTEX_LOCK();
|
SPI_MUTEX_LOCK();
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -901,7 +984,7 @@ uint32_t spiTransferLong(spi_t * spi, uint32_t data)
|
|||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#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
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1012,7 +1095,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
|
|||||||
spi->dev->clock.val = clockDiv;
|
spi->dev->clock.val = clockDiv;
|
||||||
switch (dataMode) {
|
switch (dataMode) {
|
||||||
case SPI_MODE1:
|
case SPI_MODE1:
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
|
||||||
spi->dev->misc.ck_idle_edge = 0;
|
spi->dev->misc.ck_idle_edge = 0;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.ck_idle_edge = 0;
|
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;
|
spi->dev->user.ck_out_edge = 1;
|
||||||
break;
|
break;
|
||||||
case SPI_MODE2:
|
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;
|
spi->dev->misc.ck_idle_edge = 1;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.ck_idle_edge = 1;
|
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;
|
spi->dev->user.ck_out_edge = 1;
|
||||||
break;
|
break;
|
||||||
case SPI_MODE3:
|
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;
|
spi->dev->misc.ck_idle_edge = 1;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.ck_idle_edge = 1;
|
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;
|
break;
|
||||||
case SPI_MODE0:
|
case SPI_MODE0:
|
||||||
default:
|
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;
|
spi->dev->misc.ck_idle_edge = 0;
|
||||||
#else
|
#else
|
||||||
spi->dev->pin.ck_idle_edge = 0;
|
spi->dev->pin.ck_idle_edge = 0;
|
||||||
@ -1076,11 +1159,11 @@ void ARDUINO_ISR_ATTR spiWriteByteNL(spi_t * spi, uint8_t data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
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;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1096,7 +1179,7 @@ uint8_t spiTransferByteNL(spi_t * spi, uint8_t data)
|
|||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1115,11 +1198,11 @@ void ARDUINO_ISR_ATTR spiWriteShortNL(spi_t * spi, uint16_t data)
|
|||||||
MSB_16_SET(data, data);
|
MSB_16_SET(data, data);
|
||||||
}
|
}
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
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;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1138,7 +1221,7 @@ uint16_t spiTransferShortNL(spi_t * spi, uint16_t data)
|
|||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 15;
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1160,11 +1243,11 @@ void ARDUINO_ISR_ATTR spiWriteLongNL(spi_t * spi, uint32_t data)
|
|||||||
MSB_32_SET(data, data);
|
MSB_32_SET(data, data);
|
||||||
}
|
}
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
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;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1183,7 +1266,7 @@ uint32_t spiTransferLongNL(spi_t * spi, uint32_t data)
|
|||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 31;
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1212,13 +1295,13 @@ void spiWriteNL(spi_t * spi, const void * data_in, uint32_t len){
|
|||||||
c_longs = (longs > 16)?16:longs;
|
c_longs = (longs > 16)?16:longs;
|
||||||
|
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1;
|
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;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
for (int i=0; i<c_longs; i++) {
|
for (int i=0; i<c_longs; i++) {
|
||||||
spi->dev->data_buf[i] = data[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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#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;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#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->mosi_dlen.usr_mosi_dbitlen = (bits - 1);
|
||||||
spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1);
|
spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1);
|
||||||
spi->dev->data_buf[0] = data;
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1353,7 +1436,7 @@ void ARDUINO_ISR_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, uint32
|
|||||||
l_bytes = (c_len & 3);
|
l_bytes = (c_len & 3);
|
||||||
|
|
||||||
spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1;
|
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;
|
spi->dev->miso_dlen.usr_miso_dbitlen = 0;
|
||||||
#endif
|
#endif
|
||||||
for (int i=0; i<c_longs; i++) {
|
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];
|
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;
|
spi->dev->cmd.update = 1;
|
||||||
while (spi->dev->cmd.update);
|
while (spi->dev->cmd.update);
|
||||||
#endif
|
#endif
|
||||||
@ -1397,7 +1480,7 @@ typedef union {
|
|||||||
uint32_t clkcnt_l: 6; /*it must be equal to spi_clkcnt_N.*/
|
uint32_t clkcnt_l: 6; /*it must be equal to spi_clkcnt_N.*/
|
||||||
uint32_t clkcnt_h: 6; /*it must be floor((spi_clkcnt_N+1)/2-1).*/
|
uint32_t clkcnt_h: 6; /*it must be floor((spi_clkcnt_N+1)/2-1).*/
|
||||||
uint32_t clkcnt_n: 6; /*it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/
|
uint32_t clkcnt_n: 6; /*it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
uint32_t clkdiv_pre: 4; /*it is pre-divider of spi_clk.*/
|
uint32_t clkdiv_pre: 4; /*it is pre-divider of spi_clk.*/
|
||||||
uint32_t reserved: 9; /*reserved*/
|
uint32_t reserved: 9; /*reserved*/
|
||||||
#else
|
#else
|
||||||
@ -1444,7 +1527,7 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
|
|||||||
|
|
||||||
while(calPreVari++ <= 1) {
|
while(calPreVari++ <= 1) {
|
||||||
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
|
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
if(calPre > 0xF) {
|
if(calPre > 0xF) {
|
||||||
reg.clkdiv_pre = 0xF;
|
reg.clkdiv_pre = 0xF;
|
||||||
#else
|
#else
|
||||||
@ -1475,4 +1558,3 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
|
|||||||
}
|
}
|
||||||
return bestReg.value;
|
return bestReg.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define SPI_HAS_TRANSACTION
|
#define SPI_HAS_TRANSACTION
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
#define FSPI 0
|
#define FSPI 0
|
||||||
#define HSPI 1
|
#define HSPI 1
|
||||||
#else
|
#else
|
||||||
|
@ -44,8 +44,6 @@ static void setTimeZone(long offset, int daylight)
|
|||||||
/*
|
/*
|
||||||
* configTime
|
* configTime
|
||||||
* Source: https://github.com/esp8266/Arduino/blob/master/cores/esp8266/time.c
|
* 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)
|
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
|
* configTzTime
|
||||||
* sntp setup using TZ environment variable
|
* 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)
|
void configTzTime(const char* tz, const char* server1, const char* server2, const char* server3)
|
||||||
{
|
{
|
||||||
|
@ -13,335 +13,227 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "esp32-hal-timer.h"
|
#include "esp32-hal-timer.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "driver/timer.h"
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
#include "soc/soc_caps.h"
|
||||||
#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 "esp_system.h"
|
typedef union {
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
struct {
|
||||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
uint32_t reserved0: 10;
|
||||||
#include "esp32/rom/ets_sys.h"
|
uint32_t alarm_en: 1; /*When set alarm is enabled*/
|
||||||
#include "esp_intr_alloc.h"
|
uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
uint32_t edge_int_en: 1; /*When set edge type interrupt will be generated during alarm*/
|
||||||
#include "esp32s2/rom/ets_sys.h"
|
uint32_t divider: 16; /*Timer clock (T0/1_clk) pre-scale value.*/
|
||||||
#include "esp_intr_alloc.h"
|
uint32_t autoreload: 1; /*When set timer 0/1 auto-reload at alarming is enabled*/
|
||||||
#include "soc/periph_defs.h"
|
uint32_t increase: 1; /*When set timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
uint32_t enable: 1; /*When set timer 0/1 time-base counter is enabled*/
|
||||||
#include "esp32c3/rom/ets_sys.h"
|
};
|
||||||
#include "esp_intr_alloc.h"
|
uint32_t val;
|
||||||
#include "soc/periph_defs.h"
|
} timer_cfg_t;
|
||||||
#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
|
|
||||||
|
|
||||||
#define HWTIMER_LOCK() portENTER_CRITICAL(timer->lock)
|
#define NUM_OF_TIMERS SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||||
#define HWTIMER_UNLOCK() portEXIT_CRITICAL(timer->lock)
|
|
||||||
|
|
||||||
typedef volatile struct {
|
typedef struct {
|
||||||
union {
|
int timer_group;
|
||||||
struct {
|
int timer_idx;
|
||||||
uint32_t reserved0: 10;
|
int alarm_interval;
|
||||||
uint32_t alarm_en: 1; /*When set alarm is enabled*/
|
bool auto_reload;
|
||||||
uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/
|
} timer_info_t;
|
||||||
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 {
|
typedef struct hw_timer_s
|
||||||
hw_timer_reg_t * dev;
|
{
|
||||||
uint8_t num;
|
uint8_t group;
|
||||||
uint8_t group;
|
uint8_t num;
|
||||||
uint8_t timer;
|
|
||||||
portMUX_TYPE lock;
|
|
||||||
} hw_timer_t;
|
} hw_timer_t;
|
||||||
|
|
||||||
static hw_timer_t hw_timer[4] = {
|
// Works for all chips
|
||||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE),0,0,0,portMUX_INITIALIZER_UNLOCKED},
|
static hw_timer_t timer_dev[4] = {
|
||||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x0024),1,0,1,portMUX_INITIALIZER_UNLOCKED},
|
{0,0}, {1,0}, {1,0}, {1,1}
|
||||||
{(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}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*voidFuncPtr)(void);
|
// NOTE: (in IDF 5.0 there wont be need to know groups/numbers
|
||||||
static voidFuncPtr __timerInterruptHandlers[4] = {0,0,0,0};
|
// 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){
|
uint64_t inline timerRead(hw_timer_t *timer){
|
||||||
timer->dev->update = 1;
|
|
||||||
while (timer->dev->update) {};
|
uint64_t value;
|
||||||
uint64_t h = timer->dev->cnt_high;
|
timer_get_counter_value(timer->group, timer->num,&value);
|
||||||
uint64_t l = timer->dev->cnt_low;
|
return value;
|
||||||
return (h << 32) | l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t timerAlarmRead(hw_timer_t *timer){
|
uint64_t timerAlarmRead(hw_timer_t *timer){
|
||||||
uint64_t h = timer->dev->alarm_high;
|
uint64_t value;
|
||||||
uint64_t l = timer->dev->alarm_low;
|
timer_get_alarm_value(timer->group, timer->num, &value);
|
||||||
return (h << 32) | l;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerWrite(hw_timer_t *timer, uint64_t val){
|
void timerWrite(hw_timer_t *timer, uint64_t val){
|
||||||
timer->dev->load_high = (uint32_t) (val >> 32);
|
timer_set_counter_value(timer->group, timer->num, val);
|
||||||
timer->dev->load_low = (uint32_t) (val);
|
|
||||||
timer->dev->reload = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){
|
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){
|
||||||
timer->dev->alarm_high = (uint32_t) (alarm_value >> 32);
|
timer_set_alarm_value(timer->group, timer->num, alarm_value);
|
||||||
timer->dev->alarm_low = (uint32_t) alarm_value;
|
timerSetAutoReload(timer,autoreload);
|
||||||
timer->dev->config.autoreload = autoreload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerSetConfig(hw_timer_t *timer, uint32_t config){
|
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){
|
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){
|
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){
|
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){
|
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){
|
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
|
// Set divider from 2 to 65535
|
||||||
if(!divider){
|
void timerSetDivider(hw_timer_t *timer, uint16_t divider){
|
||||||
divider = 0xFFFF;
|
if(divider < 2)
|
||||||
} else if(divider == 1){
|
{
|
||||||
divider = 2;
|
log_e("Timer divider must be set in range of 2 to 65535");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
int timer_en = timer->dev->config.enable;
|
timer_set_divider(timer->group, timer->num,divider);
|
||||||
timer->dev->config.enable = 0;
|
|
||||||
timer->dev->config.divider = divider;
|
|
||||||
timer->dev->config.enable = timer_en;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t timerGetDivider(hw_timer_t *timer){
|
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){
|
void timerStart(hw_timer_t *timer){
|
||||||
timer->dev->config.enable = 1;
|
timer_start(timer->group, timer->num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerStop(hw_timer_t *timer){
|
void timerStop(hw_timer_t *timer){
|
||||||
timer->dev->config.enable = 0;
|
timer_pause(timer->group, timer->num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerRestart(hw_timer_t *timer){
|
void timerRestart(hw_timer_t *timer){
|
||||||
timer->dev->config.enable = 0;
|
timerWrite(timer,0);
|
||||||
timer->dev->reload = 1;
|
|
||||||
timer->dev->config.enable = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool timerStarted(hw_timer_t *timer){
|
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){
|
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){
|
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){
|
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){
|
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;
|
hw_timer_t * timer = (hw_timer_t *)arg;
|
||||||
if(ev_type == APB_BEFORE_CHANGE){
|
if(ev_type == APB_BEFORE_CHANGE){
|
||||||
timer->dev->config.enable = 0;
|
timerStop(timer);
|
||||||
} else {
|
} else {
|
||||||
old_apb /= 1000000;
|
old_apb /= 1000000;
|
||||||
new_apb /= 1000000;
|
new_apb /= 1000000;
|
||||||
timer->dev->config.divider = (new_apb * timer->dev->config.divider) / old_apb;
|
uint16_t divider = (new_apb * timerGetDivider(timer)) / old_apb;
|
||||||
timer->dev->config.enable = 1;
|
timerSetDivider(timer,divider);
|
||||||
|
timerStart(timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
|
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
|
||||||
if(num > 3){
|
if(num >= NUM_OF_TIMERS)
|
||||||
|
{
|
||||||
|
log_e("Timer dont have that timer number.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
hw_timer_t * timer = &hw_timer[num];
|
|
||||||
if(timer->group) {
|
hw_timer_t * timer = &timer_dev[num]; //Get Timer group/num from 0-3 number
|
||||||
periph_module_enable(PERIPH_TIMG1_MODULE);
|
|
||||||
} else {
|
timer_config_t config = {
|
||||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
.divider = divider,
|
||||||
}
|
.counter_dir = countUp,
|
||||||
timer->dev->config.enable = 0;
|
.counter_en = TIMER_PAUSE,
|
||||||
if(timer->group) {
|
.alarm_en = TIMER_ALARM_DIS,
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
.auto_reload = false,
|
||||||
TIMERG1.int_ena.val &= ~BIT(timer->timer);
|
};
|
||||||
#else
|
|
||||||
TIMERG1.int_ena_timers.val &= ~BIT(timer->timer);
|
timer_init(timer->group, timer->num, &config);
|
||||||
#endif
|
timer_set_counter_value(timer->group, timer->num, 0);
|
||||||
TIMERG1.int_clr_timers.val |= BIT(timer->timer);
|
timerStart(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;
|
|
||||||
addApbChangeCallback(timer, _on_apb_change);
|
addApbChangeCallback(timer, _on_apb_change);
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerEnd(hw_timer_t *timer){
|
void timerEnd(hw_timer_t *timer){
|
||||||
timer->dev->config.enable = 0;
|
|
||||||
timerAttachInterrupt(timer, NULL, false);
|
|
||||||
removeApbChangeCallback(timer, _on_apb_change);
|
removeApbChangeCallback(timer, _on_apb_change);
|
||||||
|
timer_deinit(timer->group, timer->num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
|
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
if(edge){
|
if(edge){
|
||||||
log_w("EDGE timer interrupt does not work properly on ESP32! Setting to LEVEL...");
|
log_w("EDGE timer interrupt is not supported! Setting to LEVEL...");
|
||||||
edge = false;
|
edge = false;
|
||||||
}
|
}
|
||||||
#endif
|
timer_enable_intr(timer->group, timer->num);
|
||||||
static bool initialized = false;
|
|
||||||
static intr_handle_t intr_handle = NULL;
|
timer_info_t *timer_info = calloc(1, sizeof(timer_info_t));
|
||||||
if(intr_handle){
|
timer_info->timer_group = timer->group;
|
||||||
esp_intr_disable(intr_handle);
|
timer_info->timer_idx = timer->num;
|
||||||
}
|
timer_info->auto_reload = timerGetAutoReload(timer);
|
||||||
if(fn == NULL){
|
timer_info->alarm_interval = timerAlarmRead(timer);
|
||||||
timer->dev->config.level_int_en = 0;
|
|
||||||
timer->dev->config.edge_int_en = 0;
|
timer_isr_callback_add(timer->group, timer->num, (timer_isr_t)fn, timer_info, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerDetachInterrupt(hw_timer_t *timer){
|
void timerDetachInterrupt(hw_timer_t *timer){
|
||||||
@ -354,6 +246,12 @@ uint64_t timerReadMicros(hw_timer_t *timer){
|
|||||||
return timer_val * div / (getApbFrequency() / 1000000);
|
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){
|
double timerReadSeconds(hw_timer_t *timer){
|
||||||
uint64_t timer_val = timerRead(timer);
|
uint64_t timer_val = timerRead(timer);
|
||||||
uint16_t div = timerGetDivider(timer);
|
uint16_t div = timerGetDivider(timer);
|
||||||
@ -366,6 +264,12 @@ uint64_t timerAlarmReadMicros(hw_timer_t *timer){
|
|||||||
return timer_val * div / (getApbFrequency() / 1000000);
|
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){
|
double timerAlarmReadSeconds(hw_timer_t *timer){
|
||||||
uint64_t timer_val = timerAlarmRead(timer);
|
uint64_t timer_val = timerAlarmRead(timer);
|
||||||
uint16_t div = timerGetDivider(timer);
|
uint16_t div = timerGetDivider(timer);
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
#ifndef MAIN_ESP32_HAL_TIMER_H_
|
#ifndef MAIN_ESP32_HAL_TIMER_H_
|
||||||
#define MAIN_ESP32_HAL_TIMER_H_
|
#define MAIN_ESP32_HAL_TIMER_H_
|
||||||
|
|
||||||
|
#include "esp32-hal.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "esp32-hal.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
|
|
||||||
struct hw_timer_s;
|
struct hw_timer_s;
|
||||||
typedef struct hw_timer_s hw_timer_t;
|
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);
|
bool timerStarted(hw_timer_t *timer);
|
||||||
uint64_t timerRead(hw_timer_t *timer);
|
uint64_t timerRead(hw_timer_t *timer);
|
||||||
uint64_t timerReadMicros(hw_timer_t *timer);
|
uint64_t timerReadMicros(hw_timer_t *timer);
|
||||||
|
uint64_t timerReadMilis(hw_timer_t *timer);
|
||||||
double timerReadSeconds(hw_timer_t *timer);
|
double timerReadSeconds(hw_timer_t *timer);
|
||||||
uint16_t timerGetDivider(hw_timer_t *timer);
|
uint16_t timerGetDivider(hw_timer_t *timer);
|
||||||
bool timerGetCountUp(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 timerAlarmEnable(hw_timer_t *timer);
|
||||||
void timerAlarmDisable(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);
|
bool timerAlarmEnabled(hw_timer_t *timer);
|
||||||
uint64_t timerAlarmRead(hw_timer_t *timer);
|
uint64_t timerAlarmRead(hw_timer_t *timer);
|
||||||
|
@ -34,9 +34,16 @@
|
|||||||
#include "esp32-hal.h"
|
#include "esp32-hal.h"
|
||||||
|
|
||||||
#include "esp32-hal-tinyusb.h"
|
#include "esp32-hal-tinyusb.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2
|
||||||
#include "esp32s2/rom/usb/usb_persist.h"
|
#include "esp32s2/rom/usb/usb_persist.h"
|
||||||
#include "esp32s2/rom/usb/usb_dc.h"
|
#include "esp32s2/rom/usb/usb_dc.h"
|
||||||
#include "esp32s2/rom/usb/chip_usb_dw_wrapper.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{
|
typedef enum{
|
||||||
TINYUSB_USBDEV_0,
|
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 bool usb_persist_enabled = false;
|
||||||
static restart_type_t usb_persist_mode = RESTART_NO_PERSIST;
|
static restart_type_t usb_persist_mode = RESTART_NO_PERSIST;
|
||||||
|
|
||||||
|
#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){
|
static bool tinyusb_reserve_in_endpoint(uint8_t endpoint){
|
||||||
if(endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0){
|
if(endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0){
|
||||||
return false;
|
return false;
|
||||||
@ -515,35 +636,6 @@ static void tinyusb_apply_device_config(tinyusb_device_config_t *config){
|
|||||||
tinyusb_device_descriptor.bDeviceProtocol = config->usb_protocol;
|
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
|
// USB Device Driver task
|
||||||
// This top level thread processes all usb events and invokes callbacks
|
// This top level thread processes all usb events and invokes callbacks
|
||||||
static void usb_device_task(void *param) {
|
static void usb_device_task(void *param) {
|
||||||
@ -607,11 +699,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
|
|||||||
periph_module_enable(PERIPH_USB_MODULE);
|
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 = {
|
tinyusb_config_t tusb_cfg = {
|
||||||
.external_phy = false // In the most cases you need to use a `false` value
|
.external_phy = false // In the most cases you need to use a `false` value
|
||||||
};
|
};
|
||||||
@ -624,14 +711,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
|
|||||||
return err;
|
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){
|
uint8_t tinyusb_add_string_descriptor(const char * str){
|
||||||
if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){
|
if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
#include "esp32-hal.h"
|
#include "esp32-hal.h"
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
|
||||||
#if CONFIG_TINYUSB_ENABLED
|
#if CONFIG_TINYUSB_ENABLED
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -105,4 +104,3 @@ uint8_t tinyusb_get_free_out_endpoint(void);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_TINYUSB_ENABLED */
|
#endif /* CONFIG_TINYUSB_ENABLED */
|
||||||
#endif /* CONFIG_IDF_TARGET_ESP32S2 */
|
|
||||||
|
@ -12,219 +12,268 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "esp32-hal-touch.h"
|
#include "soc/soc_caps.h"
|
||||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
#if SOC_TOUCH_SENSOR_NUM > 0
|
||||||
#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 "driver/touch_sensor.h"
|
#include "driver/touch_sensor.h"
|
||||||
|
#include "esp32-hal-touch.h"
|
||||||
|
|
||||||
#include "esp_system.h"
|
/*
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
Internal Private Touch Data Structure and Functions
|
||||||
#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
|
|
||||||
|
|
||||||
|
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||||
static uint16_t __touchSleepCycles = 0x1000;
|
static uint16_t __touchSleepCycles = 0x1000;
|
||||||
static uint16_t __touchMeasureCycles = 0x1000;
|
static uint16_t __touchMeasureCycles = 0x1000;
|
||||||
|
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||||
|
static uint16_t __touchSleepCycles = TOUCH_PAD_SLEEP_CYCLE_DEFAULT;
|
||||||
|
static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef void (*voidFuncPtr)(void);
|
typedef void (*voidFuncPtr)(void);
|
||||||
static voidFuncPtr __touchInterruptHandlers[10] = {0,};
|
typedef void (*voidArgFuncPtr)(void *);
|
||||||
static intr_handle_t touch_intr_handle = NULL;
|
|
||||||
|
|
||||||
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
|
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||||
uint32_t pad_intr = READ_PERI_REG(SENS_SAR_TOUCH_CTRL2_REG) & 0x3ff;
|
uint32_t pad_intr = touch_pad_get_status();
|
||||||
uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG);
|
|
||||||
uint8_t i = 0;
|
|
||||||
//clear interrupt
|
//clear interrupt
|
||||||
WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, rtc_intr);
|
touch_pad_clear_status();
|
||||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR);
|
// call Pad ISR User callback
|
||||||
|
for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||||
if (rtc_intr & RTC_CNTL_TOUCH_INT_ST) {
|
if ((pad_intr >> i) & 0x01) {
|
||||||
for (i = 0; i < 10; ++i) {
|
if(__touchInterruptHandlers[i].fn){
|
||||||
if ((pad_intr >> i) & 0x01) {
|
// keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)"
|
||||||
if(__touchInterruptHandlers[i]){
|
if (__touchInterruptHandlers[i].callWithArgs) {
|
||||||
__touchInterruptHandlers[i]();
|
((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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void __touchSetCycles(uint16_t measure, uint16_t sleep)
|
|
||||||
|
|
||||||
|
static void __touchSetCycles(uint16_t measure, uint16_t sleep)
|
||||||
{
|
{
|
||||||
__touchSleepCycles = sleep;
|
__touchSleepCycles = sleep;
|
||||||
__touchMeasureCycles = measure;
|
__touchMeasureCycles = measure;
|
||||||
#if 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);
|
touch_pad_set_meas_time(sleep, measure);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __touchInit()
|
|
||||||
|
|
||||||
|
static void __touchInit()
|
||||||
{
|
{
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
if(initialized){
|
if(initialized){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
initialized = true;
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
esp_err_t err = ESP_OK;
|
||||||
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);
|
#if SOC_TOUCH_VERSION_1 // ESP32
|
||||||
//clear touch enable
|
err = touch_pad_init();
|
||||||
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, 0x0);
|
if (err != ESP_OK) {
|
||||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_TOUCH_SLP_TIMER_EN);
|
goto err;
|
||||||
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles);
|
}
|
||||||
esp_intr_alloc(ETS_RTC_CORE_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, __touchISR, NULL, &touch_intr_handle);
|
// the next two lines will drive the touch reading values -- both will return ESP_OK
|
||||||
#else
|
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V);
|
||||||
touch_pad_init();
|
touch_pad_set_meas_time(__touchMeasureCycles, __touchSleepCycles);
|
||||||
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V5);
|
// Touch Sensor Timer initiated
|
||||||
touch_pad_set_idle_channel_connect(TOUCH_PAD_CONN_GND);
|
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK
|
||||||
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles);
|
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 = {
|
touch_pad_denoise_t denoise = {
|
||||||
.grade = TOUCH_PAD_DENOISE_BIT4,
|
.grade = TOUCH_PAD_DENOISE_BIT4,
|
||||||
.cap_level = TOUCH_PAD_DENOISE_CAP_L4,
|
.cap_level = TOUCH_PAD_DENOISE_CAP_L4,
|
||||||
};
|
};
|
||||||
touch_pad_denoise_set_config(&denoise);
|
touch_pad_denoise_set_config(&denoise);
|
||||||
touch_pad_denoise_enable();
|
touch_pad_denoise_enable();
|
||||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
// Touch Sensor Timer initiated
|
||||||
touch_pad_fsm_start();
|
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
|
#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);
|
int8_t pad = digitalPinToTouchChannel(pin);
|
||||||
if(pad < 0){
|
if(pad < 0){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pinMode(pin, ANALOG);
|
|
||||||
|
|
||||||
__touchInit();
|
__touchInit();
|
||||||
|
__touchChannelInit(pad);
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
touch_value_t touch_value;
|
||||||
uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
|
touch_pad_read_raw_data(pad, &touch_value);
|
||||||
//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)));
|
|
||||||
|
|
||||||
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;
|
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);
|
int8_t pad = digitalPinToTouchChannel(pin);
|
||||||
if(pad < 0){
|
if(pad < 0){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pinMode(pin, ANALOG);
|
if (userFunc == NULL) {
|
||||||
|
// dettach ISR User Call
|
||||||
__touchInit();
|
__touchInterruptHandlers[pad].fn = NULL;
|
||||||
|
threshold = SOC_TOUCH_PAD_THRESHOLD_MAX; // deactivate the ISR with SOC_TOUCH_PAD_THRESHOLD_MAX
|
||||||
__touchInterruptHandlers[pad] = userFunc;
|
} else {
|
||||||
|
// attach ISR User Call
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
__touchInit();
|
||||||
//clear touch force ,select the Touch mode is Timer
|
#if SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
|
__touchChannelInit(pad);
|
||||||
|
#endif
|
||||||
//interrupt when touch value < threshold
|
__touchInterruptHandlers[pad].fn = userFunc;
|
||||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL);
|
__touchInterruptHandlers[pad].callWithArgs = callWithArgs;
|
||||||
//Intr will give ,when SET0 < threshold
|
__touchInterruptHandlers[pad].arg = Args;
|
||||||
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 SOC_TOUCH_VERSION_1 // ESP32
|
||||||
|
touch_pad_config(pad, threshold);
|
||||||
|
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
|
||||||
|
touch_pad_set_thresh(pad, threshold);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint16_t touchRead(uint8_t pin) __attribute__ ((weak, alias("__touchRead")));
|
// it keeps backwards compatibility
|
||||||
extern void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold) __attribute__ ((weak, alias("__touchAttachInterrupt")));
|
static void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold)
|
||||||
extern void touchSetCycles(uint16_t measure, uint16_t sleep) __attribute__ ((weak, alias("__touchSetCycles")));
|
{
|
||||||
|
__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
|
#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" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
#include "esp32-hal.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
|
* Set cycles that measurement operation takes
|
||||||
* The result from touchRead, threshold and detection
|
* 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
|
* You can use this method to chose a good threshold value
|
||||||
* to use as value for touchAttachInterrupt
|
* 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
|
* Set function to be called if touch pad value falls (ESP32)
|
||||||
* below the given threshold. Use touchRead to determine
|
* below the given threshold / rises (ESP32-S2/S3) by given increment (threshold).
|
||||||
* a proper threshold between touched and untouched state
|
* 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */
|
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */
|
||||||
|
@ -34,7 +34,7 @@ struct uart_struct_t {
|
|||||||
uint8_t num;
|
uint8_t num;
|
||||||
bool has_peek;
|
bool has_peek;
|
||||||
uint8_t peek_byte;
|
uint8_t peek_byte;
|
||||||
|
QueueHandle_t uart_event_queue; // export it by some uartGetEventQueue() function
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CONFIG_DISABLE_HAL_LOCKS
|
#if CONFIG_DISABLE_HAL_LOCKS
|
||||||
@ -43,12 +43,12 @@ struct uart_struct_t {
|
|||||||
#define UART_MUTEX_UNLOCK()
|
#define UART_MUTEX_UNLOCK()
|
||||||
|
|
||||||
static uart_t _uart_bus_array[] = {
|
static uart_t _uart_bus_array[] = {
|
||||||
{0, false, 0},
|
{0, false, 0, NULL},
|
||||||
#if SOC_UART_NUM > 1
|
#if SOC_UART_NUM > 1
|
||||||
{1, false, 0},
|
{1, false, 0, NULL},
|
||||||
#endif
|
#endif
|
||||||
#if SOC_UART_NUM > 2
|
#if SOC_UART_NUM > 2
|
||||||
{2, false, 0},
|
{2, false, 0, NULL},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,21 +58,46 @@ static uart_t _uart_bus_array[] = {
|
|||||||
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
|
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
|
||||||
|
|
||||||
static uart_t _uart_bus_array[] = {
|
static uart_t _uart_bus_array[] = {
|
||||||
{NULL, 0, false, 0},
|
{NULL, 0, false, 0, NULL},
|
||||||
#if SOC_UART_NUM > 1
|
#if SOC_UART_NUM > 1
|
||||||
{NULL, 1, false, 0},
|
{NULL, 1, false, 0, NULL},
|
||||||
#endif
|
#endif
|
||||||
#if SOC_UART_NUM > 2
|
#if SOC_UART_NUM > 2
|
||||||
{NULL, 2, false, 0},
|
{NULL, 2, false, 0, NULL},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#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)
|
bool uartIsDriverInstalled(uart_t* uart)
|
||||||
{
|
{
|
||||||
if(uart == NULL) {
|
if(uart == NULL) {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uart_is_driver_installed(uart->num)) {
|
if (uart_is_driver_installed(uart->num)) {
|
||||||
@ -81,28 +106,36 @@ bool uartIsDriverInstalled(uart_t* uart)
|
|||||||
return false;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
UART_MUTEX_LOCK();
|
UART_MUTEX_LOCK();
|
||||||
ESP_ERROR_CHECK(uart_set_pin(uart->num, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
// IDF uart_set_pin() will issue necessary Error Message and take care of all GPIO Number validation.
|
||||||
UART_MUTEX_UNLOCK();
|
uart_set_pin(uart->num, txPin, rxPin, ctsPin, rtsPin);
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold) {
|
||||||
|
if(uart == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// IDF will issue corresponding error message when mode or threshold are wrong and prevent crashing
|
||||||
|
// IDF will check (mode > HW_FLOWCTRL_CTS_RTS || threshold >= SOC_UART_FIFO_LEN)
|
||||||
|
uart_set_hw_flow_ctrl(uart->num, (uart_hw_flowcontrol_t) mode, threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted, uint8_t rxfifo_full_thrhd)
|
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t rx_buffer_size, uint16_t tx_buffer_size, bool inverted, uint8_t rxfifo_full_thrhd)
|
||||||
{
|
{
|
||||||
if(uart_nr >= SOC_UART_NUM) {
|
if(uart_nr >= SOC_UART_NUM) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rxPin == -1 && txPin == -1) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uart_t* uart = &_uart_bus_array[uart_nr];
|
uart_t* uart = &_uart_bus_array[uart_nr];
|
||||||
|
|
||||||
if (uart_is_driver_installed(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_MUTEX_LOCK();
|
||||||
|
|
||||||
uart_config_t uart_config;
|
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.data_bits = (config & 0xc) >> 2;
|
||||||
uart_config.parity = (config & 0x3);
|
uart_config.parity = (config & 0x3);
|
||||||
uart_config.stop_bits = (config & 0x30) >> 4;
|
uart_config.stop_bits = (config & 0x30) >> 4;
|
||||||
@ -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;
|
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_param_config(uart_nr, &uart_config));
|
||||||
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
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();
|
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 ) {
|
if ( !txOnly ) {
|
||||||
ESP_ERROR_CHECK(uart_flush_input(uart->num));
|
ESP_ERROR_CHECK(uart_flush_input(uart->num));
|
||||||
@ -304,7 +337,7 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UART_MUTEX_LOCK();
|
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();
|
UART_MUTEX_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,11 +421,12 @@ int log_printf(const char *format, ...)
|
|||||||
va_list copy;
|
va_list copy;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
va_copy(copy, arg);
|
va_copy(copy, arg);
|
||||||
len = vsnprintf(NULL, 0, format, arg);
|
len = vsnprintf(NULL, 0, format, copy);
|
||||||
va_end(copy);
|
va_end(copy);
|
||||||
if(len >= sizeof(loc_buf)){
|
if(len >= sizeof(loc_buf)){
|
||||||
temp = (char*)malloc(len+1);
|
temp = (char*)malloc(len+1);
|
||||||
if(temp == NULL) {
|
if(temp == NULL) {
|
||||||
|
va_end(arg);
|
||||||
return 0;
|
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)
|
unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32S3
|
||||||
if(uart == NULL) {
|
if(uart == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -471,6 +506,9 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
|
|||||||
UART_MUTEX_UNLOCK();
|
UART_MUTEX_UNLOCK();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -515,7 +553,7 @@ void uartStartDetectBaudrate(uart_t *uart) {
|
|||||||
//hw->rx_filt.glitch_filt_en = 1;
|
//hw->rx_filt.glitch_filt_en = 1;
|
||||||
//hw->conf0.autobaud_en = 0;
|
//hw->conf0.autobaud_en = 0;
|
||||||
//hw->conf0.autobaud_en = 1;
|
//hw->conf0.autobaud_en = 1;
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
#else
|
#else
|
||||||
hw->auto_baud.glitch_filt = 0x08;
|
hw->auto_baud.glitch_filt = 0x08;
|
||||||
hw->auto_baud.en = 0;
|
hw->auto_baud.en = 0;
|
||||||
@ -552,6 +590,7 @@ uartDetectBaudrate(uart_t *uart)
|
|||||||
|
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||||
//hw->conf0.autobaud_en = 0;
|
//hw->conf0.autobaud_en = 0;
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
#else
|
#else
|
||||||
hw->auto_baud.en = 0;
|
hw->auto_baud.en = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,6 +22,8 @@ extern "C" {
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
|
||||||
#define SERIAL_5N1 0x8000010
|
#define SERIAL_5N1 0x8000010
|
||||||
#define SERIAL_6N1 0x8000014
|
#define SERIAL_6N1 0x8000014
|
||||||
@ -48,12 +50,23 @@ extern "C" {
|
|||||||
#define SERIAL_7O2 0x800003b
|
#define SERIAL_7O2 0x800003b
|
||||||
#define SERIAL_8O2 0x800003f
|
#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;
|
struct uart_struct_t;
|
||||||
typedef struct uart_struct_t uart_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);
|
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 uartAvailable(uart_t* uart);
|
||||||
uint32_t uartAvailableForWrite(uart_t* uart);
|
uint32_t uartAvailableForWrite(uart_t* uart);
|
||||||
uint8_t uartRead(uart_t* uart);
|
uint8_t uartRead(uart_t* uart);
|
||||||
@ -74,7 +87,12 @@ void uartSetDebug(uart_t* uart);
|
|||||||
int uartGetDebug();
|
int uartGetDebug();
|
||||||
|
|
||||||
bool uartIsDriverInstalled(uart_t* uart);
|
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);
|
void uartStartDetectBaudrate(uart_t *uart);
|
||||||
unsigned long uartDetectBaudrate(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
|
//returns chip temperature in Celsius
|
||||||
float temperatureRead();
|
float temperatureRead();
|
||||||
|
|
||||||
|
//allows user to bypass SPI RAM test routine
|
||||||
|
bool testSPIRAM(void);
|
||||||
|
|
||||||
#if CONFIG_AUTOSTART_ARDUINO
|
#if CONFIG_AUTOSTART_ARDUINO
|
||||||
//enable/disable WDT for Arduino's setup and loop functions
|
//enable/disable WDT for Arduino's setup and loop functions
|
||||||
void enableLoopWDT();
|
void enableLoopWDT();
|
||||||
|
@ -23,7 +23,7 @@ extern "C" {
|
|||||||
/** Minor version number (x.X.x) */
|
/** Minor version number (x.X.x) */
|
||||||
#define ESP_ARDUINO_VERSION_MINOR 0
|
#define ESP_ARDUINO_VERSION_MINOR 0
|
||||||
/** Patch version number (x.x.X) */
|
/** Patch version number (x.x.X) */
|
||||||
#define ESP_ARDUINO_VERSION_PATCH 0
|
#define ESP_ARDUINO_VERSION_PATCH 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Macro to convert ARDUINO version number into an integer
|
* Macro to convert ARDUINO version number into an integer
|
||||||
|
0
cores/esp32/libb64/AUTHORS
Executable file → Normal file
0
cores/esp32/libb64/AUTHORS
Executable file → Normal file
0
cores/esp32/libb64/LICENSE
Executable file → Normal file
0
cores/esp32/libb64/LICENSE
Executable file → Normal file
0
cores/esp32/libb64/cdecode.c
Executable file → Normal file
0
cores/esp32/libb64/cdecode.c
Executable file → Normal file
0
cores/esp32/libb64/cdecode.h
Executable file → Normal file
0
cores/esp32/libb64/cdecode.h
Executable file → Normal file
0
cores/esp32/libb64/cencode.c
Executable file → Normal file
0
cores/esp32/libb64/cencode.c
Executable file → Normal file
0
cores/esp32/libb64/cencode.h
Executable file → Normal file
0
cores/esp32/libb64/cencode.h
Executable file → Normal file
@ -2,7 +2,7 @@
|
|||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
#include "Arduino.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"
|
#include "USB.h"
|
||||||
#if ARDUINO_USB_MSC_ON_BOOT
|
#if ARDUINO_USB_MSC_ON_BOOT
|
||||||
#include "FirmwareMSC.h"
|
#include "FirmwareMSC.h"
|
||||||
@ -33,6 +33,10 @@ void yieldIfNecessary(void){
|
|||||||
|
|
||||||
bool loopTaskWDTEnabled;
|
bool loopTaskWDTEnabled;
|
||||||
|
|
||||||
|
__attribute__((weak)) size_t getArduinoLoopTaskStackSize(void) {
|
||||||
|
return ARDUINO_LOOP_STACK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
void loopTask(void *pvParameters)
|
void loopTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
setup();
|
setup();
|
||||||
@ -50,21 +54,21 @@ void loopTask(void *pvParameters)
|
|||||||
|
|
||||||
extern "C" void app_main()
|
extern "C" void app_main()
|
||||||
{
|
{
|
||||||
#if ARDUINO_USB_CDC_ON_BOOT
|
#if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE
|
||||||
Serial.begin();
|
Serial.begin();
|
||||||
#endif
|
#endif
|
||||||
#if ARDUINO_USB_MSC_ON_BOOT
|
#if ARDUINO_USB_MSC_ON_BOOT && !ARDUINO_USB_MODE
|
||||||
MSC_Update.begin();
|
MSC_Update.begin();
|
||||||
#endif
|
#endif
|
||||||
#if ARDUINO_USB_DFU_ON_BOOT
|
#if ARDUINO_USB_DFU_ON_BOOT && !ARDUINO_USB_MODE
|
||||||
USB.enableDFU();
|
USB.enableDFU();
|
||||||
#endif
|
#endif
|
||||||
#if ARDUINO_USB_ON_BOOT
|
#if ARDUINO_USB_ON_BOOT && !ARDUINO_USB_MODE
|
||||||
USB.begin();
|
USB.begin();
|
||||||
#endif
|
#endif
|
||||||
loopTaskWDTEnabled = false;
|
loopTaskWDTEnabled = false;
|
||||||
initArduino();
|
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
|
#endif
|
||||||
|
@ -88,7 +88,7 @@ char* ultoa(unsigned long value, char* result, int base) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
|
char * dtostrf(double number, signed int width, unsigned int prec, char *s) {
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
|
|
||||||
if (isnan(number)) {
|
if (isnan(number)) {
|
||||||
@ -117,7 +117,7 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
|
|||||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||||
// I optimized out most of the divisions
|
// I optimized out most of the divisions
|
||||||
double rounding = 2.0;
|
double rounding = 2.0;
|
||||||
for (uint8_t i = 0; i < prec; ++i)
|
for (uint32_t i = 0; i < prec; ++i)
|
||||||
rounding *= 10.0;
|
rounding *= 10.0;
|
||||||
rounding = 1.0 / rounding;
|
rounding = 1.0 / rounding;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ char* utoa (unsigned int val, char *s, int radix);
|
|||||||
|
|
||||||
char* ultoa (unsigned long val, char *s, int radix);
|
char* ultoa (unsigned long val, char *s, int radix);
|
||||||
|
|
||||||
char* dtostrf (double val, signed char width, unsigned char prec, char *s);
|
char* dtostrf (double val, signed int width, unsigned int prec, char *s);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // 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
|
# matplotlib is currently required only by the script generate_chart.py
|
||||||
sphinx-copybutton==0.3.0
|
sphinx-copybutton==0.3.0
|
||||||
|
sphinx-tabs==3.2.0
|
BIN
docs/source/_static/gpio_output.png
Normal file
BIN
docs/source/_static/gpio_output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
BIN
docs/source/_static/gpio_pullup.png
Normal file
BIN
docs/source/_static/gpio_pullup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
BIN
docs/source/_static/logo_arduino.png
Normal file
BIN
docs/source/_static/logo_arduino.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
docs/source/_static/logo_pio.png
Normal file
BIN
docs/source/_static/logo_pio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
docs/source/_static/usb_msc_drive.png
Normal file
BIN
docs/source/_static/usb_msc_drive.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
208
docs/source/api/adc.rst
Normal file
208
docs/source/api/adc.rst
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
###
|
||||||
|
ADC
|
||||||
|
###
|
||||||
|
|
||||||
|
About
|
||||||
|
-----
|
||||||
|
|
||||||
|
ADC (analog to digital converter) is a very common peripheral used to convert an analog signal such as voltage
|
||||||
|
to a digital form so that it can be read and processed by a microcontroller.
|
||||||
|
|
||||||
|
ADCs are very useful in control and monitoring applications since most sensors
|
||||||
|
(e.g., temperature, pressure, force) produce analogue output voltages.
|
||||||
|
|
||||||
|
.. note:: Each SoC or module has a different number of ADC's with a different number of channels and pins availible. Refer to datasheet of each board for more info.
|
||||||
|
|
||||||
|
Arduino-ESP32 ADC API
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
ADC common API
|
||||||
|
**************
|
||||||
|
|
||||||
|
analogRead
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to get the ADC raw value for a given pin/ADC channel.
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
uint16_t analogRead(uint8_t pin);
|
||||||
|
|
||||||
|
* ``pin`` GPIO pin to read analog value
|
||||||
|
|
||||||
|
This function will return analog raw value.
|
||||||
|
|
||||||
|
analogReadMillivolts
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to get ADC value for a given pin/ADC channel in millivolts.
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
uint32_t analogReadMilliVolts(uint8_t pin);
|
||||||
|
|
||||||
|
* ``pin`` GPIO pin to read analog value
|
||||||
|
|
||||||
|
This function will return analog value in millivolts.
|
||||||
|
|
||||||
|
analogReadResolution
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to set the resolution of ``analogRead`` return value. Default is 12 bits (range from 0 to 4096)
|
||||||
|
for all chips except ESP32S3 where default is 13 bits (range from 0 to 8192).
|
||||||
|
When different resolution is set, the values read will be shifted to match the given resolution.
|
||||||
|
|
||||||
|
Range is 1 - 16 .The default value will be used, if this function is not used.
|
||||||
|
|
||||||
|
.. note:: For the ESP32, the resolution is between 9 to12 and it will change the ADC hardware resolution. Else value will be shifted.
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
void analogReadResolution(uint8_t bits);
|
||||||
|
|
||||||
|
* ``bits`` sets analog read resolution
|
||||||
|
|
||||||
|
analogSetClockDiv
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to set the divider for the ADC clock.
|
||||||
|
|
||||||
|
Range is 1 - 255. Default value is 1.
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
void analogSetClockDiv(uint8_t clockDiv);
|
||||||
|
|
||||||
|
* ``clockDiv`` sets the divider for ADC clock.
|
||||||
|
|
||||||
|
analogSetAttenuation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to set the attenuation for all channels.
|
||||||
|
|
||||||
|
Input voltages can be attenuated before being input to the ADCs.
|
||||||
|
There are 4 available attenuation options, the higher the attenuation is, the higher the measurable input voltage could be.
|
||||||
|
|
||||||
|
The measurable input voltage differs for each chip, see table below for detailed information.
|
||||||
|
|
||||||
|
.. tabs::
|
||||||
|
|
||||||
|
.. tab:: ESP32
|
||||||
|
|
||||||
|
===================== ===========================================
|
||||||
|
Attenuation Measurable input voltage range
|
||||||
|
===================== ===========================================
|
||||||
|
``ADC_ATTEN_DB_0`` 100 mV ~ 950 mV
|
||||||
|
``ADC_ATTEN_DB_2_5`` 100 mV ~ 1250 mV
|
||||||
|
``ADC_ATTEN_DB_6`` 150 mV ~ 1750 mV
|
||||||
|
``ADC_ATTEN_DB_11`` 150 mV ~ 2450 mV
|
||||||
|
===================== ===========================================
|
||||||
|
|
||||||
|
.. tab:: ESP32-S2
|
||||||
|
|
||||||
|
===================== ===========================================
|
||||||
|
Attenuation Measurable input voltage range
|
||||||
|
===================== ===========================================
|
||||||
|
``ADC_ATTEN_DB_0`` 0 mV ~ 750 mV
|
||||||
|
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1050 mV
|
||||||
|
``ADC_ATTEN_DB_6`` 0 mV ~ 1300 mV
|
||||||
|
``ADC_ATTEN_DB_11`` 0 mV ~ 2500 mV
|
||||||
|
===================== ===========================================
|
||||||
|
|
||||||
|
.. tab:: ESP32-C3
|
||||||
|
|
||||||
|
===================== ===========================================
|
||||||
|
Attenuation Measurable input voltage range
|
||||||
|
===================== ===========================================
|
||||||
|
``ADC_ATTEN_DB_0`` 0 mV ~ 750 mV
|
||||||
|
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1050 mV
|
||||||
|
``ADC_ATTEN_DB_6`` 0 mV ~ 1300 mV
|
||||||
|
``ADC_ATTEN_DB_11`` 0 mV ~ 2500 mV
|
||||||
|
===================== ===========================================
|
||||||
|
|
||||||
|
.. tab:: ESP32-S3
|
||||||
|
|
||||||
|
===================== ===========================================
|
||||||
|
Attenuation Measurable input voltage range
|
||||||
|
===================== ===========================================
|
||||||
|
``ADC_ATTEN_DB_0`` 0 mV ~ 950 mV
|
||||||
|
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1250 mV
|
||||||
|
``ADC_ATTEN_DB_6`` 0 mV ~ 1750 mV
|
||||||
|
``ADC_ATTEN_DB_11`` 0 mV ~ 3100 mV
|
||||||
|
===================== ===========================================
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
void analogSetAttenuation(adc_attenuation_t attenuation);
|
||||||
|
|
||||||
|
* ``attenuation`` sets the attenuation.
|
||||||
|
|
||||||
|
analogSetPinAttenuation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to set the attenuation for a specific pin/ADC channel. For more information refer to `analogSetAttenuation`_.
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation);
|
||||||
|
|
||||||
|
* ``pin`` selects specific pin for attenuation settings.
|
||||||
|
* ``attenuation`` sets the attenuation.
|
||||||
|
|
||||||
|
adcAttachPin
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to attach the pin to ADC (it will also clear any other analog mode that could be on)
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
bool adcAttachPin(uint8_t pin);
|
||||||
|
|
||||||
|
This function will return ``true`` if configuration is successful. Else returns ``false``.
|
||||||
|
|
||||||
|
ADC API specific for ESP32 chip
|
||||||
|
*******************************
|
||||||
|
|
||||||
|
analogSetWidth
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to set the hardware sample bits and read resolution.
|
||||||
|
Default is 12bit (0 - 4095).
|
||||||
|
Range is 9 - 12.
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
void analogSetWidth(uint8_t bits);
|
||||||
|
|
||||||
|
analogSetVRefPin
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to set pin to use for ADC calibration if the esp is not already calibrated (pins 25, 26 or 27).
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
void analogSetVRefPin(uint8_t pin);
|
||||||
|
|
||||||
|
* ``pin`` GPIO pin to set VRefPin for ADC calibration
|
||||||
|
|
||||||
|
hallRead
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
This function is used to get the ADC value of the HALL sensor conneted to pins 36(SVP) and 39(SVN).
|
||||||
|
|
||||||
|
.. code-block:: arduino
|
||||||
|
|
||||||
|
int hallRead();
|
||||||
|
|
||||||
|
This function will return the hall sensor value.
|
||||||
|
|
||||||
|
|
||||||
|
Example Applications
|
||||||
|
********************
|
||||||
|
|
||||||
|
Here is an example of how to use the ADC.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogRead/AnalogRead.ino
|
||||||
|
:language: arduino
|
||||||
|
|
||||||
|
Or you can run Arduino example 01.Basics -> AnalogReadSerial.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user