forked from espressif/arduino-esp32
Compare commits
50 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 |
54
.github/ISSUE_TEMPLATE/Feature-request.yml
vendored
Normal file
54
.github/ISSUE_TEMPLATE/Feature-request.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
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 ...
|
130
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
Normal file
130
.github/ISSUE_TEMPLATE/Issue-report.yml
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
name: Issue report
|
||||
description: Report any problem here
|
||||
labels: ["Status: Awaiting triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
* Before reporting a new issue please check and search in [List of existing issues](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue)
|
||||
* Please check [Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/index.html)
|
||||
* Take a look on [Troubleshooting guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html)
|
||||
* If still experiencing the issue, please provide as many details as possible below about your hardware, computer setup and code.
|
||||
- type: input
|
||||
id: Board
|
||||
attributes:
|
||||
label: Board
|
||||
description: On which Board does this issue occur?
|
||||
placeholder: eg. ESP32 Dev Module, ESP32-S2, LilyGo TTGO LoRa32...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: devboard
|
||||
attributes:
|
||||
label: Device Description
|
||||
description: What development board or other hardware is the chip attached to?
|
||||
placeholder: ex. DevKitC, plain module on breadboard, etc. If your hardware is custom or unusual, please attach a photo.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other-hw
|
||||
attributes:
|
||||
label: Hardware Configuration
|
||||
description: Is anything else attached to the development board?
|
||||
placeholder: ex. GPIO 18 & 19 are connected to I2C devices.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of Arduino ESP32 are you running? If possible, consider updating to the latest version.
|
||||
options:
|
||||
- latest master
|
||||
- v2.0.1
|
||||
- v2.0.0
|
||||
- v1.0.6
|
||||
- other
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: IDE
|
||||
attributes:
|
||||
label: IDE Name
|
||||
description: What IDE are you using?
|
||||
placeholder: eg. Arduino IDE, PlatformIO, IDF component...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: On which OS does this issue occur?
|
||||
placeholder: ex. macOS 12.1, Windows 10...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: Flash
|
||||
attributes:
|
||||
label: Flash frequency
|
||||
description: What flash frequency is used?
|
||||
placeholder: eg. 40Mhz
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: PSRAM
|
||||
attributes:
|
||||
label: PSRAM enabled
|
||||
description: Is PSRAM enabled?
|
||||
options:
|
||||
- 'yes'
|
||||
- 'no'
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: Upload
|
||||
attributes:
|
||||
label: Upload speed
|
||||
description: What upload speed is used?
|
||||
placeholder: eg. 115200
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Please describe your problem here and expected behaviour
|
||||
placeholder: ex. Can't connect/weird behaviour/wrong function/missing parameter..
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: sketch
|
||||
attributes:
|
||||
label: Sketch
|
||||
description: Please provide your sketch/code which was run
|
||||
placeholder: ex. related part of the code
|
||||
render: cpp
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Debug
|
||||
attributes:
|
||||
label: Debug Message
|
||||
description: Please provide a debug message or error message. If you have a Guru Meditation Error or Backtrace, please decode it with [ExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder)
|
||||
placeholder: Enable Core debug level - Debug on tools menu of Arduino IDE, then put the serial output here.
|
||||
render: plain
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other-remarks
|
||||
attributes:
|
||||
label: Other Steps to Reproduce
|
||||
description: Is there any other information you can think of which will help us reproduce this problem? Any additional info can be added as well.
|
||||
placeholder: ex. I also tried on other OS, HW...it works correctly on that setup.
|
||||
- type: checkboxes
|
||||
id: confirmation
|
||||
attributes:
|
||||
label: I have checked existing issues, online documentation and the Troubleshooting Guide
|
||||
description: You agree to check all the resources above before opening a new issue.
|
||||
options:
|
||||
- label: I confirm I have checked existing issues, online documentation and Troubleshooting guide.
|
||||
required: true
|
54
.github/ISSUE_TEMPLATE/bug_report.md
vendored
54
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,54 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Please fill in the bug report carefully
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Make your question, not a Statement, inclusive. Include all pertinent information:
|
||||
|
||||
What you are trying to do?
|
||||
Describe your system( Hardware, computer, O/S, core version, environment).
|
||||
Describe what is failing.
|
||||
Show the shortest possible code that will duplicate the error.
|
||||
Show the EXACT error message(it doesn't work is not enough).
|
||||
All of this work on your part shows us that you have worked to solve YOUR problem. The more complete your issue posting is, the more likely someone will volunteer their time to help you.
|
||||
|
||||
If you have a Guru Meditation Error or Backtrace, ***please decode it***:
|
||||
https://github.com/me-no-dev/EspExceptionDecoder
|
||||
|
||||
----------------------------- Remove above -----------------------------
|
||||
|
||||
|
||||
### Hardware:
|
||||
Board: ?ESP32 Dev Module? ?node32? ?ttgo_lora?
|
||||
Core Installation version: ?1.0.0? ?1.0.1-rc4? ?1.0.1? ?1.0.1-git? ?1.0.2? ?1.0.3?
|
||||
IDE name: ?Arduino IDE? ?Platform.io? ?IDF component?
|
||||
Flash Frequency: ?40Mhz?
|
||||
PSRAM enabled: ?no? ?yes?
|
||||
Upload Speed: ?115200?
|
||||
Computer OS: ?Windows 10? ?Mac OSX? ?Ubuntu?
|
||||
|
||||
### Description:
|
||||
Describe your problem here
|
||||
|
||||
|
||||
### Sketch: (leave the backquotes for [code formatting](https://help.github.com/articles/creating-and-highlighting-code-blocks/))
|
||||
```cpp
|
||||
|
||||
//Change the code below by your sketch
|
||||
#include <Arduino.h>
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
```
|
||||
|
||||
### Debug Messages:
|
||||
```
|
||||
Enable Core debug level: Debug on tools menu of Arduino IDE, then put the serial output here
|
||||
```
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Arduino ESP32 Gitter Channel
|
||||
url: https://gitter.im/espressif/arduino-esp32
|
||||
about: Community channel for questions and help
|
||||
- name: ESP32 Forum - Arduino
|
||||
url: https://esp32.com/viewforum.php?f=19
|
||||
about: Official Forum for questions
|
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,16 +1,18 @@
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
This entire section can be deleted if all items are checked.
|
||||
|
||||
*By completing this PR sufficiently, you help us to improve the quality of Release Notes*
|
||||
|
||||
### Checklist
|
||||
|
||||
1. [ ] Please provide specific title of the PR describing the change, including the component name (eg."Update of Documentation link on Readme.md")
|
||||
1. [ ] Please provide specific title of the PR describing the change, including the component name (eg. *„Update of Documentation link on Readme.md“*)
|
||||
2. [ ] Please provide related links (eg. Issue, other Project, submodule PR..)
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
3. [ ] Please check [Contributing guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html)
|
||||
|
||||
*This entire section above can be deleted if all items are checked.*
|
||||
|
||||
-----------
|
||||
## Summary
|
||||
Please describe your proposed PR and what it contains.
|
||||
|
||||
## Impact
|
||||
Please describe impact of your PR and it's function.
|
||||
|
||||
## Related links
|
||||
Please provide links to related issue, PRs etc.
|
||||
|
2
.github/scripts/check-cmakelists.sh
vendored
2
.github/scripts/check-cmakelists.sh
vendored
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This script is for Travis. It checks all non-examples source files in libraries/ and cores/ are listed in
|
||||
# This script is used in the CI workflow. It checks all non-examples source files in libraries/ and cores/ are listed in
|
||||
# CMakeLists.txt for the cmake-based IDF component
|
||||
#
|
||||
# If you see an error running this script, edit CMakeLists.txt and add any new source files into your PR
|
||||
|
0
.github/scripts/on-pages.sh
vendored
Normal file → Executable file
0
.github/scripts/on-pages.sh
vendored
Normal file → Executable file
13
.github/scripts/on-push.sh
vendored
13
.github/scripts/on-push.sh
vendored
@ -2,18 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
if [ ! -z "$TRAVIS_TAG" ]; then
|
||||
echo "Skipping Test: Tagged build"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -z "$GITHUB_WORKSPACE" ]; then
|
||||
export TRAVIS_BUILD_DIR="$GITHUB_WORKSPACE"
|
||||
export TRAVIS_REPO_SLUG="$GITHUB_REPOSITORY"
|
||||
elif [ ! -z "$TRAVIS_BUILD_DIR" ]; then
|
||||
export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR"
|
||||
export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG"
|
||||
else
|
||||
if [ -z "$GITHUB_WORKSPACE" ]; then
|
||||
export GITHUB_WORKSPACE="$PWD"
|
||||
export GITHUB_REPOSITORY="espressif/arduino-esp32"
|
||||
fi
|
||||
|
2
.github/workflows/gh-pages.yml
vendored
2
.github/workflows/gh-pages.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
name: Build GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
- name: Copy Files
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
12
.github/workflows/push.yml
vendored
12
.github/workflows/push.yml
vendored
@ -18,8 +18,8 @@ jobs:
|
||||
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build Sketches
|
||||
@ -34,8 +34,8 @@ jobs:
|
||||
os: [windows-latest, macOS-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build Sketches
|
||||
@ -50,8 +50,8 @@ jobs:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build Sketches
|
||||
|
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -10,10 +10,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v1
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build Release
|
||||
|
1
.github/workflows/test_selfhosted_runner.yml
vendored
1
.github/workflows/test_selfhosted_runner.yml
vendored
@ -10,6 +10,7 @@ jobs:
|
||||
build:
|
||||
name: Dummy test - self hosted GHR
|
||||
runs-on: self-hosted
|
||||
if: github.repository == 'espressif/arduino-esp32'
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v2
|
||||
|
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
|
@ -27,6 +27,10 @@ You can use [Arduino-ESP32 Online Documentation](https://docs.espressif.com/proj
|
||||
* [FAQ](https://docs.espressif.com/projects/arduino-esp32/en/latest/faq.html)
|
||||
* [Troubleshooting](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html)
|
||||
|
||||
### Supported Chips
|
||||
|
||||
Visit the [supported chips](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html#supported-soc-s) documentation to see the list of current supported ESP32 SoCs.
|
||||
|
||||
### Decoding exceptions
|
||||
|
||||
You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder) to get meaningful call trace.
|
||||
@ -34,7 +38,7 @@ You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecod
|
||||
### Issue/Bug report template
|
||||
Before reporting an issue, make sure you've searched for similar one that was already created. Also make sure to go through all the issues labelled as [Type: For reference](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue+label%3A%22Type%3A+For+reference%22+).
|
||||
|
||||
Finally, if you are sure no one else had the issue, follow the [issue template](docs/ISSUE_TEMPLATE.md) while reporting any issue.
|
||||
Finally, if you are sure no one else had the issue, follow the **Issue template** or **Feature request template** while reporting any [new Issue](https://github.com/espressif/arduino-esp32/issues/new/choose).
|
||||
|
||||
### Contributing
|
||||
|
||||
|
1200
boards.txt
1200
boards.txt
File diff suppressed because it is too large
Load Diff
@ -179,6 +179,9 @@ uint16_t makeWord(uint8_t h, uint8_t l);
|
||||
|
||||
#define word(...) makeWord(__VA_ARGS__)
|
||||
|
||||
size_t getArduinoLoopTaskStackSize(void);
|
||||
#define SET_LOOP_TASK_STACK_SIZE(sz) size_t getArduinoLoopTaskStackSize() { return sz;}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <Arduino.h>
|
||||
#include <MD5Builder.h>
|
||||
|
||||
uint8_t hex_char_to_byte(uint8_t c)
|
||||
static uint8_t hex_char_to_byte(uint8_t c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) :
|
||||
(c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) :
|
||||
@ -28,13 +28,13 @@ uint8_t hex_char_to_byte(uint8_t c)
|
||||
|
||||
void MD5Builder::begin(void)
|
||||
{
|
||||
memset(_buf, 0x00, 16);
|
||||
MD5Init(&_ctx);
|
||||
memset(_buf, 0x00, ESP_ROM_MD5_DIGEST_LEN);
|
||||
esp_rom_md5_init(&_ctx);
|
||||
}
|
||||
|
||||
void MD5Builder::add(uint8_t * data, uint16_t len)
|
||||
{
|
||||
MD5Update(&_ctx, data, len);
|
||||
esp_rom_md5_update(&_ctx, data, len);
|
||||
}
|
||||
|
||||
void MD5Builder::addHexString(const char * data)
|
||||
@ -82,7 +82,7 @@ bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
|
||||
}
|
||||
|
||||
// Update MD5 with buffer payload
|
||||
MD5Update(&_ctx, buf, numBytesRead);
|
||||
esp_rom_md5_update(&_ctx, buf, numBytesRead);
|
||||
|
||||
// update available number of bytes
|
||||
maxLengthLeft -= numBytesRead;
|
||||
@ -94,24 +94,24 @@ bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
|
||||
|
||||
void MD5Builder::calculate(void)
|
||||
{
|
||||
MD5Final(_buf, &_ctx);
|
||||
esp_rom_md5_final(_buf, &_ctx);
|
||||
}
|
||||
|
||||
void MD5Builder::getBytes(uint8_t * output)
|
||||
{
|
||||
memcpy(output, _buf, 16);
|
||||
memcpy(output, _buf, ESP_ROM_MD5_DIGEST_LEN);
|
||||
}
|
||||
|
||||
void MD5Builder::getChars(char * output)
|
||||
{
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
for(uint8_t i = 0; i < ESP_ROM_MD5_DIGEST_LEN; i++) {
|
||||
sprintf(output + (i * 2), "%02x", _buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
String MD5Builder::toString(void)
|
||||
{
|
||||
char out[33];
|
||||
char out[(ESP_ROM_MD5_DIGEST_LEN * 2) + 1];
|
||||
getChars(out);
|
||||
return String(out);
|
||||
}
|
||||
|
@ -23,25 +23,13 @@
|
||||
#include <Stream.h>
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/md5_hash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/md5_hash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/md5_hash.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/md5_hash.h"
|
||||
#endif
|
||||
#include "esp_rom_md5.h"
|
||||
|
||||
class MD5Builder
|
||||
{
|
||||
private:
|
||||
struct MD5Context _ctx;
|
||||
uint8_t _buf[16];
|
||||
md5_context_t _ctx;
|
||||
uint8_t _buf[ESP_ROM_MD5_DIGEST_LEN];
|
||||
public:
|
||||
void begin(void);
|
||||
void add(uint8_t * data, uint16_t len);
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
|
||||
cbuf *next;
|
||||
|
||||
private:
|
||||
protected:
|
||||
inline char* wrap_if_bufend(char* ptr) const
|
||||
{
|
||||
return (ptr == _bufend) ? _buf : ptr;
|
||||
|
@ -13,51 +13,37 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#define DAC1 25
|
||||
#define DAC2 26
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#define DAC1 17
|
||||
#define DAC2 18
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#ifndef SOC_DAC_SUPPORTED
|
||||
#define NODAC
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
|
||||
#ifndef NODAC
|
||||
#include "esp_attr.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/rtc_io_periph.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "driver/dac.h"
|
||||
#include "soc/dac_channel.h"
|
||||
#include "driver/dac_common.h"
|
||||
|
||||
void ARDUINO_ISR_ATTR __dacWrite(uint8_t pin, uint8_t value)
|
||||
{
|
||||
if(pin < DAC1 || pin > DAC2){
|
||||
if(pin < DAC_CHANNEL_1_GPIO_NUM || pin > DAC_CHANNEL_2_GPIO_NUM){
|
||||
return;//not dac pin
|
||||
}
|
||||
pinMode(pin, ANALOG);
|
||||
uint8_t channel = pin - DAC1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
SENS.sar_dac_ctrl1.dac_clkgate_en = 1;
|
||||
#endif
|
||||
RTCIO.pad_dac[channel].dac_xpd_force = 1;
|
||||
RTCIO.pad_dac[channel].xpd_dac = 1;
|
||||
if (channel == 0) {
|
||||
SENS.sar_dac_ctrl2.dac_cw_en1 = 0;
|
||||
} else if (channel == 1) {
|
||||
SENS.sar_dac_ctrl2.dac_cw_en2 = 0;
|
||||
|
||||
uint8_t channel = pin - DAC_CHANNEL_1_GPIO_NUM;
|
||||
dac_output_enable(channel);
|
||||
dac_output_voltage(channel, value);
|
||||
|
||||
}
|
||||
|
||||
void ARDUINO_ISR_ATTR __dacDisable(uint8_t pin)
|
||||
{
|
||||
if(pin < DAC_CHANNEL_1_GPIO_NUM || pin > DAC_CHANNEL_2_GPIO_NUM){
|
||||
return;//not dac pin
|
||||
}
|
||||
RTCIO.pad_dac[channel].dac = value;
|
||||
|
||||
uint8_t channel = pin - DAC_CHANNEL_1_GPIO_NUM;
|
||||
dac_output_disable(channel);
|
||||
}
|
||||
|
||||
extern void dacWrite(uint8_t pin, uint8_t value) __attribute__ ((weak, alias("__dacWrite")));
|
||||
extern void dacDisable(uint8_t pin) __attribute__ ((weak, alias("__dacDisable")));
|
||||
|
||||
#endif
|
||||
|
@ -28,6 +28,7 @@ extern "C" {
|
||||
#include "driver/gpio.h"
|
||||
|
||||
void dacWrite(uint8_t pin, uint8_t value);
|
||||
void dacDisable(uint8_t pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -37,6 +37,12 @@
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#define GPIO_FUNC 1
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "esp32c3/rom/gpio.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#define USE_ESP_IDF_GPIO 1
|
||||
#else
|
||||
#define USE_ESP_IDF_GPIO 1
|
||||
#endif
|
||||
@ -143,6 +149,29 @@ const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT]={
|
||||
{0xb8, -1, -1, -1},//SCL?
|
||||
{0xbc, -1, -1, -1},//INPUT ONLY
|
||||
{0, -1, -1, -1}
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
{0x04, -1, 0, -1}, // ADC1_CH0
|
||||
{0x08, -1, 1, -1}, // ADC1_CH1
|
||||
{0x0c, -1, 2, -1}, // ADC1_CH2 | FSPIQ
|
||||
{0x10, -1, 3, -1}, // ADC1_CH3
|
||||
{0x14, -1, 4, -1}, // MTMS | ADC1_CH4 | FSPIHD
|
||||
{0x18, -1, 5, -1}, // MTDI | ADC2_CH0 | FSPIWP
|
||||
{0x1c, -1, -1, -1}, // MTCK | FSPICLK
|
||||
{0x20, -1, -1, -1}, // MTDO | FSPID
|
||||
{0x24, -1, -1, -1}, //
|
||||
{0x28, -1, -1, -1}, //
|
||||
{0x2c, -1, -1, -1}, // FSPICSO
|
||||
{0x30, -1, -1, -1}, //
|
||||
{0x34, -1, -1, -1}, // SPIHD
|
||||
{0x38, -1, -1, -1}, // SPIWP
|
||||
{0x3c, -1, -1, -1}, // SPICSO
|
||||
{0x40, -1, -1, -1}, // SPICLK
|
||||
{0x44, -1, -1, -1}, // SPID
|
||||
{0x48, -1, -1, -1}, // SPIQ
|
||||
{0x4c, -1, -1, -1}, // USB-
|
||||
{0x50, -1, -1, -1}, // USB+
|
||||
{0x54, -1, -1, -1}, // U0RXD
|
||||
{0x58, -1, -1, -1}, // U0TXD
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -481,4 +510,3 @@ extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")
|
||||
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
|
||||
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
|
||||
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
|
||||
|
||||
|
2
cores/esp32/esp32-hal-i2c-slave.c
Executable file → Normal file
2
cores/esp32/esp32-hal-i2c-slave.c
Executable file → Normal file
@ -302,7 +302,7 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
|
||||
i2c_ll_slave_init(i2c->dev);
|
||||
i2c_ll_set_fifo_mode(i2c->dev, true);
|
||||
i2c_ll_set_slave_addr(i2c->dev, slaveID, false);
|
||||
i2c_ll_set_tout(i2c->dev, 32000);
|
||||
i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT);
|
||||
i2c_slave_set_frequency(i2c, frequency);
|
||||
|
||||
if (!i2c_slave_check_line_state(sda, scl)) {
|
||||
|
0
cores/esp32/esp32-hal-i2c-slave.h
Executable file → Normal file
0
cores/esp32/esp32-hal-i2c-slave.h
Executable file → Normal file
@ -24,6 +24,7 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/i2c_periph.h"
|
||||
#include "hal/i2c_hal.h"
|
||||
#include "hal/i2c_ll.h"
|
||||
#include "driver/i2c.h"
|
||||
|
||||
typedef volatile struct {
|
||||
@ -91,6 +92,8 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency){
|
||||
} else {
|
||||
bus[i2c_num].initialized = true;
|
||||
bus[i2c_num].frequency = frequency;
|
||||
//Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2
|
||||
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
|
@ -13,46 +13,25 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/ledc_reg.h"
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/ledc.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#define LAST_CHAN (15)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#define LAST_CHAN (7)
|
||||
#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#define LAST_CHAN (7)
|
||||
#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V
|
||||
#ifdef SOC_LEDC_SUPPORT_HS_MODE
|
||||
#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1)
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM)
|
||||
#endif
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
#define LEDC_MUTEX_LOCK()
|
||||
#define LEDC_MUTEX_UNLOCK()
|
||||
//Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz
|
||||
//Need to be fixed in ESP-IDF
|
||||
#ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK
|
||||
#define LEDC_DEFAULT_CLK LEDC_USE_XTAL_CLK
|
||||
#else
|
||||
#define LEDC_MUTEX_LOCK() do {} while (xSemaphoreTake(_ledc_sys_lock, portMAX_DELAY) != pdPASS)
|
||||
#define LEDC_MUTEX_UNLOCK() xSemaphoreGive(_ledc_sys_lock)
|
||||
xSemaphoreHandle _ledc_sys_lock = NULL;
|
||||
#define LEDC_DEFAULT_CLK LEDC_AUTO_CLK
|
||||
#endif
|
||||
|
||||
#define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM
|
||||
|
||||
/*
|
||||
* LEDC Chan to Group/Channel/Timer Mapping
|
||||
** ledc: 0 => Group: 0, Channel: 0, Timer: 0
|
||||
@ -72,203 +51,55 @@ xSemaphoreHandle _ledc_sys_lock = NULL;
|
||||
** ledc: 14 => Group: 1, Channel: 6, Timer: 3
|
||||
** ledc: 15 => Group: 1, Channel: 7, Timer: 3
|
||||
*/
|
||||
#define LEDC_CHAN(g,c) LEDC.channel_group[(g)].channel[(c)]
|
||||
#define LEDC_TIMER(g,t) LEDC.timer_group[(g)].timer[(t)]
|
||||
|
||||
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
||||
if(ev_type == APB_AFTER_CHANGE && old_apb != new_apb){
|
||||
uint16_t iarg = *(uint16_t*)arg;
|
||||
uint8_t chan = 0;
|
||||
old_apb /= 1000000;
|
||||
new_apb /= 1000000;
|
||||
while(iarg){ // run though all active channels, adjusting timing configurations
|
||||
if(iarg & 1) {// this channel is active
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
if(LEDC_TIMER(group, timer).conf.tick_sel){
|
||||
LEDC_MUTEX_LOCK();
|
||||
uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider;
|
||||
uint32_t div_num = (new_apb * old_div) / old_apb;
|
||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V){
|
||||
div_num = ((REF_CLK_FREQ /1000000) * old_div) / old_apb;
|
||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
|
||||
}
|
||||
LEDC_TIMER(group, timer).conf.tick_sel = 0;
|
||||
} else if(div_num < 256) {
|
||||
div_num = 256;//highest clock possible
|
||||
}
|
||||
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
}
|
||||
else {
|
||||
log_d("using REF_CLK chan=%d",chan);
|
||||
}
|
||||
}
|
||||
iarg = iarg >> 1;
|
||||
chan++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//uint32_t frequency = (80MHz or 1MHz)/((div_num / 256.0)*(1 << bit_num));
|
||||
static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, bool apb_clk)
|
||||
{
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
static bool tHasStarted = false;
|
||||
static uint16_t _activeChannels = 0;
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
// ESP32-S2 TRM v1.0 on Page 789 -> BIT LEDC_TICK_SEL_TIMERx is 0 for LEDC_PWM_CLK and 1 for REF_TICK
|
||||
apb_clk = 0;
|
||||
#endif
|
||||
if(!tHasStarted) {
|
||||
tHasStarted = true;
|
||||
periph_module_enable(PERIPH_LEDC_MODULE);
|
||||
LEDC.conf.apb_clk_sel = 1;//LS use apb clock
|
||||
addApbChangeCallback((void*)&_activeChannels, _on_apb_change);
|
||||
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
_ledc_sys_lock = xSemaphoreCreateMutex();
|
||||
#endif
|
||||
}
|
||||
LEDC_MUTEX_LOCK();
|
||||
LEDC_TIMER(group, timer).conf.clock_divider = div_num;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part.
|
||||
LEDC_TIMER(group, timer).conf.duty_resolution = bit_num;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20.
|
||||
LEDC_TIMER(group, timer).conf.tick_sel = apb_clk;//apb clock
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(group) {
|
||||
#endif
|
||||
LEDC_TIMER(group, timer).conf.low_speed_update = 1;//This bit is only useful for low speed timer channels, reserved for high speed timers
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
}
|
||||
#endif
|
||||
LEDC_TIMER(group, timer).conf.pause = 0;
|
||||
LEDC_TIMER(group, timer).conf.rst = 1;//This bit is used to reset timer the counter will be 0 after reset.
|
||||
LEDC_TIMER(group, timer).conf.rst = 0;
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
_activeChannels |= (1 << chan); // mark as active for APB callback
|
||||
}
|
||||
|
||||
//max div_num 0x3FFFF (262143)
|
||||
//max bit_num 0x1F (31)
|
||||
static double _ledcSetupTimerFreq(uint8_t chan, double freq, uint8_t bit_num)
|
||||
{
|
||||
uint64_t clk_freq = getApbFrequency();
|
||||
clk_freq <<= 8;//div_num is 8 bit decimal
|
||||
uint32_t div_num = (clk_freq >> bit_num) / freq;
|
||||
bool apb_clk = true;
|
||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
clk_freq /= 80;
|
||||
div_num = (clk_freq >> bit_num) / freq;
|
||||
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
|
||||
}
|
||||
apb_clk = false;
|
||||
} else if(div_num < 256) {
|
||||
div_num = 256;//highest clock possible
|
||||
}
|
||||
_ledcSetupTimer(chan, div_num, bit_num, apb_clk);
|
||||
//log_i("Fin: %f, Fclk: %uMhz, bits: %u, DIV: %u, Fout: %f",
|
||||
// freq, apb_clk?80:1, bit_num, div_num, (clk_freq >> bit_num) / (double)div_num);
|
||||
return (clk_freq >> bit_num) / (double)div_num;
|
||||
}
|
||||
|
||||
static double _ledcTimerRead(uint8_t chan)
|
||||
{
|
||||
uint32_t div_num;
|
||||
uint8_t bit_num;
|
||||
bool apb_clk;
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
LEDC_MUTEX_LOCK();
|
||||
div_num = LEDC_TIMER(group, timer).conf.clock_divider;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part.
|
||||
bit_num = LEDC_TIMER(group, timer).conf.duty_resolution;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20.
|
||||
apb_clk = LEDC_TIMER(group, timer).conf.tick_sel;//apb clock
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
uint64_t clk_freq = 1000000;
|
||||
if(apb_clk) {
|
||||
clk_freq = getApbFrequency();
|
||||
}
|
||||
clk_freq <<= 8;//div_num is 8 bit decimal
|
||||
return (clk_freq >> bit_num) / (double)div_num;
|
||||
}
|
||||
|
||||
static void _ledcSetupChannel(uint8_t chan, uint8_t idle_level)
|
||||
{
|
||||
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
|
||||
LEDC_MUTEX_LOCK();
|
||||
LEDC_CHAN(group, channel).conf0.timer_sel = timer;//2 bit Selects the timer to attach 0-3
|
||||
LEDC_CHAN(group, channel).conf0.idle_lv = idle_level;//1 bit This bit is used to control the output value when channel is off.
|
||||
LEDC_CHAN(group, channel).hpoint.hpoint = 0;//20 bit The output value changes to high when timer selected by channel has reached hpoint
|
||||
LEDC_CHAN(group, channel).conf1.duty_inc = 1;//1 bit This register is used to increase the duty of output signal or decrease the duty of output signal for high speed channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_num = 1;//10 bit This register is used to control the number of increased or decreased times for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_cycle = 1;//10 bit This register is used to increase or decrease the duty every duty_cycle cycles for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_scale = 0;//10 bit This register controls the increase or decrease step scale for channel.
|
||||
LEDC_CHAN(group, channel).duty.duty = 0;
|
||||
LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(group) {
|
||||
#endif
|
||||
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
} else {
|
||||
LEDC_CHAN(group, channel).conf0.clk_en = 0;
|
||||
}
|
||||
#endif
|
||||
LEDC_MUTEX_UNLOCK();
|
||||
}
|
||||
uint8_t channels_resolution[LEDC_CHANNELS] = {0};
|
||||
|
||||
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
log_e("No more LEDC channels available! You can have maximum %u", LEDC_CHANNELS);
|
||||
return 0;
|
||||
}
|
||||
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
|
||||
_ledcSetupChannel(chan, LOW);
|
||||
return res_freq;
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = group,
|
||||
.timer_num = timer,
|
||||
.duty_resolution = bit_num,
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
ledc_timer_config(&ledc_timer);
|
||||
channels_resolution[chan] = bit_num;
|
||||
|
||||
return ledc_get_freq(group,timer);
|
||||
}
|
||||
|
||||
void ledcWrite(uint8_t chan, uint32_t duty)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return;
|
||||
}
|
||||
uint8_t group=(chan/8), channel=(chan%8);
|
||||
LEDC_MUTEX_LOCK();
|
||||
LEDC_CHAN(group, channel).duty.duty = duty << 4;//25 bit (21.4)
|
||||
if(duty) {
|
||||
LEDC_CHAN(group, channel).conf0.sig_out_en = 1;//This is the output enable control bit for channel
|
||||
LEDC_CHAN(group, channel).conf1.duty_start = 1;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(group) {
|
||||
#endif
|
||||
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
} else {
|
||||
LEDC_CHAN(group, channel).conf0.clk_en = 1;
|
||||
|
||||
//Fixing if all bits in resolution is set = LEDC FULL ON
|
||||
uint32_t max_duty = (1 << channels_resolution[chan]) - 1;
|
||||
|
||||
if(duty == max_duty){
|
||||
duty = max_duty + 1;
|
||||
}
|
||||
#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)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return 0;
|
||||
}
|
||||
return LEDC.channel_group[chan/8].channel[chan%8].duty.duty >> 4;
|
||||
uint8_t group=(chan/8), channel=(chan%8);
|
||||
return ledc_get_duty(group,channel);
|
||||
}
|
||||
|
||||
double ledcReadFreq(uint8_t chan)
|
||||
@ -276,19 +107,33 @@ double ledcReadFreq(uint8_t chan)
|
||||
if(!ledcRead(chan)){
|
||||
return 0;
|
||||
}
|
||||
return _ledcTimerRead(chan);
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
return ledc_get_freq(group,timer);
|
||||
}
|
||||
|
||||
double ledcWriteTone(uint8_t chan, double freq)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return 0;
|
||||
}
|
||||
if(!freq) {
|
||||
if(!freq){
|
||||
ledcWrite(chan, 0);
|
||||
return 0;
|
||||
}
|
||||
double res_freq = _ledcSetupTimerFreq(chan, freq, 10);
|
||||
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = group,
|
||||
.timer_num = timer,
|
||||
.duty_resolution = 10,
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
ledc_timer_config(&ledc_timer);
|
||||
channels_resolution[chan] = 10;
|
||||
|
||||
double res_freq = ledc_get_freq(group,timer);
|
||||
ledcWrite(chan, 0x1FF);
|
||||
return res_freq;
|
||||
}
|
||||
@ -308,15 +153,21 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
|
||||
|
||||
void ledcAttachPin(uint8_t pin, uint8_t chan)
|
||||
{
|
||||
if(chan > LAST_CHAN) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return;
|
||||
}
|
||||
pinMode(pin, OUTPUT);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
pinMatrixOutAttach(pin, LEDC_LS_SIG_OUT0_IDX + chan, false, false);
|
||||
#else
|
||||
pinMatrixOutAttach(pin, ((chan/8)?LEDC_LS_SIG_OUT0_IDX:LEDC_HS_SIG_OUT0_IDX) + (chan%8), false, false);
|
||||
#endif
|
||||
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
|
||||
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.speed_mode = group,
|
||||
.channel = channel,
|
||||
.timer_sel = timer,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = pin,
|
||||
.duty = 0,
|
||||
.hpoint = 0
|
||||
};
|
||||
ledc_channel_config(&ledc_channel);
|
||||
}
|
||||
|
||||
void ledcDetachPin(uint8_t pin)
|
||||
@ -326,21 +177,32 @@ void ledcDetachPin(uint8_t pin)
|
||||
|
||||
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
|
||||
{
|
||||
if (chan > 15) {
|
||||
if(chan >= LEDC_CHANNELS){
|
||||
return 0;
|
||||
}
|
||||
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
|
||||
return res_freq;
|
||||
uint8_t group=(chan/8), timer=((chan/2)%4);
|
||||
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = group,
|
||||
.timer_num = timer,
|
||||
.duty_resolution = bit_num,
|
||||
.freq_hz = freq,
|
||||
.clk_cfg = LEDC_DEFAULT_CLK
|
||||
};
|
||||
ledc_timer_config(&ledc_timer);
|
||||
channels_resolution[chan] = bit_num;
|
||||
|
||||
return ledc_get_freq(group,timer);
|
||||
}
|
||||
|
||||
static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 };
|
||||
static int cnt_channel = SOC_LEDC_CHANNEL_NUM;
|
||||
static int cnt_channel = LEDC_CHANNELS;
|
||||
void analogWrite(uint8_t pin, int value) {
|
||||
// Use ledc hardware for internal pins
|
||||
if (pin < SOC_GPIO_PIN_COUNT) {
|
||||
if (pin_to_channel[pin] == 0) {
|
||||
if (!cnt_channel) {
|
||||
log_e("No more analogWrite channels available! You can have maximum %u", SOC_LEDC_CHANNEL_NUM);
|
||||
log_e("No more analogWrite channels available! You can have maximum %u", LEDC_CHANNELS);
|
||||
return;
|
||||
}
|
||||
pin_to_channel[pin] = cnt_channel--;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,9 @@ extern "C" {
|
||||
#define RMT_FLAG_ERROR (4)
|
||||
#define RMT_FLAGS_ALL (RMT_FLAG_TX_DONE | RMT_FLAG_RX_DONE | RMT_FLAG_ERROR)
|
||||
|
||||
#define RMT_TX_MODE true
|
||||
#define RMT_RX_MODE false
|
||||
|
||||
struct rmt_obj_s;
|
||||
|
||||
typedef enum {
|
||||
@ -54,6 +57,13 @@ typedef struct {
|
||||
};
|
||||
} rmt_data_t;
|
||||
|
||||
|
||||
/**
|
||||
* Prints object information
|
||||
*
|
||||
*/
|
||||
void _rmtDumpStatus(rmt_obj_t* rmt);
|
||||
|
||||
/**
|
||||
* Initialize the object
|
||||
*
|
||||
@ -69,10 +79,17 @@ float rmtSetTick(rmt_obj_t* rmt, float tick);
|
||||
/**
|
||||
* Sending data in one-go mode or continual mode
|
||||
* (more data being send while updating buffers in interrupts)
|
||||
*
|
||||
* Non-Blocking mode - returns right after executing
|
||||
*/
|
||||
bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
|
||||
|
||||
/**
|
||||
* Sending data in one-go mode or continual mode
|
||||
* (more data being send while updating buffers in interrupts)
|
||||
* Blocking mode - only returns when data has been sent
|
||||
*/
|
||||
bool rmtWriteBlocking(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
|
||||
|
||||
/**
|
||||
* Loop data up to the reserved memsize continuously
|
||||
*
|
||||
|
@ -12,38 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "soc/gpio_sd_reg.h"
|
||||
#include "soc/gpio_sd_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "driver/sigmadelta.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
#define SD_MUTEX_LOCK()
|
||||
#define SD_MUTEX_UNLOCK()
|
||||
#else
|
||||
#define SD_MUTEX_LOCK() do {} while (xSemaphoreTake(_sd_sys_lock, portMAX_DELAY) != pdPASS)
|
||||
#define SD_MUTEX_UNLOCK() xSemaphoreGive(_sd_sys_lock)
|
||||
xSemaphoreHandle _sd_sys_lock;
|
||||
#endif
|
||||
static uint8_t duty_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0};
|
||||
static uint32_t prescaler_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0};
|
||||
|
||||
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
||||
if(old_apb == new_apb){
|
||||
@ -51,79 +27,60 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb
|
||||
}
|
||||
uint32_t iarg = (uint32_t)arg;
|
||||
uint8_t channel = iarg;
|
||||
if(ev_type == APB_BEFORE_CHANGE){
|
||||
SIGMADELTA.cg.clk_en = 0;
|
||||
} else {
|
||||
if(ev_type == APB_AFTER_CHANGE){
|
||||
old_apb /= 1000000;
|
||||
new_apb /= 1000000;
|
||||
SD_MUTEX_LOCK();
|
||||
uint32_t old_prescale = SIGMADELTA.channel[channel].prescale + 1;
|
||||
SIGMADELTA.channel[channel].prescale = ((new_apb * old_prescale) / old_apb) - 1;
|
||||
SIGMADELTA.cg.clk_en = 0;
|
||||
SIGMADELTA.cg.clk_en = 1;
|
||||
SD_MUTEX_UNLOCK();
|
||||
uint32_t old_prescale = prescaler_set[channel] + 1;
|
||||
uint32_t new_prescale = ((new_apb * old_prescale) / old_apb) - 1;
|
||||
sigmadelta_set_prescale(channel,new_prescale);
|
||||
prescaler_set[channel] = new_prescale;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-312500
|
||||
uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq) //chan 0-x according to SOC, freq 1220-312500
|
||||
{
|
||||
if(channel > 7) {
|
||||
if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
|
||||
return 0;
|
||||
}
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
static bool tHasStarted = false;
|
||||
if(!tHasStarted) {
|
||||
tHasStarted = true;
|
||||
_sd_sys_lock = xSemaphoreCreateMutex();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t apb_freq = getApbFrequency();
|
||||
uint32_t prescale = (apb_freq/(freq*256)) - 1;
|
||||
if(prescale > 0xFF) {
|
||||
prescale = 0xFF;
|
||||
}
|
||||
SD_MUTEX_LOCK();
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
SIGMADELTA.misc.function_clk_en = 1;
|
||||
#endif
|
||||
SIGMADELTA.channel[channel].prescale = prescale;
|
||||
SIGMADELTA.cg.clk_en = 0;
|
||||
SIGMADELTA.cg.clk_en = 1;
|
||||
SD_MUTEX_UNLOCK();
|
||||
|
||||
sigmadelta_config_t sigmadelta_cfg = {
|
||||
.channel = channel,
|
||||
.sigmadelta_prescale = prescale,
|
||||
.sigmadelta_duty = 0,
|
||||
.sigmadelta_gpio = pin,
|
||||
};
|
||||
sigmadelta_config(&sigmadelta_cfg);
|
||||
|
||||
prescaler_set[channel] = prescale;
|
||||
uint32_t iarg = channel;
|
||||
addApbChangeCallback((void*)iarg, _on_apb_change);
|
||||
|
||||
return apb_freq/((prescale + 1) * 256);
|
||||
}
|
||||
|
||||
void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-7 duty 8 bit
|
||||
void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-x according to SOC duty 8 bit
|
||||
{
|
||||
if(channel > 7) {
|
||||
if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
|
||||
return;
|
||||
}
|
||||
duty -= 128;
|
||||
SD_MUTEX_LOCK();
|
||||
SIGMADELTA.channel[channel].duty = duty;
|
||||
SD_MUTEX_UNLOCK();
|
||||
|
||||
sigmadelta_set_duty(channel,duty);
|
||||
duty_set[channel] = duty;
|
||||
}
|
||||
|
||||
uint8_t sigmaDeltaRead(uint8_t channel) //chan 0-7
|
||||
uint8_t sigmaDeltaRead(uint8_t channel) //chan 0-x according to SOC
|
||||
{
|
||||
if(channel > 7) {
|
||||
if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
|
||||
return 0;
|
||||
}
|
||||
SD_MUTEX_LOCK();
|
||||
uint8_t duty = SIGMADELTA.channel[channel].duty + 128;
|
||||
SD_MUTEX_UNLOCK();
|
||||
return duty;
|
||||
}
|
||||
|
||||
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel) //channel 0-7
|
||||
{
|
||||
if(channel > 7) {
|
||||
return;
|
||||
}
|
||||
pinMode(pin, OUTPUT);
|
||||
pinMatrixOutAttach(pin, GPIO_SD0_OUT_IDX + channel, false, false);
|
||||
return duty_set[channel]+128;
|
||||
}
|
||||
|
||||
void sigmaDeltaDetachPin(uint8_t pin)
|
||||
|
@ -23,10 +23,9 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
|
||||
//channel 0-7 freq 1220-312500 duty 0-255
|
||||
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq);
|
||||
uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq);
|
||||
void sigmaDeltaWrite(uint8_t channel, uint8_t duty);
|
||||
uint8_t sigmaDeltaRead(uint8_t channel);
|
||||
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel);
|
||||
void sigmaDeltaDetachPin(uint8_t pin);
|
||||
|
||||
|
||||
|
@ -13,42 +13,10 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#endif
|
||||
#include "freertos/task.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "esp_attr.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/timer.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_intr.h"
|
||||
#endif
|
||||
|
||||
#define HWTIMER_LOCK() portENTER_CRITICAL(timer->lock)
|
||||
#define HWTIMER_UNLOCK() portEXIT_CRITICAL(timer->lock)
|
||||
|
||||
typedef volatile struct {
|
||||
union {
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t reserved0: 10;
|
||||
uint32_t alarm_en: 1; /*When set alarm is enabled*/
|
||||
@ -60,288 +28,212 @@ typedef volatile struct {
|
||||
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;
|
||||
} timer_cfg_t;
|
||||
|
||||
typedef struct hw_timer_s {
|
||||
hw_timer_reg_t * dev;
|
||||
uint8_t num;
|
||||
#define NUM_OF_TIMERS SOC_TIMER_GROUP_TOTAL_TIMERS
|
||||
|
||||
typedef struct {
|
||||
int timer_group;
|
||||
int timer_idx;
|
||||
int alarm_interval;
|
||||
bool auto_reload;
|
||||
} timer_info_t;
|
||||
|
||||
typedef struct hw_timer_s
|
||||
{
|
||||
uint8_t group;
|
||||
uint8_t timer;
|
||||
portMUX_TYPE lock;
|
||||
uint8_t num;
|
||||
} hw_timer_t;
|
||||
|
||||
static hw_timer_t hw_timer[4] = {
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE),0,0,0,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x0024),1,0,1,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1000),2,1,0,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1024),3,1,1,portMUX_INITIALIZER_UNLOCKED}
|
||||
// Works for all chips
|
||||
static hw_timer_t timer_dev[4] = {
|
||||
{0,0}, {1,0}, {1,0}, {1,1}
|
||||
};
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
static voidFuncPtr __timerInterruptHandlers[4] = {0,0,0,0};
|
||||
// NOTE: (in IDF 5.0 there wont be need to know groups/numbers
|
||||
// timer_init() will list thru all timers and return free timer handle)
|
||||
|
||||
void ARDUINO_ISR_ATTR __timerISR(void * arg){
|
||||
uint32_t s0 = TIMERG0.int_st_timers.val;
|
||||
uint32_t s1 = TIMERG1.int_st_timers.val;
|
||||
TIMERG0.int_clr_timers.val = s0;
|
||||
TIMERG1.int_clr_timers.val = s1;
|
||||
uint8_t status = (s1 & 3) << 2 | (s0 & 3);
|
||||
uint8_t i = 4;
|
||||
//restart the timers that should autoreload
|
||||
while(i--){
|
||||
hw_timer_reg_t * dev = hw_timer[i].dev;
|
||||
if((status & (1 << i)) && dev->config.autoreload){
|
||||
dev->config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
i = 4;
|
||||
//call callbacks
|
||||
while(i--){
|
||||
if(__timerInterruptHandlers[i] && (status & (1 << i))){
|
||||
__timerInterruptHandlers[i]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t inline timerRead(hw_timer_t *timer){
|
||||
timer->dev->update = 1;
|
||||
while (timer->dev->update) {};
|
||||
uint64_t h = timer->dev->cnt_high;
|
||||
uint64_t l = timer->dev->cnt_low;
|
||||
return (h << 32) | l;
|
||||
|
||||
uint64_t value;
|
||||
timer_get_counter_value(timer->group, timer->num,&value);
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t timerAlarmRead(hw_timer_t *timer){
|
||||
uint64_t h = timer->dev->alarm_high;
|
||||
uint64_t l = timer->dev->alarm_low;
|
||||
return (h << 32) | l;
|
||||
uint64_t value;
|
||||
timer_get_alarm_value(timer->group, timer->num, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void timerWrite(hw_timer_t *timer, uint64_t val){
|
||||
timer->dev->load_high = (uint32_t) (val >> 32);
|
||||
timer->dev->load_low = (uint32_t) (val);
|
||||
timer->dev->reload = 1;
|
||||
timer_set_counter_value(timer->group, timer->num, val);
|
||||
}
|
||||
|
||||
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){
|
||||
timer->dev->alarm_high = (uint32_t) (alarm_value >> 32);
|
||||
timer->dev->alarm_low = (uint32_t) alarm_value;
|
||||
timer->dev->config.autoreload = autoreload;
|
||||
timer_set_alarm_value(timer->group, timer->num, alarm_value);
|
||||
timerSetAutoReload(timer,autoreload);
|
||||
}
|
||||
|
||||
void timerSetConfig(hw_timer_t *timer, uint32_t config){
|
||||
timer->dev->config.val = config;
|
||||
timer_cfg_t cfg;
|
||||
cfg.val = config;
|
||||
timer_set_alarm(timer->group, timer->num, cfg.alarm_en);
|
||||
timerSetDivider(timer,cfg.divider);
|
||||
timerSetAutoReload(timer,cfg.autoreload);
|
||||
timerSetCountUp(timer, cfg.increase);
|
||||
|
||||
if (cfg.enable) {
|
||||
timerStart(timer);
|
||||
}
|
||||
else{
|
||||
timerStop(timer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t timerGetConfig(hw_timer_t *timer){
|
||||
return timer->dev->config.val;
|
||||
timer_config_t timer_cfg;
|
||||
timer_get_config(timer->group, timer->num,&timer_cfg);
|
||||
|
||||
//Translate to default uint32_t
|
||||
timer_cfg_t cfg;
|
||||
cfg.alarm_en = timer_cfg.alarm_en;
|
||||
cfg.autoreload = timer_cfg.auto_reload;
|
||||
cfg.divider = timer_cfg.divider;
|
||||
cfg.edge_int_en = timer_cfg.intr_type;
|
||||
cfg.level_int_en = !timer_cfg.intr_type;
|
||||
cfg.enable = timer_cfg.counter_en;
|
||||
cfg.increase = timer_cfg.counter_dir;
|
||||
|
||||
return cfg.val;
|
||||
}
|
||||
|
||||
void timerSetCountUp(hw_timer_t *timer, bool countUp){
|
||||
timer->dev->config.increase = countUp;
|
||||
timer_set_counter_mode(timer->group, timer->num,countUp);
|
||||
}
|
||||
|
||||
bool timerGetCountUp(hw_timer_t *timer){
|
||||
return timer->dev->config.increase;
|
||||
timer_cfg_t config;
|
||||
config.val = timerGetConfig(timer);
|
||||
return config.increase;
|
||||
}
|
||||
|
||||
void timerSetAutoReload(hw_timer_t *timer, bool autoreload){
|
||||
timer->dev->config.autoreload = autoreload;
|
||||
timer_set_auto_reload(timer->group, timer->num,autoreload);
|
||||
}
|
||||
|
||||
bool timerGetAutoReload(hw_timer_t *timer){
|
||||
return timer->dev->config.autoreload;
|
||||
timer_cfg_t config;
|
||||
config.val= timerGetConfig(timer);
|
||||
return config.autoreload;
|
||||
}
|
||||
|
||||
void timerSetDivider(hw_timer_t *timer, uint16_t divider){//2 to 65536
|
||||
if(!divider){
|
||||
divider = 0xFFFF;
|
||||
} else if(divider == 1){
|
||||
divider = 2;
|
||||
// Set divider from 2 to 65535
|
||||
void timerSetDivider(hw_timer_t *timer, uint16_t divider){
|
||||
if(divider < 2)
|
||||
{
|
||||
log_e("Timer divider must be set in range of 2 to 65535");
|
||||
return;
|
||||
}
|
||||
int timer_en = timer->dev->config.enable;
|
||||
timer->dev->config.enable = 0;
|
||||
timer->dev->config.divider = divider;
|
||||
timer->dev->config.enable = timer_en;
|
||||
timer_set_divider(timer->group, timer->num,divider);
|
||||
}
|
||||
|
||||
uint16_t timerGetDivider(hw_timer_t *timer){
|
||||
return timer->dev->config.divider;
|
||||
timer_cfg_t config;
|
||||
config.val = timerGetConfig(timer);
|
||||
return config.divider;
|
||||
}
|
||||
|
||||
void timerStart(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 1;
|
||||
timer_start(timer->group, timer->num);
|
||||
}
|
||||
|
||||
void timerStop(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
timer_pause(timer->group, timer->num);
|
||||
}
|
||||
|
||||
void timerRestart(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
timer->dev->reload = 1;
|
||||
timer->dev->config.enable = 1;
|
||||
timerWrite(timer,0);
|
||||
}
|
||||
|
||||
bool timerStarted(hw_timer_t *timer){
|
||||
return timer->dev->config.enable;
|
||||
timer_cfg_t config;
|
||||
config.val = timerGetConfig(timer);
|
||||
return config.enable;
|
||||
}
|
||||
|
||||
void timerAlarmEnable(hw_timer_t *timer){
|
||||
timer->dev->config.alarm_en = 1;
|
||||
timer_set_alarm(timer->group, timer->num,true);
|
||||
}
|
||||
|
||||
void timerAlarmDisable(hw_timer_t *timer){
|
||||
timer->dev->config.alarm_en = 0;
|
||||
timer_set_alarm(timer->group, timer->num,false);
|
||||
}
|
||||
|
||||
bool timerAlarmEnabled(hw_timer_t *timer){
|
||||
return timer->dev->config.alarm_en;
|
||||
timer_cfg_t config;
|
||||
config.val = timerGetConfig(timer);
|
||||
return config.alarm_en;
|
||||
}
|
||||
|
||||
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
||||
hw_timer_t * timer = (hw_timer_t *)arg;
|
||||
if(ev_type == APB_BEFORE_CHANGE){
|
||||
timer->dev->config.enable = 0;
|
||||
timerStop(timer);
|
||||
} else {
|
||||
old_apb /= 1000000;
|
||||
new_apb /= 1000000;
|
||||
timer->dev->config.divider = (new_apb * timer->dev->config.divider) / old_apb;
|
||||
timer->dev->config.enable = 1;
|
||||
uint16_t divider = (new_apb * timerGetDivider(timer)) / old_apb;
|
||||
timerSetDivider(timer,divider);
|
||||
timerStart(timer);
|
||||
}
|
||||
}
|
||||
|
||||
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
|
||||
if(num > 3){
|
||||
if(num >= NUM_OF_TIMERS)
|
||||
{
|
||||
log_e("Timer dont have that timer number.");
|
||||
return NULL;
|
||||
}
|
||||
hw_timer_t * timer = &hw_timer[num];
|
||||
if(timer->group) {
|
||||
periph_module_enable(PERIPH_TIMG1_MODULE);
|
||||
} else {
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
}
|
||||
timer->dev->config.enable = 0;
|
||||
if(timer->group) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG1.int_ena.val &= ~BIT(timer->timer);
|
||||
#else
|
||||
TIMERG1.int_ena_timers.val &= ~BIT(timer->timer);
|
||||
#endif
|
||||
TIMERG1.int_clr_timers.val |= BIT(timer->timer);
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG0.int_ena.val &= ~BIT(timer->timer);
|
||||
#else
|
||||
TIMERG0.int_ena_timers.val &= ~BIT(timer->timer);
|
||||
#endif
|
||||
TIMERG0.int_clr_timers.val |= BIT(timer->timer);
|
||||
}
|
||||
#ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK
|
||||
timer->dev->config.use_xtal = 0;
|
||||
#endif
|
||||
timerSetDivider(timer, divider);
|
||||
timerSetCountUp(timer, countUp);
|
||||
timerSetAutoReload(timer, false);
|
||||
timerAttachInterrupt(timer, NULL, false);
|
||||
timerWrite(timer, 0);
|
||||
timer->dev->config.enable = 1;
|
||||
|
||||
hw_timer_t * timer = &timer_dev[num]; //Get Timer group/num from 0-3 number
|
||||
|
||||
timer_config_t config = {
|
||||
.divider = divider,
|
||||
.counter_dir = countUp,
|
||||
.counter_en = TIMER_PAUSE,
|
||||
.alarm_en = TIMER_ALARM_DIS,
|
||||
.auto_reload = false,
|
||||
};
|
||||
|
||||
timer_init(timer->group, timer->num, &config);
|
||||
timer_set_counter_value(timer->group, timer->num, 0);
|
||||
timerStart(timer);
|
||||
addApbChangeCallback(timer, _on_apb_change);
|
||||
return timer;
|
||||
}
|
||||
|
||||
void timerEnd(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
timerAttachInterrupt(timer, NULL, false);
|
||||
removeApbChangeCallback(timer, _on_apb_change);
|
||||
timer_deinit(timer->group, timer->num);
|
||||
}
|
||||
|
||||
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(edge){
|
||||
log_w("EDGE timer interrupt does not work properly on ESP32! Setting to LEVEL...");
|
||||
log_w("EDGE timer interrupt is not supported! Setting to LEVEL...");
|
||||
edge = false;
|
||||
}
|
||||
#endif
|
||||
static bool initialized = false;
|
||||
static intr_handle_t intr_handle = NULL;
|
||||
if(intr_handle){
|
||||
esp_intr_disable(intr_handle);
|
||||
}
|
||||
if(fn == NULL){
|
||||
timer->dev->config.level_int_en = 0;
|
||||
timer->dev->config.edge_int_en = 0;
|
||||
timer->dev->config.alarm_en = 0;
|
||||
if(timer->num & 2){
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG1.int_ena.val &= ~BIT(timer->timer);
|
||||
#else
|
||||
TIMERG1.int_ena_timers.val &= ~BIT(timer->timer);
|
||||
#endif
|
||||
TIMERG1.int_clr_timers.val |= BIT(timer->timer);
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG0.int_ena.val &= ~BIT(timer->timer);
|
||||
#else
|
||||
TIMERG0.int_ena_timers.val &= ~BIT(timer->timer);
|
||||
#endif
|
||||
TIMERG0.int_clr_timers.val |= BIT(timer->timer);
|
||||
}
|
||||
__timerInterruptHandlers[timer->num] = NULL;
|
||||
} else {
|
||||
__timerInterruptHandlers[timer->num] = fn;
|
||||
timer->dev->config.level_int_en = edge?0:1;//When set, an alarm will generate a level type interrupt.
|
||||
timer->dev->config.edge_int_en = edge?1:0;//When set, an alarm will generate an edge type interrupt.
|
||||
int intr_source = 0;
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
if(!edge){
|
||||
#endif
|
||||
if(timer->group){
|
||||
intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer->timer;
|
||||
} else {
|
||||
intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer->timer;
|
||||
}
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C3
|
||||
} else {
|
||||
if(timer->group){
|
||||
intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer->timer;
|
||||
} else {
|
||||
intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer->timer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(!initialized){
|
||||
initialized = true;
|
||||
esp_intr_alloc(intr_source, (int)(ARDUINO_ISR_FLAG|ESP_INTR_FLAG_LOWMED), __timerISR, NULL, &intr_handle);
|
||||
} else {
|
||||
intr_matrix_set(esp_intr_get_cpu(intr_handle), intr_source, esp_intr_get_intno(intr_handle));
|
||||
}
|
||||
if(timer->group){
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG1.int_ena.val |= BIT(timer->timer);
|
||||
#else
|
||||
TIMERG1.int_ena_timers.val |= BIT(timer->timer);
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG0.int_ena.val |= BIT(timer->timer);
|
||||
#else
|
||||
TIMERG0.int_ena_timers.val |= BIT(timer->timer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(intr_handle){
|
||||
esp_intr_enable(intr_handle);
|
||||
}
|
||||
timer_enable_intr(timer->group, timer->num);
|
||||
|
||||
timer_info_t *timer_info = calloc(1, sizeof(timer_info_t));
|
||||
timer_info->timer_group = timer->group;
|
||||
timer_info->timer_idx = timer->num;
|
||||
timer_info->auto_reload = timerGetAutoReload(timer);
|
||||
timer_info->alarm_interval = timerAlarmRead(timer);
|
||||
|
||||
timer_isr_callback_add(timer->group, timer->num, (timer_isr_t)fn, timer_info, 0);
|
||||
}
|
||||
|
||||
void timerDetachInterrupt(hw_timer_t *timer){
|
||||
@ -354,6 +246,12 @@ uint64_t timerReadMicros(hw_timer_t *timer){
|
||||
return timer_val * div / (getApbFrequency() / 1000000);
|
||||
}
|
||||
|
||||
uint64_t timerReadMilis(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
return timer_val * div / (getApbFrequency() / 1000);
|
||||
}
|
||||
|
||||
double timerReadSeconds(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
@ -366,6 +264,12 @@ uint64_t timerAlarmReadMicros(hw_timer_t *timer){
|
||||
return timer_val * div / (getApbFrequency() / 1000000);
|
||||
}
|
||||
|
||||
uint64_t timerAlarmReadMilis(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerAlarmRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
return timer_val * div / (getApbFrequency() / 1000);
|
||||
}
|
||||
|
||||
double timerAlarmReadSeconds(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerAlarmRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
|
@ -20,13 +20,13 @@
|
||||
#ifndef MAIN_ESP32_HAL_TIMER_H_
|
||||
#define MAIN_ESP32_HAL_TIMER_H_
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
struct hw_timer_s;
|
||||
typedef struct hw_timer_s hw_timer_t;
|
||||
|
||||
@ -50,6 +50,7 @@ void timerSetAutoReload(hw_timer_t *timer, bool autoreload);
|
||||
bool timerStarted(hw_timer_t *timer);
|
||||
uint64_t timerRead(hw_timer_t *timer);
|
||||
uint64_t timerReadMicros(hw_timer_t *timer);
|
||||
uint64_t timerReadMilis(hw_timer_t *timer);
|
||||
double timerReadSeconds(hw_timer_t *timer);
|
||||
uint16_t timerGetDivider(hw_timer_t *timer);
|
||||
bool timerGetCountUp(hw_timer_t *timer);
|
||||
|
@ -69,6 +69,19 @@ static uart_t _uart_bus_array[] = {
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
bool uartIsDriverInstalled(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
@ -121,7 +134,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
UART_MUTEX_LOCK();
|
||||
|
||||
uart_config_t uart_config;
|
||||
uart_config.baud_rate = baudrate;
|
||||
uart_config.baud_rate = _get_effective_baudrate(baudrate);
|
||||
uart_config.data_bits = (config & 0xc) >> 2;
|
||||
uart_config.parity = (config & 0x3);
|
||||
uart_config.stop_bits = (config & 0x30) >> 4;
|
||||
@ -140,6 +153,9 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
ESP_ERROR_CHECK(uart_set_line_inverse(uart_nr, UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV));
|
||||
}
|
||||
|
||||
// Set RS485 half duplex mode on UART. This shall force flush to wait up to sending all bits out
|
||||
ESP_ERROR_CHECK(uart_set_mode(uart_nr, UART_MODE_RS485_HALF_DUPLEX));
|
||||
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
uartFlush(uart);
|
||||
@ -304,7 +320,7 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), baud_rate);
|
||||
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate));
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
|
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
@ -33,6 +33,10 @@ void yieldIfNecessary(void){
|
||||
|
||||
bool loopTaskWDTEnabled;
|
||||
|
||||
__attribute__((weak)) size_t getArduinoLoopTaskStackSize(void) {
|
||||
return ARDUINO_LOOP_STACK_SIZE;
|
||||
}
|
||||
|
||||
void loopTask(void *pvParameters)
|
||||
{
|
||||
setup();
|
||||
@ -64,7 +68,7 @@ extern "C" void app_main()
|
||||
#endif
|
||||
loopTaskWDTEnabled = false;
|
||||
initArduino();
|
||||
xTaskCreateUniversal(loopTask, "loopTask", ARDUINO_LOOP_STACK_SIZE, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
|
||||
xTaskCreateUniversal(loopTask, "loopTask", getArduinoLoopTaskStackSize(), NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
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 |
@ -1,3 +1,170 @@
|
||||
####
|
||||
GPIO
|
||||
####
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
One of the most used and versatile peripheral in a microcontroller is the GPIO. The GPIO is commonly used to write and read the pin state.
|
||||
|
||||
GPIO stands to General Purpose Input Output, and is responsible to control or read the state of a specific pin in the digital world. For example, this peripheral is widely used to create the LED blinking or to read a simple button.
|
||||
|
||||
.. note:: There are some GPIOs with special restrictions, and not all GPIOs are accessible through the developemnt board. For more information about it, see the corresponding board pin layout information.
|
||||
|
||||
GPIOs Modes
|
||||
***********
|
||||
|
||||
There are two different modes in the GPIO configuration:
|
||||
|
||||
- **Input Mode**
|
||||
|
||||
In this mode, the GPIO will receive the digital state from a specific device. This device could be a button or a switch.
|
||||
|
||||
- **Output Mode**
|
||||
|
||||
For the output mode, the GPIO will change the GPIO digital state to a specific device. You can drive an LED for example.
|
||||
|
||||
GPIO API
|
||||
--------
|
||||
|
||||
Here is the common functions used for the GPIO peripheral.
|
||||
|
||||
pinMode
|
||||
*******
|
||||
|
||||
The ``pinMode`` function is used to define the GPIO operation mode for a specific pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
* ``mode`` sets operation mode.
|
||||
|
||||
The following modes are supported for the basic `input` and `output`:
|
||||
|
||||
* **INPUT** sets the GPIO as input without pullup or pulldown (high impedance).
|
||||
* **OUTPUT** sets the GPIO as output/read mode.
|
||||
* **INPUT_PULLDOWN** sets the GPIO as input with the internal pulldown.
|
||||
* **INPUT_PULLUP** sets the GPIO as input with the internal pullup.
|
||||
|
||||
Internal Pullup and Pulldown
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ESP32 SoC families supports the internal pullup and pulldown throught a 45kR resistor, that can be enabled when configuring the GPIO mode as ``INPUT`` mode.
|
||||
If the pullup or pulldown mode is not defined, the pin will stay in the high impedance mode.
|
||||
|
||||
digitalWrite
|
||||
*************
|
||||
|
||||
The function ``digitalWrite`` sets the state of the selected GPIO to ``HIGH`` or ``LOW``. This function is only used if the ``pinMode`` was configured as ``OUTPUT``.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void digitalWrite(uint8_t pin, uint8_t val);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
* ``val`` set the output digital state to ``HIGH`` or ``LOW``.
|
||||
|
||||
digitalRead
|
||||
***********
|
||||
|
||||
To read the state of a given pin configured as ``INPUT``, the function ``digitalRead`` is used.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int digitalRead(uint8_t pin);
|
||||
|
||||
* ``pin`` select GPIO
|
||||
|
||||
This function will return the logical state of the selected pin as ``HIGH`` or ``LOW``.
|
||||
|
||||
Interrupts
|
||||
----------
|
||||
|
||||
The GPIO peripheral on the ESP32 supports interruptions.
|
||||
|
||||
attachInterrupt
|
||||
***************
|
||||
|
||||
The function ``attachInterruptArg`` is used to attach the interrupt to the defined pin.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
* ``handler`` set the handler function.
|
||||
* ``mode`` set the interrupt mode.
|
||||
|
||||
Here are the supported interrupt modes:
|
||||
|
||||
* **DISABLED**
|
||||
* **RISING**
|
||||
* **FALLING**
|
||||
* **CHANGE**
|
||||
* **ONLOW**
|
||||
* **ONHIGH**
|
||||
* **ONLOW_WE**
|
||||
* **ONHIGH_WE**
|
||||
|
||||
attachInterruptArg
|
||||
******************
|
||||
|
||||
The function ``attachInterruptArg`` is used to attach the interrupt to the defined pin using arguments.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
* ``handler`` set the handler function.
|
||||
* ``arg`` pointer to the interrupt arguments.
|
||||
* ``mode`` set the interrupt mode.
|
||||
|
||||
detachInterrupt
|
||||
***************
|
||||
|
||||
To detach the interruption from a specific pin, use the ``detachInterrupt`` function giving the GPIO to be detached.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
detachInterrupt(uint8_t pin);
|
||||
|
||||
* ``pin`` defines the GPIO pin number.
|
||||
|
||||
.. _gpio_example_code:
|
||||
|
||||
Example Code
|
||||
------------
|
||||
|
||||
GPIO Input and Output Modes
|
||||
***************************
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
#define LED 12
|
||||
#define BUTTON 2
|
||||
|
||||
uint8_t stateLED = 0;
|
||||
|
||||
void setup() {
|
||||
pinMode(LED, OUTPUT);
|
||||
pinMode(BUTTON,INPUT_PULLUP);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
if(!digitalRead(BUTTON)){
|
||||
stateLED = stateLED^1;
|
||||
digitalWrite(LED,stateLED);
|
||||
}
|
||||
}
|
||||
|
||||
GPIO Interrupt
|
||||
**************
|
||||
|
||||
.. literalinclude:: ../../../libraries/ESP32/examples/GPIO/GPIOInterrupt/GPIOInterrupt.ino
|
||||
:language: arduino
|
||||
|
||||
.. _datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
|
331
docs/source/api/usb.rst
Normal file
331
docs/source/api/usb.rst
Normal file
@ -0,0 +1,331 @@
|
||||
#######
|
||||
USB API
|
||||
#######
|
||||
|
||||
.. note:: This feature is only supported on ESP chips that have USB peripheral, like the ESP32-S2 and ESP32-S3. Some chips, like the ESP32-C3 include native CDC+JTAG peripheral that is not covered here.
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
The **Universal Serial Bus** is a widely used peripheral to exchange data between devices. USB was introduced on the ESP32, supporting both device and host mode.
|
||||
|
||||
To learn about the USB, see the `USB.org`_ for developers.
|
||||
|
||||
USB as Device
|
||||
*************
|
||||
|
||||
In the device mode, the ESP32 acts as an USB device, like a mouse or keyboard to be connected to a host device, like your computer or smartphone.
|
||||
|
||||
USB as Host
|
||||
***********
|
||||
|
||||
The USB host mode, you can connect devices on the ESP32, like external modems, mouse and keyboards.
|
||||
|
||||
.. note:: This mode is still under development for the ESP32.
|
||||
|
||||
API Description
|
||||
---------------
|
||||
|
||||
This is the common USB API description.
|
||||
|
||||
For more supported USB classes implementation, see the following sections:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Classes:
|
||||
|
||||
USB CDC <usb_cdc>
|
||||
USB MSC <usb_msc>
|
||||
|
||||
USB Common
|
||||
**********
|
||||
|
||||
These are the common APIs for the USB driver.
|
||||
|
||||
onEvent
|
||||
^^^^^^^
|
||||
|
||||
Event handling function to set the callback.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onEvent(esp_event_handler_t callback);
|
||||
|
||||
Event handling function for the specific event.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onEvent(arduino_usb_event_t event, esp_event_handler_t callback);
|
||||
|
||||
Where ``event`` can be:
|
||||
|
||||
* ARDUINO_USB_ANY_EVENT
|
||||
* ARDUINO_USB_STARTED_EVENT
|
||||
* ARDUINO_USB_STOPPED_EVENT
|
||||
* ARDUINO_USB_SUSPEND_EVENT
|
||||
* ARDUINO_USB_RESUME_EVENT
|
||||
* ARDUINO_USB_MAX_EVENT
|
||||
|
||||
VID
|
||||
^^^
|
||||
|
||||
Set the Vendor ID. This 16 bits identification is used to identify the company that develops the product.
|
||||
|
||||
.. note:: You can't define your own VID. If you need your own VID, you need to buy one. See https://www.usb.org/getting-vendor-id for more details.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool VID(uint16_t v);
|
||||
|
||||
|
||||
Get the Vendor ID.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint16_t VID(void);
|
||||
|
||||
Returns the Vendor ID. The default value for the VID is: ``0x303A``.
|
||||
|
||||
PID
|
||||
^^^
|
||||
|
||||
Set the Product ID. This 16 bits identification is used to identify the product.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool PID(uint16_t p);
|
||||
|
||||
Get the Product ID.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint16_t PID(void);
|
||||
|
||||
Returns the Product ID. The default PID is: ``0x0002``.
|
||||
|
||||
firmwareVersion
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Set the firmware version. This is a 16 bits unsigned value.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool firmwareVersion(uint16_t version);
|
||||
|
||||
Get the firmware version.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint16_t firmwareVersion(void);
|
||||
|
||||
Return the 16 bits unsigned value. The default value is: ``0x100``.
|
||||
|
||||
usbVersion
|
||||
^^^^^^^^^^
|
||||
|
||||
Set the USB version.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool usbVersion(uint16_t version);
|
||||
|
||||
Get the USB version.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint16_t usbVersion(void);
|
||||
|
||||
Return the USB version. The default value is: ``0x200`` (USB 2.0).
|
||||
|
||||
usbPower
|
||||
^^^^^^^^
|
||||
|
||||
Set the USB power as mA (current).
|
||||
|
||||
.. note:: This configuration does not change the physical power output. This is only used for the USB device information.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool usbPower(uint16_t mA);
|
||||
|
||||
Get the USB power configuration.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint16_t usbPower(void);
|
||||
|
||||
Return the current in mA. The default value is: ``0x500`` (500mA).
|
||||
|
||||
usbClass
|
||||
^^^^^^^^
|
||||
|
||||
Set the USB class.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool usbClass(uint8_t _class);
|
||||
|
||||
Get the USB class.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint8_t usbClass(void);
|
||||
|
||||
Return the USB class. The default value is: ``TUSB_CLASS_MISC``.
|
||||
|
||||
usbSubClass
|
||||
^^^^^^^^^^^
|
||||
|
||||
Set the USB sub-class.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool usbSubClass(uint8_t subClass);
|
||||
|
||||
Get the USB sub-class.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint8_t usbSubClass(void);
|
||||
|
||||
Return the USB sub-class. The default value is: ``MISC_SUBCLASS_COMMON``.
|
||||
|
||||
usbProtocol
|
||||
^^^^^^^^^^^
|
||||
|
||||
Define the USB protocol.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool usbProtocol(uint8_t protocol);
|
||||
|
||||
Get the USB protocol.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint8_t usbProtocol(void);
|
||||
|
||||
Return the USB protocol. The default value is: ``MISC_PROTOCOL_IAD``
|
||||
|
||||
usbAttributes
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Set the USB attributes.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool usbAttributes(uint8_t attr);
|
||||
|
||||
Get the USB attributes.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint8_t usbAttributes(void);
|
||||
|
||||
Return the USB attributes. The default value is: ``TUSB_DESC_CONFIG_ATT_SELF_POWERED``
|
||||
|
||||
webUSB
|
||||
^^^^^^
|
||||
|
||||
This function is used to enable the ``webUSB`` functionality.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool webUSB(bool enabled);
|
||||
|
||||
This function is used to get the ``webUSB`` setting.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool webUSB(void);
|
||||
|
||||
Return the ``webUSB`` setting (`Enabled` or `Disabled`)
|
||||
|
||||
productName
|
||||
^^^^^^^^^^^
|
||||
|
||||
This function is used to define the product name.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool productName(const char * name);
|
||||
|
||||
This function is used to get the product's name.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
const char * productName(void);
|
||||
|
||||
manufacturerName
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to define the manufacturer name.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool manufacturerName(const char * name);
|
||||
|
||||
This function is used to get the manufacturer's name.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
const char * manufacturerName(void);
|
||||
|
||||
serialNumber
|
||||
^^^^^^^^^^^^
|
||||
|
||||
This function is used to define the serial number.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool serialNumber(const char * name);
|
||||
|
||||
This function is used to get the serial number.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
const char * serialNumber(void);
|
||||
|
||||
The default serial number is: ``0``.
|
||||
|
||||
webUSBURL
|
||||
^^^^^^^^^
|
||||
|
||||
This function is used to define the ``webUSBURL``.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool webUSBURL(const char * name);
|
||||
|
||||
This function is used to get the ``webUSBURL``.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
const char * webUSBURL(void);
|
||||
|
||||
The default ``webUSBURL`` is: https://espressif.github.io/arduino-esp32/webusb.html
|
||||
|
||||
enableDFU
|
||||
^^^^^^^^^
|
||||
|
||||
This function is used to enable the DFU capability.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool enableDFU();
|
||||
|
||||
begin
|
||||
^^^^^
|
||||
|
||||
This function is used to start the peripheral using the default configuration.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool begin();
|
||||
|
||||
Example Code
|
||||
------------
|
||||
|
||||
There are a collection of USB device examples on the project GitHub, including Firmware MSC update, USB CDC, HID and composite device.
|
||||
|
||||
.. _USB.org: https://www.usb.org/developers
|
192
docs/source/api/usb_cdc.rst
Normal file
192
docs/source/api/usb_cdc.rst
Normal file
@ -0,0 +1,192 @@
|
||||
#######
|
||||
USB CDC
|
||||
#######
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
USB Communications Device Class API. This class is used to enable communication between the host and the device.
|
||||
|
||||
This class is often used to enable serial communication and can be used to flash the firmware on the ESP32 without the external USB to Serial chip.
|
||||
|
||||
APIs
|
||||
****
|
||||
|
||||
onEvent
|
||||
^^^^^^^
|
||||
|
||||
Event handling functions.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onEvent(esp_event_handler_t callback);
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback);
|
||||
|
||||
Where ``event`` can be:
|
||||
|
||||
* ARDUINO_USB_CDC_ANY_EVENT
|
||||
* ARDUINO_USB_CDC_CONNECTED_EVENT
|
||||
* ARDUINO_USB_CDC_DISCONNECTED_EVENT
|
||||
* ARDUINO_USB_CDC_LINE_STATE_EVENT
|
||||
* ARDUINO_USB_CDC_LINE_CODING_EVENT
|
||||
* ARDUINO_USB_CDC_RX_EVENT
|
||||
* ARDUINO_USB_CDC_TX_EVENT
|
||||
* ARDUINO_USB_CDC_MAX_EVENT
|
||||
|
||||
setRxBufferSize
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The ``setRxBufferSize`` function is used to set the size of the RX buffer.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t setRxBufferSize(size_t size);
|
||||
|
||||
setTxTimeoutMs
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to define the time to reach the timeout for the TX.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void setTxTimeoutMs(uint32_t timeout);
|
||||
|
||||
begin
|
||||
^^^^^
|
||||
|
||||
This function is used to start the peripheral using the default CDC configuration.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void begin(unsigned long baud);
|
||||
|
||||
Where:
|
||||
|
||||
* ``baud`` is the baud rate.
|
||||
|
||||
end
|
||||
^^^
|
||||
|
||||
This function will finish the peripheral as CDC and release all the allocated resources. After calling ``end`` you need to use ``begin`` again in order to initialize the USB CDC driver again.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void end();
|
||||
|
||||
available
|
||||
^^^^^^^^^
|
||||
|
||||
This function will return if there are messages in the queue.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int available(void);
|
||||
|
||||
The return is the number of bytes available to read.
|
||||
|
||||
availableForWrite
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
This function will return if the hardware is available to write data.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int availableForWrite(void);
|
||||
|
||||
peek
|
||||
^^^^
|
||||
|
||||
This function is used to ``peek`` messages from the queue.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
int peek(void);
|
||||
|
||||
read
|
||||
^^^^
|
||||
|
||||
This function is used to read the bytes available.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t read(uint8_t *buffer, size_t size);
|
||||
|
||||
Where:
|
||||
|
||||
* ``buffer`` is the pointer to the buffer to be read.
|
||||
* ``size`` is the number of bytes to be read.
|
||||
|
||||
write
|
||||
^^^^^
|
||||
|
||||
This function is used to write the message.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
Where:
|
||||
|
||||
* ``buffer`` is the pointer to the buffer to be written.
|
||||
* ``size`` is the number of bytes to be written.
|
||||
|
||||
flush
|
||||
^^^^^
|
||||
|
||||
This function is used to flush the data.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void flush(void);
|
||||
|
||||
baudRate
|
||||
^^^^^^^^
|
||||
|
||||
This function is used to get the ``baudRate``.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
uint32_t baudRate();
|
||||
|
||||
setDebugOutput
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
This function will enable the debug output, usually from the `UART0`, to the USB CDC.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void setDebugOutput(bool);
|
||||
|
||||
enableReboot
|
||||
^^^^^^^^^^^^
|
||||
|
||||
This function enables the device to reboot by the DTR as RTS signals.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void enableReboot(bool enable);
|
||||
|
||||
rebootEnabled
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
This function will return if the reboot is enabled.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool rebootEnabled(void);
|
||||
|
||||
Example Code
|
||||
------------
|
||||
|
||||
Here is an example of how to use the USB CDC.
|
||||
|
||||
USBSerial
|
||||
*********
|
||||
|
||||
.. literalinclude:: ../../../libraries/USB/examples/USBSerial/USBSerial.ino
|
||||
:language: arduino
|
||||
|
||||
.. _USB.org: https://www.usb.org/developers
|
114
docs/source/api/usb_msc.rst
Normal file
114
docs/source/api/usb_msc.rst
Normal file
@ -0,0 +1,114 @@
|
||||
#######
|
||||
USB MSC
|
||||
#######
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
USB Mass Storage Class API. This class makes the device accessible as a mass storage device and allows you to transfer data between the host and the device.
|
||||
|
||||
One of the examples for this mode is to flash the device by dropping the firmware binary like a flash memory device when connecting the ESP32 to the host computer.
|
||||
|
||||
APIs
|
||||
****
|
||||
|
||||
begin
|
||||
^^^^^
|
||||
|
||||
This function is used to start the peripheral using the default MSC configuration.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
bool begin(uint32_t block_count, uint16_t block_size);
|
||||
|
||||
Where:
|
||||
|
||||
* ``block_count`` set the disk sector count.
|
||||
* ``block_size`` set the disk sector size.
|
||||
|
||||
This function will return ``true`` if the configuration was successful.
|
||||
|
||||
end
|
||||
^^^
|
||||
|
||||
This function will finish the peripheral as MSC and release all the allocated resources. After calling ``end`` you need to use ``begin`` again in order to initialize the USB MSC driver again.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void end();
|
||||
|
||||
vendorID
|
||||
^^^^^^^^
|
||||
|
||||
This function is used to define the vendor ID.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void vendorID(const char * vid);//max 8 chars
|
||||
|
||||
productID
|
||||
^^^^^^^^^
|
||||
|
||||
This function is used to define the product ID.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void productID(const char * pid);//max 16 chars
|
||||
|
||||
productRevision
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
This function is used to define the product revision.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void productRevision(const char * ver);//max 4 chars
|
||||
|
||||
mediaPresent
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Set the ``mediaPresent`` configuration.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void mediaPresent(bool media_present);
|
||||
|
||||
onStartStop
|
||||
^^^^^^^^^^^
|
||||
|
||||
Set the ``onStartStop`` callback function.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onStartStop(msc_start_stop_cb cb);
|
||||
|
||||
onRead
|
||||
^^^^^^
|
||||
|
||||
Set the ``onRead`` callback function.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onRead(msc_read_cb cb);
|
||||
|
||||
onWrite
|
||||
^^^^^^^
|
||||
|
||||
Set the ``onWrite`` callback function.
|
||||
|
||||
.. code-block:: arduino
|
||||
|
||||
void onWrite(msc_write_cb cb);
|
||||
|
||||
Example Code
|
||||
------------
|
||||
|
||||
Here is an example of how to use the USB MSC.
|
||||
|
||||
FirmwareMSC
|
||||
***********
|
||||
|
||||
.. literalinclude:: ../../../libraries/USB/examples/FirmwareMSC/FirmwareMSC.ino
|
||||
:language: arduino
|
||||
|
||||
.. _USB.org: https://www.usb.org/developers
|
@ -5,15 +5,15 @@ Arduino as a ESP-IDF component
|
||||
ESP32 Arduino lib-builder
|
||||
-------------------------
|
||||
|
||||
For a simplified method, see `lib-builder <lib_builder>`_.
|
||||
For a simplified method, see `lib-builder <https://github.com/espressif/esp32-arduino-lib-builder>`_.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
.. note:: Latest Arduino Core ESP32 version is now compatible with [ESP-IDF v4.4](https://github.com/espressif/esp-idf/tree/release/v4.4). Please consider this compability when using Arduino as component in ESP-IDF.
|
||||
.. note:: Latest Arduino Core ESP32 version is now compatible with `ESP-IDF v4.4 <https://github.com/espressif/esp-idf/tree/release/v4.4>`_. Please consider this compability when using Arduino as component in ESP-IDF.
|
||||
|
||||
- Download and install `ESP-IDF <https://github.com/espressif/esp-idf>`_.
|
||||
- Create blank idf project (from one of the examples).
|
||||
- Create blank ESP-IDF project (use sample_project from /examples/get-started) or choose one of the examples.
|
||||
- In the project folder, create a new folder called `components` and clone this repository inside the new created folder.
|
||||
|
||||
.. code-block:: bash
|
||||
@ -26,10 +26,19 @@ Installation
|
||||
cd ../.. && \
|
||||
idf.py menuconfig
|
||||
|
||||
Option 1. Using Arduino setup() and loop()
|
||||
******************************************
|
||||
|
||||
- The `idf.py menuconfig` has some Arduino options.
|
||||
- On `Autostart Arduino setup and loop on boot`.
|
||||
- If you enable these options, your main.cpp should be formated like any other sketch.
|
||||
- Turn on `Autostart Arduino setup and loop on boot`.
|
||||
- In main folder rename file `main.c` to `main.cpp`.
|
||||
- In main folder open file `CMakeList.txt` and change `main.c` to `main.cpp` as described below.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf_component_register(SRCS "main.cpp" INCLUDE_DIRS ".")
|
||||
|
||||
- Your main.cpp should be formated like any other sketch.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@ -45,14 +54,17 @@ Installation
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
- Otherwise, you need to implement ```app_main()``` and call ```initArduino();``` in it.
|
||||
Option 2. Using ESP-IDF appmain()
|
||||
*********************************
|
||||
|
||||
- You need to implement ``app_main()`` and call ``initArduino();`` in it.
|
||||
|
||||
Keep in mind that setup() and loop() will not be called in this case.
|
||||
If you plan to base your code on examples provided in `examples <https://github.com/espressif/esp-idf/tree/master/examples>`_, please make sure to move the app_main() function in main.cpp from the files in the example.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
//file: main.cpp
|
||||
//file: main.c or main.cpp
|
||||
#include "Arduino.h"
|
||||
|
||||
extern "C" void app_main()
|
||||
@ -69,7 +81,11 @@ If you plan to base your code on examples provided in `examples <https://github.
|
||||
- If enabled, WiFi will start with the last known configuration
|
||||
- Otherwise it will wait for WiFi.begin
|
||||
|
||||
- ```idf.py -p <your-board-serial-port> flash monitor``` will build, upload and open serial monitor to your board
|
||||
Build, flash and monitor
|
||||
************************
|
||||
|
||||
- For both options use command ``idf.py -p <your-board-serial-port> flash monitor``
|
||||
- It will build, upload and open serial monitor to your board.
|
||||
|
||||
Logging To Serial
|
||||
-----------------
|
||||
|
@ -37,7 +37,7 @@ SoC Stable Development Datasheet
|
||||
ESP32 Yes Yes `ESP32 Datasheet`_
|
||||
ESP32-S2 Yes Yes `ESP32-S2 Datasheet`_
|
||||
ESP32-C3 Yes Yes `ESP32-C3 Datasheet`_
|
||||
ESP32-S3 No No Not Available Yet
|
||||
ESP32-S3 No No `ESP32-S3 Datasheet`_
|
||||
======== ====== =========== ===================================
|
||||
|
||||
See `Boards <boards/boards.html>`_ for more details about ESP32 development boards.
|
||||
@ -122,6 +122,7 @@ Resources
|
||||
.. _ESP32 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
.. _ESP32-S2 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
|
||||
.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
|
||||
.. _ESP32-S3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf
|
||||
.. _Arduino.cc: https://www.arduino.cc/en/Main/Software
|
||||
.. _Arduino Reference: https://www.arduino.cc/reference/en/
|
||||
.. _ESP32 Forum: https://esp32.com
|
||||
|
@ -29,7 +29,7 @@ This is the preferred and easiest way to install Arduino-ESP32.
|
||||
|
||||
.. note::
|
||||
Starting with the Arduino IDE version 1.6.4, Arduino allows installation of third-party platform
|
||||
packages using Boards Manager. We have packages available for Windows, macOS, and Linux (x86, amd64, armhf and arm64).
|
||||
packages using Boards Manager. We have packages available for Windows, macOS, and Linux.
|
||||
|
||||
To start the installation process using the Boards Managaer, follow these steps:
|
||||
|
||||
@ -61,10 +61,11 @@ To start the installation process using the Boards Managaer, follow these steps:
|
||||
Windows
|
||||
-------
|
||||
|
||||
Steps to install Arduino ESP32 support on Windows:
|
||||
.. warning:: Arduino ESP32 core v2.x.x cannot be used on Windows 8.x x86 (32 bits), Windows 7 or earlier. The Windows 32 bits OS is no longer supported by this toolchain.
|
||||
|
||||
.. note::
|
||||
Tested on Windows 10 32 and 64 bit machines.
|
||||
The Arduino ESP32 v1.0.6 still works on WIN32. You might want to install python 3.8.x because it is the latest release supported by Windows 7.
|
||||
|
||||
Steps to install Arduino ESP32 support on Windows:
|
||||
|
||||
**Step 1**
|
||||
|
||||
|
@ -86,4 +86,5 @@ The Arduino ESP32 offers some unique APIs, described in this section:
|
||||
I2C <api/i2c>
|
||||
RainMaker <api/rainmaker>
|
||||
Reset Reason <api/reset_reason>
|
||||
USB <api/usb.rst>
|
||||
Wi-Fi <api/wifi>
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define HID_CARD_READER 0x03C6
|
||||
#define HID_DIGITAL_PEN 0x03C7
|
||||
#define HID_BARCODE 0x03C8
|
||||
#define HID_BRAILLE_DISPLAY 0x03C9
|
||||
|
||||
class BLEHIDDevice {
|
||||
public:
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Author: Thomas M. (ArcticSnowSky)
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)
|
||||
|
||||
#include "BTAddress.h"
|
||||
#include <string>
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef COMPONENTS_CPP_UTILS_BTADDRESS_H_
|
||||
#define COMPONENTS_CPP_UTILS_BTADDRESS_H_
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)
|
||||
#include <esp_gap_bt_api.h> // ESP32 BT
|
||||
#include <string>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)
|
||||
|
||||
//#include <map>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if defined(CONFIG_BT_ENABLED)
|
||||
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)
|
||||
|
||||
|
||||
#include <esp_err.h>
|
||||
|
@ -1,9 +1,7 @@
|
||||
void setup()
|
||||
{
|
||||
//setup channel 0 with frequency 312500 Hz
|
||||
sigmaDeltaSetup(0, 312500);
|
||||
//attach pin 18 to channel 0
|
||||
sigmaDeltaAttachPin(18,0);
|
||||
//setup on pin 18, channel 0 with frequency 312500 Hz
|
||||
sigmaDeltaSetup(18,0, 312500);
|
||||
//initialize channel 0 to off
|
||||
sigmaDeltaWrite(0, 0);
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
ESP32 Arduino creates a task to run setup() and then to execute loop() continuously
|
||||
This task can be found at https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/main.cpp
|
||||
|
||||
By default "loopTask" will be created with a stack size of 8KB.
|
||||
This should be plenty for most general sketches.
|
||||
|
||||
There is a way to change the stack size of this task by using
|
||||
SET_LOOP_TASK_STACK_SIZE(size);
|
||||
It will bypass the default stack size of 8KB and allow the user to define a new size.
|
||||
|
||||
It is recommend this value to be higher than 8KB, for instance 16KB.
|
||||
This increasing may be necessary for the sketches that use deep recursion for instance.
|
||||
|
||||
In this example, you can verify it by changing or just commenting out SET_LOOP_TASK_STACK_SIZE();
|
||||
*/
|
||||
|
||||
|
||||
// This sets Arduino Stack Size - comment this line to use default 8K stack size
|
||||
SET_LOOP_TASK_STACK_SIZE(16*1024); // 16KB
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
Serial.printf("Arduino Stack was set to %d bytes", getArduinoLoopTaskStackSize());
|
||||
|
||||
// Print unused stack for the task that is running setup()
|
||||
Serial.printf("\nSetup() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(1000);
|
||||
|
||||
// Print unused stack for the task that is running loop() - the same as for setup()
|
||||
Serial.printf("\nLoop() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL));
|
||||
}
|
@ -12,7 +12,7 @@ class MyProcessor {
|
||||
|
||||
public:
|
||||
MyProcessor(uint8_t pin, float nanoTicks) {
|
||||
assert((rmt_recv = rmtInit(21, false, RMT_MEM_192)));
|
||||
assert((rmt_recv = rmtInit(21, RMT_RX_MODE, RMT_MEM_192)));
|
||||
|
||||
realNanoTick = rmtSetTick(rmt_recv, nanoTicks);
|
||||
};
|
||||
|
@ -5,6 +5,17 @@
|
||||
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
// ESP32 C3 has only 2 channels for RX and 2 for TX, thus MAX RMT_MEM is 128
|
||||
#define RMT_TX_PIN 4
|
||||
#define RMT_RX_PIN 5
|
||||
#define RMT_MEM_RX RMT_MEM_128
|
||||
#else
|
||||
#define RMT_TX_PIN 18
|
||||
#define RMT_RX_PIN 21
|
||||
#define RMT_MEM_RX RMT_MEM_192
|
||||
#endif
|
||||
|
||||
rmt_data_t my_data[256];
|
||||
rmt_data_t data[256];
|
||||
|
||||
@ -18,18 +29,19 @@ void setup()
|
||||
Serial.begin(115200);
|
||||
events = xEventGroupCreate();
|
||||
|
||||
if ((rmt_send = rmtInit(18, true, RMT_MEM_64)) == NULL)
|
||||
if ((rmt_send = rmtInit(RMT_TX_PIN, RMT_TX_MODE, RMT_MEM_64)) == NULL)
|
||||
{
|
||||
Serial.println("init sender failed\n");
|
||||
}
|
||||
if ((rmt_recv = rmtInit(21, false, RMT_MEM_192)) == NULL)
|
||||
if ((rmt_recv = rmtInit(RMT_RX_PIN, RMT_RX_MODE, RMT_MEM_RX)) == NULL)
|
||||
{
|
||||
Serial.println("init receiver failed\n");
|
||||
}
|
||||
|
||||
float realTick = rmtSetTick(rmt_send, 100);
|
||||
printf("real tick set to: %fns\n", realTick);
|
||||
|
||||
// both will keep same tick
|
||||
realTick = rmtSetTick(rmt_recv, 100);
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
@ -182,7 +182,7 @@ void setup()
|
||||
Serial.begin(115200);
|
||||
|
||||
// Initialize the channel to capture up to 192 items
|
||||
if ((rmt_recv = rmtInit(21, false, RMT_MEM_192)) == NULL)
|
||||
if ((rmt_recv = rmtInit(21, RMT_RX_MODE, RMT_MEM_192)) == NULL)
|
||||
{
|
||||
Serial.println("init receiver failed\n");
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
if ((rmt_send = rmtInit(18, true, RMT_MEM_64)) == NULL)
|
||||
if ((rmt_send = rmtInit(18, RMT_TX_MODE, RMT_MEM_64)) == NULL)
|
||||
{
|
||||
Serial.println("init sender failed\n");
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ
|
||||
break;
|
||||
#endif
|
||||
case ETH_PHY_KSZ8081:
|
||||
#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4,3,0)
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4,4,0)
|
||||
eth_phy = esp_eth_phy_new_ksz8081(&phy_config);
|
||||
#else
|
||||
log_e("unsupported ethernet type 'ETH_PHY_KSZ8081'");
|
||||
|
@ -200,6 +200,7 @@ bool HTTPClient::begin(String url, const char* CAcert)
|
||||
end();
|
||||
}
|
||||
|
||||
clear();
|
||||
_port = 443;
|
||||
if (!beginInternal(url, "https")) {
|
||||
return false;
|
||||
@ -226,6 +227,7 @@ bool HTTPClient::begin(String url)
|
||||
end();
|
||||
}
|
||||
|
||||
clear();
|
||||
_port = 80;
|
||||
if (!beginInternal(url, "http")) {
|
||||
return begin(url, (const char*)NULL);
|
||||
@ -243,7 +245,6 @@ bool HTTPClient::begin(String url)
|
||||
bool HTTPClient::beginInternal(String url, const char* expectedProtocol)
|
||||
{
|
||||
log_v("url: %s", url.c_str());
|
||||
clear();
|
||||
|
||||
// check for : (http: or https:
|
||||
int index = url.indexOf(':');
|
||||
@ -1212,8 +1213,8 @@ int HTTPClient::handleHeaderResponse()
|
||||
return HTTPC_ERROR_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
clear();
|
||||
|
||||
_returnCode = 0;
|
||||
_size = -1;
|
||||
_canReuse = _reuse;
|
||||
|
||||
String transferEncoding;
|
||||
|
@ -8,9 +8,6 @@ arduino-esp32 includes libraries for Arduino compatibility along with some objec
|
||||
### AsyncUDP
|
||||
Asynchronous task driven UDP datagram client/server
|
||||
|
||||
### AzureIoT
|
||||
Library to interact with Microsoft Azure IoT services
|
||||
|
||||
### BLE
|
||||
Bluetooth Low Energy v4.2 client/server framework
|
||||
|
||||
@ -43,6 +40,9 @@ arduino-esp32 includes libraries for Arduino compatibility along with some objec
|
||||
### ESPmDNS
|
||||
mDNS service advertising
|
||||
|
||||
### Ethernet
|
||||
Ethernet networking
|
||||
|
||||
### FFat
|
||||
FAT indexed filesystem on SPI flash
|
||||
|
||||
@ -55,6 +55,12 @@ arduino-esp32 includes libraries for Arduino compatibility along with some objec
|
||||
### HTTPUpdate
|
||||
Download a firmware update from HTTPd and apply it using Update
|
||||
|
||||
### HTTPUpdateServer
|
||||
Upload a firmware for the update from HTTPd
|
||||
|
||||
### LittleFS
|
||||
LittleFS (File System)
|
||||
|
||||
### NetBIOS
|
||||
NetBIOS name advertiser
|
||||
|
||||
@ -85,6 +91,9 @@ arduino-esp32 includes libraries for Arduino compatibility along with some objec
|
||||
### Update
|
||||
Sketch Update using ESP32 OTA functionality
|
||||
|
||||
### USB
|
||||
Universal Serial Bus driver (device only)
|
||||
|
||||
### WebServer
|
||||
A simple HTTP daemon
|
||||
|
||||
@ -95,4 +104,4 @@ arduino-esp32 includes libraries for Arduino compatibility along with some objec
|
||||
Arduino compatible WiFi client object using embedded encryption
|
||||
|
||||
### Wire
|
||||
Arduino compatible I2C driver (master only)
|
||||
Arduino compatible I2C driver
|
||||
|
@ -0,0 +1,193 @@
|
||||
//This example demonstrates the ESP RainMaker with a standard Switch device.
|
||||
#include "RMaker.h"
|
||||
#include "WiFi.h"
|
||||
#include "WiFiProv.h"
|
||||
|
||||
#define DEFAULT_POWER_MODE false
|
||||
const char *service_name = "PROV_SONOFF_DUALR3";
|
||||
const char *pop = "123456";
|
||||
|
||||
// GPIO for push button
|
||||
static uint8_t gpio_reset = 0;
|
||||
// GPIO for switch
|
||||
static uint8_t gpio_switch1 = 32;
|
||||
static uint8_t gpio_switch2 = 33;
|
||||
// GPIO for virtual device
|
||||
static uint8_t gpio_relay1 = 27;
|
||||
static uint8_t gpio_relay2 = 14;
|
||||
/* Variable for reading pin status*/
|
||||
bool switch_state_ch1 = true;
|
||||
bool switch_state_ch2 = true;
|
||||
// GPIO for link status LED
|
||||
static uint8_t gpio_led = 13;
|
||||
|
||||
struct LightSwitch {
|
||||
const uint8_t pin;
|
||||
bool pressed;
|
||||
};
|
||||
|
||||
// Define the light switches for channel 1 and 2
|
||||
LightSwitch switch_ch1 = {gpio_switch1, false};
|
||||
LightSwitch switch_ch2 = {gpio_switch2, false};
|
||||
|
||||
//The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
|
||||
static Switch my_switch1("Switch_ch1", &gpio_relay1);
|
||||
static Switch my_switch2("Switch_ch2", &gpio_relay2);
|
||||
|
||||
void sysProvEvent(arduino_event_t *sys_event)
|
||||
{
|
||||
switch (sys_event->event_id) {
|
||||
case ARDUINO_EVENT_PROV_START:
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
|
||||
printQR(service_name, pop, "ble");
|
||||
#else
|
||||
Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
|
||||
printQR(service_name, pop, "softap");
|
||||
#endif
|
||||
break;
|
||||
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
|
||||
Serial.printf("\nConnected to Wi-Fi!\n");
|
||||
digitalWrite(gpio_led, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
|
||||
{
|
||||
const char *device_name = device->getDeviceName();
|
||||
const char *param_name = param->getParamName();
|
||||
|
||||
if(strcmp(device_name, "Switch_ch1") == 0) {
|
||||
|
||||
Serial.printf("Lightbulb = %s\n", val.val.b? "true" : "false");
|
||||
|
||||
if(strcmp(param_name, "Power") == 0) {
|
||||
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
|
||||
switch_state_ch1 = val.val.b;
|
||||
(switch_state_ch1 == false) ? digitalWrite(gpio_relay1, LOW) : digitalWrite(gpio_relay1, HIGH);
|
||||
param->updateAndReport(val);
|
||||
}
|
||||
|
||||
} else if(strcmp(device_name, "Switch_ch2") == 0) {
|
||||
|
||||
Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");
|
||||
|
||||
if(strcmp(param_name, "Power") == 0) {
|
||||
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
|
||||
switch_state_ch2 = val.val.b;
|
||||
(switch_state_ch2 == false) ? digitalWrite(gpio_relay2, LOW) : digitalWrite(gpio_relay2, HIGH);
|
||||
param->updateAndReport(val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ARDUINO_ISR_ATTR isr(void* arg) {
|
||||
LightSwitch* s = static_cast<LightSwitch*>(arg);
|
||||
s->pressed = true;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
uint32_t chipId = 0;
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
// Configure the input GPIOs
|
||||
pinMode(gpio_reset, INPUT);
|
||||
pinMode(switch_ch1.pin, INPUT_PULLUP);
|
||||
attachInterruptArg(switch_ch1.pin, isr, &switch_ch1, CHANGE);
|
||||
pinMode(switch_ch2.pin, INPUT_PULLUP);
|
||||
attachInterruptArg(switch_ch2.pin, isr, &switch_ch2, CHANGE);
|
||||
|
||||
// Set the Relays GPIOs as output mode
|
||||
pinMode(gpio_relay1, OUTPUT);
|
||||
pinMode(gpio_relay2, OUTPUT);
|
||||
pinMode(gpio_led, OUTPUT);
|
||||
// Write to the GPIOs the default state on booting
|
||||
digitalWrite(gpio_relay1, DEFAULT_POWER_MODE);
|
||||
digitalWrite(gpio_relay2, DEFAULT_POWER_MODE);
|
||||
digitalWrite(gpio_led, false);
|
||||
|
||||
Node my_node;
|
||||
my_node = RMaker.initNode("Sonoff Dual R3");
|
||||
|
||||
//Standard switch device
|
||||
my_switch1.addCb(write_callback);
|
||||
my_switch2.addCb(write_callback);
|
||||
|
||||
//Add switch device to the node
|
||||
my_node.addDevice(my_switch1);
|
||||
my_node.addDevice(my_switch2);
|
||||
|
||||
//This is optional
|
||||
RMaker.enableOTA(OTA_USING_PARAMS);
|
||||
//If you want to enable scheduling, set time zone for your region using setTimeZone().
|
||||
//The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
|
||||
// RMaker.setTimeZone("Asia/Shanghai");
|
||||
// Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
|
||||
RMaker.enableTZService();
|
||||
RMaker.enableSchedule();
|
||||
|
||||
//Service Name
|
||||
for(int i=0; i<17; i=i+8) {
|
||||
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||||
}
|
||||
|
||||
Serial.printf("\nChip ID: %d Service Name: %s\n", chipId, service_name);
|
||||
|
||||
Serial.printf("\nStarting ESP-RainMaker\n");
|
||||
RMaker.start();
|
||||
|
||||
WiFi.onEvent(sysProvEvent);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
|
||||
#else
|
||||
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (switch_ch1.pressed) {
|
||||
Serial.printf("Switch 1 has been changed\n");
|
||||
switch_ch1.pressed = false;
|
||||
// Toggle switch 1 device state
|
||||
switch_state_ch1 = !switch_state_ch1;
|
||||
Serial.printf("Toggle State to %s.\n", switch_state_ch1 ? "true" : "false");
|
||||
my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, switch_state_ch1);
|
||||
(switch_state_ch1 == false) ? digitalWrite(gpio_relay1, LOW) : digitalWrite(gpio_relay1, HIGH);
|
||||
} else if (switch_ch2.pressed) {
|
||||
Serial.printf("Switch 2 has been changed\n");
|
||||
switch_ch2.pressed = false;
|
||||
// Toggle switch 2 device state
|
||||
switch_state_ch2 = !switch_state_ch2;
|
||||
Serial.printf("Toggle State to %s.\n", switch_state_ch2 ? "true" : "false");
|
||||
my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, switch_state_ch2);
|
||||
(switch_state_ch2 == false) ? digitalWrite(gpio_relay2, LOW) : digitalWrite(gpio_relay2, HIGH);
|
||||
}
|
||||
|
||||
// Read GPIO0 (external button to reset device
|
||||
if(digitalRead(gpio_reset) == LOW) { //Push button pressed
|
||||
Serial.printf("Reset Button Pressed!\n");
|
||||
// Key debounce handling
|
||||
delay(100);
|
||||
int startTime = millis();
|
||||
while(digitalRead(gpio_reset) == LOW) delay(50);
|
||||
int endTime = millis();
|
||||
|
||||
if ((endTime - startTime) > 10000) {
|
||||
// If key pressed for more than 10secs, reset all
|
||||
Serial.printf("Reset to factory.\n");
|
||||
RMakerFactoryReset(2);
|
||||
} else if ((endTime - startTime) > 3000) {
|
||||
Serial.printf("Reset Wi-Fi.\n");
|
||||
// If key pressed for more than 3secs, but less than 10, reset Wi-Fi
|
||||
RMakerWiFiReset(2);
|
||||
}
|
||||
}
|
||||
delay(100);
|
||||
}
|
@ -609,6 +609,11 @@ unknown_card:
|
||||
|
||||
DSTATUS ff_sd_status(uint8_t pdrv)
|
||||
{
|
||||
if(sdCommand(pdrv, SEND_STATUS, 0, NULL) == 0xFF)
|
||||
{
|
||||
log_e("Check status failed");
|
||||
return STA_NOINIT;
|
||||
}
|
||||
return s_cards[pdrv]->status;
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ static void wifi_sta_config(wifi_config_t * wifi_config, const char * ssid=NULL,
|
||||
if(ssid != NULL && ssid[0] != 0){
|
||||
_wifi_strncpy((char*)wifi_config->sta.ssid, ssid, 32);
|
||||
if(password != NULL && password[0] != 0){
|
||||
wifi_config->sta.threshold.authmode = WIFI_AUTH_WEP;
|
||||
wifi_config->sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
|
||||
_wifi_strncpy((char*)wifi_config->sta.password, password, 64);
|
||||
}
|
||||
if(bssid != NULL){
|
||||
@ -176,15 +176,19 @@ wl_status_t WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_
|
||||
wifi_config_t conf;
|
||||
memset(&conf, 0, sizeof(wifi_config_t));
|
||||
_wifi_strncpy(reinterpret_cast<char*>(conf.sta.ssid), ssid, 32);
|
||||
conf.sta.scan_method = WIFI_ALL_CHANNEL_SCAN; //force full scan to be able to choose the nearest / strongest AP
|
||||
|
||||
if(passphrase) {
|
||||
_wifi_strncpy(reinterpret_cast<char*>(conf.sta.password), passphrase, 64);
|
||||
}
|
||||
|
||||
wifi_config_t current_conf;
|
||||
wifi_sta_config(&conf, ssid, passphrase, bssid, channel);
|
||||
if(channel == 0) {
|
||||
// If no specific channel specified, then do an slower WIFI_ALL_CHANNEL_SCAN
|
||||
wifi_sta_config(&conf, ssid, passphrase, bssid, channel, WIFI_ALL_CHANNEL_SCAN);
|
||||
}
|
||||
else
|
||||
wifi_sta_config(&conf, ssid, passphrase, bssid, channel, WIFI_FAST_SCAN);
|
||||
|
||||
wifi_config_t current_conf;
|
||||
if(esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_STA, ¤t_conf) != ESP_OK){
|
||||
log_e("get current config failed!");
|
||||
return WL_CONNECT_FAILED;
|
||||
|
@ -45,6 +45,8 @@ static int _handle_error(int err, const char * function, int line)
|
||||
|
||||
void ssl_init(sslclient_context *ssl_client)
|
||||
{
|
||||
// reset embedded pointers to zero
|
||||
memset(ssl_client, 0, sizeof(sslclient_context));
|
||||
mbedtls_ssl_init(&ssl_client->ssl_ctx);
|
||||
mbedtls_ssl_config_init(&ssl_client->ssl_conf);
|
||||
mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx);
|
||||
@ -232,6 +234,7 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
|
||||
ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0);
|
||||
|
||||
if (ret != 0) {
|
||||
mbedtls_x509_crt_free(&ssl_client->client_cert); // cert+key are free'd in pair
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
@ -280,7 +283,6 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
|
||||
memset(buf, 0, sizeof(buf));
|
||||
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags);
|
||||
log_e("Failed to verify peer certificate! verification info: %s", buf);
|
||||
stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue.
|
||||
return handle_error(ret);
|
||||
} else {
|
||||
log_v("Certificate verified.");
|
||||
@ -313,10 +315,20 @@ void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, cons
|
||||
ssl_client->socket = -1;
|
||||
}
|
||||
|
||||
// avoid memory leak if ssl connection attempt failed
|
||||
if (ssl_client->ssl_conf.ca_chain != NULL) {
|
||||
mbedtls_x509_crt_free(&ssl_client->ca_cert);
|
||||
}
|
||||
if (ssl_client->ssl_conf.key_cert != NULL) {
|
||||
mbedtls_x509_crt_free(&ssl_client->client_cert);
|
||||
mbedtls_pk_free(&ssl_client->client_key);
|
||||
}
|
||||
mbedtls_ssl_free(&ssl_client->ssl_ctx);
|
||||
mbedtls_ssl_config_free(&ssl_client->ssl_conf);
|
||||
mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx);
|
||||
mbedtls_entropy_free(&ssl_client->entropy_ctx);
|
||||
// reset embedded pointers to zero
|
||||
memset(ssl_client, 0, sizeof(sslclient_context));
|
||||
}
|
||||
|
||||
|
||||
|
@ -354,7 +354,7 @@ uint8_t TwoWire::endTransmission(bool sendStop)
|
||||
return 4;
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint16_t address, uint8_t size, bool sendStop)
|
||||
size_t TwoWire::requestFrom(uint16_t address, size_t size, bool sendStop)
|
||||
{
|
||||
if(is_slave){
|
||||
log_e("Bus is in Slave Mode");
|
||||
@ -445,42 +445,47 @@ void TwoWire::flush(void)
|
||||
//i2cFlush(num); // cleanup
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
|
||||
size_t TwoWire::requestFrom(uint8_t address, size_t len, bool sendStop)
|
||||
{
|
||||
return requestFrom(static_cast<uint16_t>(address), static_cast<uint8_t>(quantity), static_cast<bool>(sendStop));
|
||||
return requestFrom(static_cast<uint16_t>(address), static_cast<size_t>(len), static_cast<bool>(sendStop));
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint16_t address, uint8_t quantity, uint8_t sendStop)
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t len, uint8_t sendStop)
|
||||
{
|
||||
return requestFrom(address, static_cast<uint8_t>(quantity), static_cast<bool>(sendStop));
|
||||
return requestFrom(static_cast<uint16_t>(address), static_cast<size_t>(len), static_cast<bool>(sendStop));
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint16_t address, uint8_t len, uint8_t sendStop)
|
||||
{
|
||||
return requestFrom(address, static_cast<size_t>(len), static_cast<bool>(sendStop));
|
||||
}
|
||||
|
||||
/* Added to match the Arduino function definition: https://github.com/arduino/ArduinoCore-API/blob/173e8eadced2ad32eeb93bcbd5c49f8d6a055ea6/api/HardwareI2C.h#L39
|
||||
* See: https://github.com/arduino-libraries/ArduinoECCX08/issues/25
|
||||
*/
|
||||
size_t TwoWire::requestFrom(uint8_t address, size_t len, bool stopBit)
|
||||
uint8_t TwoWire::requestFrom(uint16_t address, uint8_t len, bool stopBit)
|
||||
{
|
||||
return requestFrom((uint16_t)address, (uint8_t)len, stopBit);
|
||||
return requestFrom((uint16_t)address, (size_t)len, stopBit);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
|
||||
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t len)
|
||||
{
|
||||
return requestFrom(static_cast<uint16_t>(address), static_cast<uint8_t>(quantity), true);
|
||||
return requestFrom(static_cast<uint16_t>(address), static_cast<size_t>(len), true);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(uint16_t address, uint8_t quantity)
|
||||
uint8_t TwoWire::requestFrom(uint16_t address, uint8_t len)
|
||||
{
|
||||
return requestFrom(address, static_cast<uint8_t>(quantity), true);
|
||||
return requestFrom(address, static_cast<size_t>(len), true);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(int address, int quantity)
|
||||
uint8_t TwoWire::requestFrom(int address, int len)
|
||||
{
|
||||
return requestFrom(static_cast<uint16_t>(address), static_cast<uint8_t>(quantity), true);
|
||||
return requestFrom(static_cast<uint16_t>(address), static_cast<size_t>(len), true);
|
||||
}
|
||||
|
||||
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
|
||||
uint8_t TwoWire::requestFrom(int address, int len, int sendStop)
|
||||
{
|
||||
return static_cast<uint8_t>(requestFrom(static_cast<uint16_t>(address), static_cast<uint8_t>(quantity), static_cast<bool>(sendStop)));
|
||||
return static_cast<uint8_t>(requestFrom(static_cast<uint16_t>(address), static_cast<size_t>(len), static_cast<bool>(sendStop)));
|
||||
}
|
||||
|
||||
void TwoWire::beginTransmission(int address)
|
||||
|
@ -93,6 +93,7 @@ public:
|
||||
uint8_t endTransmission(bool sendStop);
|
||||
uint8_t endTransmission(void);
|
||||
|
||||
size_t requestFrom(uint16_t address, size_t size, bool sendStop);
|
||||
uint8_t requestFrom(uint16_t address, uint8_t size, bool sendStop);
|
||||
uint8_t requestFrom(uint16_t address, uint8_t size, uint8_t sendStop);
|
||||
size_t requestFrom(uint8_t address, size_t len, bool stopBit);
|
||||
|
0
package.json
Executable file → Normal file
0
package.json
Executable file → Normal file
14
platform.txt
14
platform.txt
File diff suppressed because one or more lines are too long
@ -81,7 +81,6 @@ env.Append(
|
||||
"-Wl,--gc-sections",
|
||||
"-fno-rtti",
|
||||
"-fno-lto",
|
||||
"-Wl,--wrap=mbedtls_mpi_exp_mod",
|
||||
"-Wl,--wrap=longjmp",
|
||||
"-Wl,--undefined=uxTopUsedPriority",
|
||||
"-T", "esp32.rom.redefined.ld",
|
||||
@ -100,6 +99,7 @@ env.Append(
|
||||
"-u", "pthread_include_pthread_impl",
|
||||
"-u", "pthread_include_pthread_cond_impl",
|
||||
"-u", "pthread_include_pthread_local_storage_impl",
|
||||
"-u", "pthread_include_pthread_rwlock_impl",
|
||||
"-u", "ld_include_highint_hdl",
|
||||
"-u", "start_app",
|
||||
"-u", "start_app_other_cores",
|
||||
@ -303,8 +303,9 @@ env.Append(
|
||||
"UNITY_INCLUDE_CONFIG_H",
|
||||
"WITH_POSIX",
|
||||
"_GNU_SOURCE",
|
||||
("IDF_VER", '\\"v4.4-dev-3569-g6a7d83af19\\"'),
|
||||
("IDF_VER", '\\"v4.4-beta1-189-ga79dc75f0a\\"'),
|
||||
"ESP_PLATFORM",
|
||||
"_POSIX_READER_WRITER_LOCKS",
|
||||
"ARDUINO_ARCH_ESP32",
|
||||
"ESP32",
|
||||
("F_CPU", "$BOARD_F_CPU"),
|
||||
|
@ -81,7 +81,6 @@ env.Append(
|
||||
"-Wl,--gc-sections",
|
||||
"-fno-rtti",
|
||||
"-fno-lto",
|
||||
"-Wl,--wrap=mbedtls_mpi_exp_mod",
|
||||
"-Wl,--undefined=uxTopUsedPriority",
|
||||
"-Wl,--wrap=_Unwind_SetEnableExceptionFdeSorting",
|
||||
"-Wl,--wrap=__register_frame_info_bases",
|
||||
@ -127,6 +126,7 @@ env.Append(
|
||||
"-u", "pthread_include_pthread_impl",
|
||||
"-u", "pthread_include_pthread_cond_impl",
|
||||
"-u", "pthread_include_pthread_local_storage_impl",
|
||||
"-u", "pthread_include_pthread_rwlock_impl",
|
||||
"-u", "start_app",
|
||||
"-u", "__ubsan_include",
|
||||
"-u", "__assert_func",
|
||||
@ -293,8 +293,9 @@ env.Append(
|
||||
"UNITY_INCLUDE_CONFIG_H",
|
||||
"WITH_POSIX",
|
||||
"_GNU_SOURCE",
|
||||
("IDF_VER", '\\"v4.4-dev-3569-g6a7d83af19\\"'),
|
||||
("IDF_VER", '\\"v4.4-beta1-189-ga79dc75f0a\\"'),
|
||||
"ESP_PLATFORM",
|
||||
"_POSIX_READER_WRITER_LOCKS",
|
||||
"ARDUINO_ARCH_ESP32",
|
||||
"ESP32",
|
||||
("F_CPU", "$BOARD_F_CPU"),
|
||||
|
@ -95,6 +95,7 @@ env.Append(
|
||||
"-u", "pthread_include_pthread_impl",
|
||||
"-u", "pthread_include_pthread_cond_impl",
|
||||
"-u", "pthread_include_pthread_local_storage_impl",
|
||||
"-u", "pthread_include_pthread_rwlock_impl",
|
||||
"-u", "ld_include_highint_hdl",
|
||||
"-u", "start_app",
|
||||
"-u", "__ubsan_include",
|
||||
@ -289,8 +290,9 @@ env.Append(
|
||||
"UNITY_INCLUDE_CONFIG_H",
|
||||
"WITH_POSIX",
|
||||
"_GNU_SOURCE",
|
||||
("IDF_VER", '\\"v4.4-dev-3569-g6a7d83af19\\"'),
|
||||
("IDF_VER", '\\"v4.4-beta1-189-ga79dc75f0a\\"'),
|
||||
"ESP_PLATFORM",
|
||||
"_POSIX_READER_WRITER_LOCKS",
|
||||
"ARDUINO_ARCH_ESP32",
|
||||
"ESP32",
|
||||
("F_CPU", "$BOARD_F_CPU"),
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -68,7 +68,7 @@ typedef struct {
|
||||
*/
|
||||
static inline void esp_apptrace_lock_init(esp_apptrace_lock_t *lock)
|
||||
{
|
||||
vPortCPUInitializeMutex(&lock->mux);
|
||||
portMUX_INITIALIZE(&lock->mux);
|
||||
lock->int_state = 0;
|
||||
}
|
||||
|
||||
|
@ -291,6 +291,7 @@
|
||||
#define CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0 1
|
||||
#define CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN 752
|
||||
#define CONFIG_ESP32_WIFI_MGMT_SBUF_NUM 32
|
||||
#define CONFIG_ESP_WIFI_SOFTAP_SUPPORT 1
|
||||
#define CONFIG_ESP_COREDUMP_ENABLE_TO_NONE 1
|
||||
#define CONFIG_FATFS_CODEPAGE_850 1
|
||||
#define CONFIG_FATFS_CODEPAGE 850
|
||||
@ -346,6 +347,7 @@
|
||||
#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0
|
||||
#define CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER 1
|
||||
#define CONFIG_FREERTOS_DEBUG_OCDAWARE 1
|
||||
#define CONFIG_FREERTOS_FPU_IN_ISR 1
|
||||
#define CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT 1
|
||||
#define CONFIG_HAL_ASSERTION_EQUALS_SYSTEM 1
|
||||
#define CONFIG_HAL_DEFAULT_ASSERTION_LEVEL 2
|
||||
@ -370,6 +372,7 @@
|
||||
#define CONFIG_LWIP_ESP_GRATUITOUS_ARP 1
|
||||
#define CONFIG_LWIP_GARP_TMR_INTERVAL 60
|
||||
#define CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 32
|
||||
#define CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID 1
|
||||
#define CONFIG_LWIP_DHCP_RESTORE_LAST_IP 1
|
||||
#define CONFIG_LWIP_DHCP_OPTIONS_LEN 128
|
||||
#define CONFIG_LWIP_DHCPS 1
|
||||
@ -403,7 +406,9 @@
|
||||
#define CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS 5
|
||||
#define CONFIG_LWIP_ICMP 1
|
||||
#define CONFIG_LWIP_MAX_RAW_PCBS 16
|
||||
#define CONFIG_LWIP_SNTP_MAX_SERVERS 1
|
||||
#define CONFIG_LWIP_SNTP_MAX_SERVERS 3
|
||||
#define CONFIG_LWIP_DHCP_GET_NTP_SRV 1
|
||||
#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1
|
||||
#define CONFIG_LWIP_SNTP_UPDATE_DELAY 3600000
|
||||
#define CONFIG_LWIP_ESP_LWIP_ASSERT 1
|
||||
#define CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT 1
|
||||
@ -636,6 +641,7 @@
|
||||
#define CONFIG_OPTIMIZATION_LEVEL_RELEASE CONFIG_COMPILER_OPTIMIZATION_SIZE
|
||||
#define CONFIG_POST_EVENTS_FROM_IRAM_ISR CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR
|
||||
#define CONFIG_POST_EVENTS_FROM_ISR CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
#define CONFIG_REDUCE_PHY_TX_POWER CONFIG_ESP_PHY_REDUCE_TX_POWER
|
||||
#define CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE
|
||||
#define CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN
|
||||
#define CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS
|
||||
@ -673,5 +679,5 @@
|
||||
#define CONFIG_ULP_COPROC_RESERVE_MEM CONFIG_ESP32_ULP_COPROC_RESERVE_MEM
|
||||
#define CONFIG_WARN_WRITE_STRINGS CONFIG_COMPILER_WARN_WRITE_STRINGS
|
||||
#define CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP
|
||||
#define CONFIG_ARDUINO_IDF_COMMIT "6a7d83af19"
|
||||
#define CONFIG_ARDUINO_IDF_COMMIT "a79dc75f0a"
|
||||
#define CONFIG_ARDUINO_IDF_BRANCH "release/v4.4"
|
||||
|
@ -174,7 +174,6 @@ typedef enum {
|
||||
/**
|
||||
* @brief Interrupt masks for MCPWM capture
|
||||
*/
|
||||
__attribute__ ((deprecated("please use callback function to avoid directly accessing registers")))
|
||||
typedef enum {
|
||||
MCPWM_LL_INTR_CAP0 = BIT(27), ///< Capture 0 happened
|
||||
MCPWM_LL_INTR_CAP1 = BIT(28), ///< Capture 1 happened
|
||||
@ -922,7 +921,6 @@ esp_err_t mcpwm_sync_invert_gpio_synchro(mcpwm_unit_t mcpwm_num, mcpwm_sync_sign
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Function pointer error.
|
||||
*/
|
||||
__attribute__((deprecated("interrupt events are handled by driver, please use callback")))
|
||||
esp_err_t mcpwm_isr_register(mcpwm_unit_t mcpwm_num, void (*fn)(void *), void *arg, int intr_alloc_flags,
|
||||
intr_handle_t *handle);
|
||||
|
||||
|
@ -6,11 +6,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/soc_caps.h"
|
||||
@ -29,6 +27,10 @@ extern "C" {
|
||||
#include "esp32h2/rom/secure_boot.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_ERR_EFUSE 0x1600 /*!< Base error code for efuse api. */
|
||||
#define ESP_OK_EFUSE_CNT (ESP_ERR_EFUSE + 0x01) /*!< OK the required number of bits is set. */
|
||||
#define ESP_ERR_EFUSE_CNT_IS_FULL (ESP_ERR_EFUSE + 0x02) /*!< Error field is full. */
|
||||
|
@ -48,6 +48,15 @@ namespace dl
|
||||
output[2] = input & 0xF8; // red
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert RGB565 image to RGB888 image.
|
||||
*
|
||||
* @param image ptr of RGB565 image
|
||||
* @param image_shape shape of the input image
|
||||
* @return Tensor<uint8_t>* output RGB88 image
|
||||
*/
|
||||
Tensor<uint8_t> *convert_image_rgb565_to_rgb888(uint16_t *image, std::vector<int> &image_shape);
|
||||
|
||||
/**
|
||||
* @brief Convert RGB565 pixel to Gray.
|
||||
*
|
||||
@ -435,5 +444,48 @@ namespace dl
|
||||
*/
|
||||
Tensor<uint8_t> *rgb2hsv(Tensor<uint8_t> &image, bool bgr = false, bool fast = true);
|
||||
|
||||
/**
|
||||
* @brief resize an image to the target shape.
|
||||
*
|
||||
* @param image the input image Tensor
|
||||
* @param target_shape the target shape of the resized image.
|
||||
* @param resize_type one of IMAGE_RESIZE_BILINEAR or IMAGE_RESIZE_MEAN or IMAGE_RESIZE_NEAREST
|
||||
* @return Tensor<uint8_t>* the pointer of the resized image Tensor
|
||||
*/
|
||||
Tensor<uint8_t> *resize_image(Tensor<uint8_t> &image, std::vector<int> target_shape, resize_type_t resize_type);
|
||||
|
||||
/**
|
||||
* @brief resize an image to the target shape.
|
||||
*
|
||||
* @param image the input image Tensor
|
||||
* @param resized_image the resized image Tensor
|
||||
* @param resize_type one of IMAGE_RESIZE_BILINEAR or IMAGE_RESIZE_MEAN or IMAGE_RESIZE_NEAREST
|
||||
*/
|
||||
void resize_image(Tensor<uint8_t> &image, Tensor<uint8_t> &resized_image, resize_type_t resize_type);
|
||||
|
||||
/**
|
||||
* @brief resize an image to the target shape with nearest method.
|
||||
*
|
||||
* @tparam T
|
||||
* @param image the pointer of the input image
|
||||
* @param input_shape the input shape of the image
|
||||
* @param target_shape the target shape of the resized image
|
||||
* @return T* the pointer of the resized image
|
||||
*/
|
||||
template <typename T>
|
||||
T *resize_image_nearest(T *image, std::vector<int> input_shape, std::vector<int> target_shape);
|
||||
|
||||
/**
|
||||
* @brief resize an image to the target shape with nearest method.
|
||||
*
|
||||
* @tparam T
|
||||
* @param image the pointer of the input image
|
||||
* @param input_shape the input shape of the image
|
||||
* @param resized_image the pointer of the resized image
|
||||
* @param target_shape the target shape of the resized image
|
||||
*/
|
||||
template <typename T>
|
||||
void resize_image_nearest(T *image, std::vector<int> input_shape, T *resized_image, std::vector<int> target_shape);
|
||||
|
||||
} // namespace image
|
||||
} // namespace dl
|
||||
|
@ -57,10 +57,10 @@ namespace dl
|
||||
const char *name = "AvgPool2D") : Layer(name),
|
||||
output_exponent(output_exponent),
|
||||
filter_shape(filter_shape),
|
||||
padding_type(padding_type),
|
||||
padding(padding),
|
||||
stride_y(stride_y),
|
||||
stride_x(stride_x),
|
||||
padding_type(padding_type),
|
||||
padding(padding),
|
||||
output_shape({})
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
|
@ -36,7 +36,10 @@ namespace dl
|
||||
* false: the output will store to a separate memory
|
||||
*/
|
||||
ExpandDims(std::vector<int> axis, const char *name = "ExpandDims", bool inplace = false) : Layer(name),
|
||||
axis(axis), inplace(inplace), output_shape({})
|
||||
output_shape({}),
|
||||
axis(axis),
|
||||
output(NULL),
|
||||
inplace(inplace)
|
||||
{
|
||||
}
|
||||
|
||||
@ -63,19 +66,18 @@ namespace dl
|
||||
this->output_exponent = input.exponent;
|
||||
if (!this->inplace)
|
||||
{
|
||||
if (this->output != NULL)
|
||||
if (this->output == NULL)
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
}
|
||||
this->output->set_exponent(this->output_exponent);
|
||||
this->output->set_shape(this->output_shape);
|
||||
this->output->set_shape(input.shape);
|
||||
this->output->expand_dims(this->axis);
|
||||
this->output->free_element();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->output = &input;
|
||||
this->output->set_shape(this->output_shape);
|
||||
this->output->expand_dims(this->axis);
|
||||
}
|
||||
this->output_shape = this->output->shape;
|
||||
|
@ -32,7 +32,7 @@ namespace dl
|
||||
* @param inplace true: the output will store to input0
|
||||
* false: the output will store to a separate memory
|
||||
*/
|
||||
Flatten(const char *name = "Flatten", bool inplace = false) : Layer(name), inplace(inplace), output_shape({})
|
||||
Flatten(const char *name = "Flatten", bool inplace = false) : Layer(name), output(NULL), inplace(inplace), output_shape({})
|
||||
{}
|
||||
|
||||
/**
|
||||
@ -59,7 +59,7 @@ namespace dl
|
||||
this->output_shape = {input.get_size()};
|
||||
if (!this->inplace)
|
||||
{
|
||||
if (this->output != NULL)
|
||||
if (this->output == NULL)
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
}
|
||||
|
@ -10,14 +10,14 @@ namespace dl
|
||||
namespace layer
|
||||
{
|
||||
/**
|
||||
* @brief LeakyReLU(input).
|
||||
* @brief LeakyRelu(input).
|
||||
*
|
||||
* @tparam feature_t supports int16_t and int8_t,
|
||||
* - int16_t: stands for operation in int16_t quantize
|
||||
* - int8_t: stands for operation in int8_t quantize
|
||||
*/
|
||||
template <typename feature_t>
|
||||
class LeakyReLU : public Layer
|
||||
class LeakyRelu : public Layer
|
||||
{
|
||||
private:
|
||||
feature_t activation_alpha; /*<! quantized alpha >*/
|
||||
@ -28,7 +28,7 @@ namespace dl
|
||||
std::vector<int> output_shape; /*<! output shape of leakyrelu >*/
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new LeakyReLU object
|
||||
* @brief Construct a new LeakyRelu object
|
||||
*
|
||||
* @param activation_alpha quantized alpha
|
||||
* @param activation_exponent exponent of quantized alpha
|
||||
@ -36,7 +36,7 @@ namespace dl
|
||||
* @param inplace true: the output will store to input0
|
||||
* false: the output will store to a separate memory
|
||||
*/
|
||||
LeakyReLU(const int activation_alpha, const int activation_exponent, const char *name = "LeakyReLU", bool inplace = false) : Layer(name), output(NULL), output_shape({})
|
||||
LeakyRelu(const int activation_alpha, const int activation_exponent, const char *name = "LeakyRelu", bool inplace = false) : Layer(name), output(NULL), output_shape({})
|
||||
{
|
||||
this->activation_alpha = activation_alpha;
|
||||
this->activation_exponent = activation_exponent;
|
||||
@ -44,10 +44,10 @@ namespace dl
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy the LeakyReLU object
|
||||
* @brief Destroy the LeakyRelu object
|
||||
*
|
||||
*/
|
||||
~LeakyReLU()
|
||||
~LeakyRelu()
|
||||
{
|
||||
if ((!this->inplace) && (this->output != NULL))
|
||||
{
|
||||
@ -66,7 +66,7 @@ namespace dl
|
||||
this->output_shape = input.shape;
|
||||
if (!this->inplace)
|
||||
{
|
||||
if (this->output != NULL)
|
||||
if (this->output == NULL)
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
}
|
||||
@ -90,7 +90,7 @@ namespace dl
|
||||
/**
|
||||
* @brief Get the output
|
||||
*
|
||||
* @return Tensor<feature_t>& LeakyReLU result
|
||||
* @return Tensor<feature_t>& LeakyRelu result
|
||||
*/
|
||||
Tensor<feature_t> &get_output()
|
||||
{
|
||||
@ -98,11 +98,11 @@ namespace dl
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call LeakyReLU operation.
|
||||
* @brief Call LeakyRelu operation.
|
||||
*
|
||||
* @param input as an input
|
||||
* @param assign_core not effective yet
|
||||
* @return LeakyReLU result
|
||||
* @return LeakyRelu result
|
||||
*/
|
||||
Tensor<feature_t> &call(Tensor<feature_t> &input, const std::vector<int> &assign_core = CONFIG_DEFAULT_ASSIGN_CORE)
|
||||
{
|
||||
@ -130,7 +130,7 @@ namespace dl
|
||||
{
|
||||
this->output->set_shape(this->output_shape);
|
||||
}
|
||||
nn::leakyrelu<true>(*this->output, input, this->activation_alpha, this->activation_exponent, assign_core);
|
||||
nn::leakyrelu(*this->output, input, this->activation_alpha, this->activation_exponent, assign_core);
|
||||
DL_LOG_LAYER_LATENCY_END(this->name, "leakyrelu");
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ namespace dl
|
||||
|
||||
if (!this->inplace)
|
||||
{
|
||||
if (this->output != NULL)
|
||||
if (this->output == NULL)
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
}
|
||||
@ -132,7 +132,7 @@ namespace dl
|
||||
{
|
||||
this->output->set_shape(this->output_shape);
|
||||
}
|
||||
nn::max2d<true>(*this->output, input0, input1, assign_core);
|
||||
nn::max2d(*this->output, input0, input1, assign_core);
|
||||
DL_LOG_LAYER_LATENCY_END(this->name, "max2d");
|
||||
}
|
||||
|
||||
|
@ -53,10 +53,10 @@ namespace dl
|
||||
const int stride_x = 1,
|
||||
const char *name = "MaxPool2D") : Layer(name),
|
||||
filter_shape(filter_shape),
|
||||
padding_type(padding_type),
|
||||
padding(padding),
|
||||
stride_y(stride_y),
|
||||
stride_x(stride_x),
|
||||
padding_type(padding_type),
|
||||
padding(padding),
|
||||
output_shape({})
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
|
@ -68,7 +68,7 @@ namespace dl
|
||||
|
||||
if (!this->inplace)
|
||||
{
|
||||
if (this->output != NULL)
|
||||
if (this->output == NULL)
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
}
|
||||
@ -132,7 +132,7 @@ namespace dl
|
||||
{
|
||||
this->output->set_shape(this->output_shape);
|
||||
}
|
||||
nn::min2d<true>(*this->output, input0, input1, assign_core);
|
||||
nn::min2d(*this->output, input0, input1, assign_core);
|
||||
DL_LOG_LAYER_LATENCY_END(this->name, "min2d");
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ namespace dl
|
||||
|
||||
if (!this->inplace)
|
||||
{
|
||||
if (this->output != NULL)
|
||||
if (this->output == NULL)
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
}
|
||||
@ -140,7 +140,7 @@ namespace dl
|
||||
{
|
||||
this->output->set_shape(this->output_shape);
|
||||
}
|
||||
nn::mul2d<true>(*this->output, input0, input1, this->activation, assign_core);
|
||||
nn::mul2d(*this->output, input0, input1, this->activation, assign_core);
|
||||
DL_LOG_LAYER_LATENCY_END(this->name, "mul2d");
|
||||
}
|
||||
|
||||
|
@ -10,17 +10,17 @@ namespace dl
|
||||
namespace layer
|
||||
{
|
||||
/**
|
||||
* @brief PReLU(input).
|
||||
* @brief PRelu(input).
|
||||
*
|
||||
* @tparam feature_t supports int16_t and int8_t,
|
||||
* - int16_t: stands for operation in int16_t quantize
|
||||
* - int8_t: stands for operation in int8_t quantize
|
||||
*/
|
||||
template <typename feature_t>
|
||||
class PReLU : public Layer
|
||||
class PRelu : public Layer
|
||||
{
|
||||
private:
|
||||
feature_t *activation_element; /*<! quantized alpha elements along channel axis >*/
|
||||
const feature_t *activation_element; /*<! quantized alpha elements along channel axis >*/
|
||||
int activation_exponent; /*<! exponent of quantized alpha elements >*/
|
||||
Tensor<feature_t> *output; /*<! output ptr of prelu >*/
|
||||
bool inplace; /*<! true: the output will store to input0
|
||||
@ -28,7 +28,7 @@ namespace dl
|
||||
std::vector<int> output_shape; /*<! output shape of prelu >*/
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new PReLU object
|
||||
* @brief Construct a new PRelu object
|
||||
*
|
||||
* @param activation_element quantized alpha elements along channel axis
|
||||
* @param activation_exponent exponent of quantized alpha elements
|
||||
@ -36,10 +36,10 @@ namespace dl
|
||||
* @param inplace true: the output will store to input0
|
||||
* false: the output will store to a separate memory
|
||||
*/
|
||||
PReLU(const feature_t *activation_element,
|
||||
PRelu(const feature_t *activation_element,
|
||||
const int activation_exponent = 0,
|
||||
const char *name = NULL,
|
||||
bool inplace = "PReLU") : Layer(name),
|
||||
const char *name = "PRelu",
|
||||
bool inplace = false) : Layer(name),
|
||||
activation_element(activation_element),
|
||||
activation_exponent(activation_exponent),
|
||||
output(NULL),
|
||||
@ -49,10 +49,10 @@ namespace dl
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy the PReLU object
|
||||
* @brief Destroy the PRelu object
|
||||
*
|
||||
*/
|
||||
~PReLU()
|
||||
~PRelu()
|
||||
{
|
||||
if ((!this->inplace) && (this->output != NULL))
|
||||
{
|
||||
@ -71,7 +71,7 @@ namespace dl
|
||||
this->output_shape = input.shape;
|
||||
if (!this->inplace)
|
||||
{
|
||||
if (this->output != NULL)
|
||||
if (this->output == NULL)
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
}
|
||||
@ -94,7 +94,7 @@ namespace dl
|
||||
/**
|
||||
* @brief Get the output
|
||||
*
|
||||
* @return Tensor<feature_t>& PReLU result
|
||||
* @return Tensor<feature_t>& PRelu result
|
||||
*/
|
||||
Tensor<feature_t> &get_output()
|
||||
{
|
||||
@ -102,11 +102,11 @@ namespace dl
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call PReLU operation.
|
||||
* @brief Call PRelu operation.
|
||||
*
|
||||
* @param input as an input
|
||||
* @param assign_core not effective yet
|
||||
* @return PReLU result
|
||||
* @return PRelu result
|
||||
*/
|
||||
Tensor<feature_t> &call(Tensor<feature_t> &input, const std::vector<int> &assign_core = CONFIG_DEFAULT_ASSIGN_CORE)
|
||||
{
|
||||
@ -125,7 +125,7 @@ namespace dl
|
||||
|
||||
DL_LOG_LAYER_LATENCY_START();
|
||||
nn::prelu(*this->output, input, this->activation_element, this->activation_exponent, assign_core);
|
||||
DL_LOG_LAYER_LATENCY_END(this->name, "leakyrelu");
|
||||
DL_LOG_LAYER_LATENCY_END(this->name, "prelu");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -135,7 +135,7 @@ namespace dl
|
||||
this->output->set_shape(this->output_shape);
|
||||
}
|
||||
nn::prelu(*this->output, input, this->activation_element, this->activation_exponent, assign_core);
|
||||
DL_LOG_LAYER_LATENCY_END(this->name, "leakyrelu");
|
||||
DL_LOG_LAYER_LATENCY_END(this->name, "prelu");
|
||||
}
|
||||
|
||||
return *this->output;
|
||||
|
@ -18,7 +18,7 @@ namespace dl
|
||||
* - int8_t: stands for operation in int8_t quantize
|
||||
*/
|
||||
template <typename feature_t>
|
||||
class ReLU : public Layer
|
||||
class Relu : public Layer
|
||||
{
|
||||
private:
|
||||
Tensor<feature_t> *output; /*<! output ptr of relu >*/
|
||||
@ -33,7 +33,7 @@ namespace dl
|
||||
* @param inplace true: the output will store to input0
|
||||
* false: the output will store to a separate memory
|
||||
*/
|
||||
ReLU(const char *name = "ReLU", bool inplace = false) : Layer(name),
|
||||
Relu(const char *name = "Relu", bool inplace = false) : Layer(name),
|
||||
output(NULL), inplace(inplace), output_shape({})
|
||||
{
|
||||
}
|
||||
@ -42,7 +42,7 @@ namespace dl
|
||||
* @brief Destroy the ReLU object
|
||||
*
|
||||
*/
|
||||
~ReLU()
|
||||
~Relu()
|
||||
{
|
||||
if ((!this->inplace) && (this->output != NULL))
|
||||
{
|
||||
@ -61,7 +61,7 @@ namespace dl
|
||||
this->output_shape = input.shape;
|
||||
if (!this->inplace)
|
||||
{
|
||||
if (this->output != NULL)
|
||||
if (this->output == NULL)
|
||||
{
|
||||
this->output = new Tensor<feature_t>;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user