Compare commits

...

210 Commits
2.0.1 ... 2.0.3

Author SHA1 Message Date
142fceb856 Fix uploader tool for ESPduino32 board (#6665) 2022-05-04 14:36:15 +03:00
ba591fd958 Added non-destructive TinyUF2 support for UM ESP32-S3 boards (#6668)
Implemented a new method for allowing folks to preserve their TinyUF2 bootloader setup when flashing their boards via Arduino IDE, without being locked out of not using it if they want to use a different partition.

Adafruit had already added support for keeping (reflashing) the TinyUF2 bootloader when flashing via Arduino IDE (thanks @ladyada ), but the issue with it is it doesn't allow users to not choose to use it. Even if they select a specific partition scheme from the partition drop down list, it ignores that selection and only does the TinyUF2 partitioning/bootloader thing.

We wanted to let users choose between keeping their TinyUF2 partitioning and bootloader, or choose another partition scheme and have the TinyUF2 support disabled and just operate like they would expect.

We've implemented this by adding the TinyUF2 support as a partition scheme option, and using these build options in platform.txt to choose to use teh UF2 path or use the standard path.
2022-05-04 14:35:46 +03:00
4453ca5493 Properly handle ARDUINO_PARTITION define in PlatformIO (#6681)
This fixes possible issues when developers specify arbitrary partition files
using relative or absolute paths.

Additionally, hyphens in filenames are replaced with underscores to
avoid compilation warnings "ISO C++11 requires whitespace after the macro name"

Resolves platformio/platform-espressif32#787
2022-05-04 14:31:30 +03:00
ce2cd111a1 Fixes INADDR_NONE (#6659)
Description of Change

Fixes IPAddress INADDR_NONE declaration when using Arduino WiFi or ETH.
This symbol was defined as 0xffffffff by lwip /inet.h, making it impossible to use INADDR_NONE correctly.

This PR only works when <wifi-provisioning/wifi_config.h> has a modification to include <lwip/ip4_addr.h> instead of <lwip/inet.h>. This will be done directly to the sdk folder in the github structure and it has been fixed in IDF by a separated Merge Request. This will be reflected in the future, for good.

Tests scenarios

This PR was tested with all Arduino WiFi examples, including AsyncUDP. Also with ETH examples.
It was also tested for #6610 test cases.
Testing done for ESP32, ESP32-S2, ESP32-C3 and ESP32-S3.

Related links

fixes #6610
fixes #6247
fixes #4732
2022-04-29 11:13:07 +03:00
5f6d093d4a Add more controls over WiFi.begin and WiFi.scan (#6651)
Added options to WiFi STA for connect:
- setMinSecurity: default WIFI_AUTH_WPA2_PSK
- setScanMethod: default WIFI_FAST_SCAN
- setSortMethod: default WIFI_CONNECT_AP_BY_SIGNAL (required all channels scan method)

Added parameters for SSID and BSSID to WiFi.scanNetworks()

Fixes: #6485
Fixes: Any issue about WiFi connecting slower now than in 1.0.x
2022-04-28 11:01:58 +03:00
51bf1832b8 Fix onRequest being called for every slave address (#6649)
Fixes: https://github.com/espressif/arduino-esp32/issues/5907
2022-04-28 02:31:32 +03:00
384dbc2081 Added support for Trueverit ESP32 Universal IoT Driver MK III (#6640)
Add support for the Trueverit Universal IoT Driver MK III (https://www.trueverit.com/)

The board will be released on market using electronic distributors soon, as the other one board added via #5269

This new board (referred as MK III) has onboard Texas Instruments RTL8201 Eth PHY chip.
2022-04-27 12:45:23 +03:00
f2cfe78705 Fix HTTP Client failing to connect because of wrong timeout (#6633) 2022-04-27 03:36:38 +03:00
45583af189 [Docs] Actualize PlatformIO installation instructions (#6629)
* Actualize PlatformIO installation instructions

Split instructions for stable and upstream versions

* Add link to platformio.ini documentation
2022-04-26 14:29:54 +01:00
f60cd8a069 Add CI job which tries to build arduino-esp32 as a component (#5842)
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2022-04-26 15:10:17 +03:00
5fa0c2010e Added Unexpected Maker Reflow Master Pro (UM RMP) board (#6630)
Fixed wrong SCK and MISO pins for TinyS2
2022-04-26 14:55:19 +03:00
adfaaecc65 add AirM2M_CORE_ESP32C3 board (#6613)
* add AirM2M_CORE_ESP32C3 board
2022-04-26 14:50:14 +03:00
0dd517dc9f enh(log) salvage TAG from ESP_IDF log-statements > (#6567)
by converting result log-rows from the 1st line to the 2nd (`NET` is the tag):
```
[ 73419][D][telelogger.cpp:915] telemetry(): state: 33C

[ 73419][D][telelogger.cpp:915] telemetry(): [NET] state: 33C
```

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2022-04-26 14:46:42 +03:00
823fe77e41 Uniform behaviour of WiFiClientSecure and WiFiClient setTimeout() (#6562)
* Uniform timeout WiFiClient-WiFiClientSecure

* Added missing prototype

* Add socket check on setTimeout
2022-04-26 14:46:07 +03:00
a9d33de70e Call i2c_set_timeout in i2cSetClock (#6537) 2022-04-26 14:45:14 +03:00
d7ffd573d0 Fixes stream load memory leak in WifiSecureClient for SSL CACert, Certificate, and (#6387)
Private Key. Issue presented during any subsequent invocation of loadCACert, loadCertificate, and
loadPrivateKey, respectively, after the first invocation.
2022-04-26 14:44:37 +03:00
b88a70a0bd Allow BluetoothSerial::connect() with specified channel and more options (#6380)
* BTAddress const, add bool()

* BTAdvertisedDevice: const functions

* BluetoothSerial: add: getChannels, add isClosed, add read/peek timeout, add connect with channel#

* BluetoothSerial: add sec_mask, role in ::connect

* BluetoothSerial add discover and connect with channel number example

* DiscoverConnect: add SPP_ENABLED check

* DiscoverConnect: disable on esp32s3
2022-04-26 14:41:29 +03:00
f3bdfb31f9 Touch change to init only selected GPIO. (#6609)
* Separated init for touch / channel called by touchRead()

* compile error

* Fixed touch_V2 + ISR
2022-04-26 14:34:50 +03:00
d8a99ed449 Added RainMaker support on Arduino IDE for ESP32-C3/S2/S3 (#6598)
* Added RainMaker support on Arduino IDE for ESP32-C3/S2/S3

Closes #6573
Note related to the issue #6435
2022-04-26 14:12:20 +03:00
0a1ba74b60 Update LittleFS PlatformIO example (#6617) 2022-04-26 14:02:14 +03:00
1aa16104ff Enable LittleFs sketches for C3 (#6618)
* LittleFs is working with C3

* Delete .skip.esp32c3
2022-04-26 14:00:14 +03:00
22c51579da publish.yml: Remove a leftover parenthesis that was making the workflow (#6620)
Description of Change

Remove a leftover parenthesis that was making the workflow that was making the workflow invalid.

Tests scenarios

Github Workflow.

Related links

https://github.com/espressif/arduino-esp32/actions/runs/2213167501

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2022-04-26 13:59:03 +03:00
f0636d515f Add support for extra flash images (#6625)
This PR adds support for uploading additional flash images (e.g. Adafruit Tiny UF2 bootloader) specified in board manifests.

Additionally, the PR switches the PlatformIO CI script to the upstream version of the ESP32 dev-platform (basically reverts changes introduced in #5387 as they are no longer required).
2022-04-26 13:58:16 +03:00
b3c203db26 Pull request/Issue Templates and Readme update (#6577)
* Templates and readme

* Templates_and_readme
2022-04-21 17:54:50 +03:00
323bbbf63b workflows/publish.yml: Run the workflow on success and failure only. (#6531)
* workflows/publish.yml: Run the workflow on success and failure only.
This prevents trying to run when the trigger was cancelled or skipped.
In these cases there will be no event file to upload.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>

* scripts/sketch_utils.sh: Move the logic that gets the build dir after
the part that retrieves the arguments.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>

* workflows/hil.yml: Update the HIL runners tags.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>

* workflows/hil.yml: Remove the Check Artifacts step.  That was only
useful for debugging.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2022-04-21 17:53:37 +03:00
02f4178b72 BUGFIX: FS read + speed improvements for SD (#6569)
* Revert "Edited VFSFileImpl::read to use both read/fread (#6456)"

This reverts commit 7b89b39e10.

* Added default file buffer size + function to change it by user
2022-04-21 17:51:44 +03:00
e1c9606531 Changed type of LEDC frequency from double to uint32_t (#6570) 2022-04-21 17:50:55 +03:00
fb60efd592 Change pinMode OUTPUT to INPUT_OUTPUT (#6602)
* Change OUTPUT to INPUT_OUTPUT

To match the official Arduino API.
2022-04-21 17:49:54 +03:00
12045d335b Update camera example to support face detection and recognition (#6603)
Fixes: #6508
2022-04-21 17:48:47 +03:00
45b7fa05b6 IDF release/v4.4 b8050b365e (#6594) 2022-04-20 12:23:18 +03:00
d3340837c7 Delete stale.yml 2022-04-20 10:54:46 +03:00
6cfe4613e4 Amend "GPIO refactoring (#6259)" (#6527) 2022-04-05 11:28:59 +03:00
7dc8ca4e1e Update OTA Command for IDE 2.0 2022-04-05 03:33:42 +03:00
d4e20294e5 Add support for ArduinoIDE 2.0.0 (#6506)
OTA is not yet working properly on the new IDE. Info: https://github.com/arduino/arduino-ide/issues/740#issuecomment-1086595394
2022-04-04 17:19:23 +03:00
f1acc432af Fix Ticker::Active crash if _ticker null (#6511) (#6513) 2022-04-04 14:45:14 +03:00
6fe1c4c5d6 Correct less- and greater-than operators (#6521)
Lets Manufacturer ranges in bluetooth address space be filtered correctly
2022-04-04 14:44:32 +03:00
5d6b9d0939 Compiler error (#6523)
Error on compile Arduino as an ESP-IDF component
2022-04-04 14:29:45 +03:00
6b72fee59b add S3 board (#6518) 2022-04-04 14:27:53 +03:00
a1409ef90d add package.json to release zip (#6501)
* add package.json to release zip

so it is directly useable from PlatformIO
2022-04-04 14:24:17 +03:00
ab197e12a9 Fix - wrong path to file (#6505) 2022-03-31 16:54:33 +03:00
1e388a24ce Update toolchain to gcc8_4_0-esp-2021r2-patch3 and esptool to 3.3 (#6497)
* Update toolchain to gcc8_4_0-esp-2021r2-patch3

* Update esptool to 3.3

* Remove old files

* Update package_esp32_index.template.json

* use esptool v3.3 (#6498)

could be used for all. Nice would be releasing in Platformio registry.

* Switch toolchain for PIO CI

Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com>
2022-03-29 18:12:16 +03:00
7c9b837cdb Fix Reading MAC from efuse for ESP32 Arduino 2.x.x (#6458) (#6459)
Also support ESP_IDF_VERSION_MAJOR > 3
Fixes #6458

Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2022-03-29 16:54:47 +03:00
5c5a112ffa Re-apply #6464 2022-03-29 12:24:23 +03:00
31510f4e17 IDF release/v4.4 c29343eb94 (#6493)
esp-dl: master d949350
esp-dsp: master 07aa7b1
esp-rainmaker: master 5af4f64
esp-sr: master d05cf97
esp32-camera: master 86a4951
esp_littlefs: master 5f0d614
2022-03-28 18:17:59 +03:00
aa783e6ac4 Reordering - HardwareSerial Constructor (#6492) 2022-03-28 17:04:38 +03:00
9d188f5c67 Add S3 in Headline (#6491) 2022-03-28 15:48:45 +03:00
51040cc4eb Fix linking failure for space in path in PlatformIO builder scripts (#6464)
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2022-03-28 15:48:13 +03:00
c26e3f4299 Adds HardwareSerial::setRxTimeout() (#6397)
* Adds HardwareSerial::onReceiveTimeout()

* Fixed typo

* Changes requested

* Fix eventQueueReset

* Changed _onReceiveTimeout to _rxTimeout for consistency

* Uniform uart_set_rx_timeout condition

* test _uart not NULL in eventQueueReset()

check if _uart is not NULL before using it.

* revert last commit - no need for it

reverting last change made - it is not necessary.

* adds onReceive() parameter 

In order to allow the user to choose if onReceive() call back will be called only when UART Rx timeout happens or also when UART FIFO gets 120 bytes, 
a new parameter has been added to onReceive() with the default behavior based on timeout.

    void onReceive(OnReceiveCb function, bool onlyOnTimeout = true);

   onReceive will setup a callback that will be called whenever an UART interruption occurs (UART_INTR_RXFIFO_FULL or UART_INTR_RXFIFO_TOUT)
   UART_INTR_RXFIFO_FULL interrupt triggers at UART_FULL_THRESH_DEFAULT bytes received (defined as 120 bytes by default in IDF)
   UART_INTR_RXFIFO_TOUT interrupt triggers at UART_TOUT_THRESH_DEFAULT symbols passed without any reception (defined as 10 symbos by default in IDF)
   onlyOnTimeout parameter will define how onReceive will behave:
   Default: true -- The callback will only be called when RX Timeout happens. 
                           Whole stream of bytes will be ready for being read on the callback function at once.
                           This option may lead to Rx Overflow depending on the Rx Buffer Size and number of bytes received in the streaming
            false --    The callback will be called when FIFO reaches 120 bytes and also on RX Timeout.
                           The stream of incommig bytes will be "split" into blocks of 120 bytes on each callback.
                           This option avoid any sort of Rx Overflow, but leaves the UART packet reassembling work to the Application.

* Adds onReceive() parameter for timeout only

* Adds back setRxTimeout()

* Adds setRxTimeout()

* CI Syntax error - "," missing

Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
2022-03-28 14:18:30 +03:00
ab34321a16 add variant init code for the feather s2 tft (#6447) 2022-03-28 12:58:25 +03:00
8ee5f0a11e Esp32 s3 support (#6341)
Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Co-authored-by: Unexpected Maker <seon@unexpectedmaker.com>
Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
Co-authored-by: Tomáš Pilný <34927466+PilnyTomas@users.noreply.github.com>
Co-authored-by: Pedro Minatel <pedro.minatel@espressif.com>
Co-authored-by: Ivan Grokhotkov <ivan@espressif.com>
Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Co-authored-by: Limor "Ladyada" Fried <limor@ladyada.net>
2022-03-28 12:09:41 +03:00
3f79097d5f Add Preferences library API and tutorial documents (#6442)
* Add Preferences library API and tutorial documents

Add API and tutorial documents for the  Preferences library.

* Revise per review

Correct some errors. Remove the "wordiness" is a few places.

* Correct link to Preferences API

Update the references and link to the Preferences API document.

Co-authored-by: Pedro Minatel <pedro.minatel@espressif.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2022-03-28 12:02:10 +03:00
e03a9f5c53 (boards.txt) Add partition scheme menu for WeMos WiFi&Bluetooth Battery (#6479) 2022-03-28 11:48:41 +03:00
528c071299 Adding sectorsize() and numSectors() to SD (#6457)
* Update SD.h

* Added numSectors() and sectorSize()
2022-03-28 11:46:15 +03:00
7b89b39e10 Edited VFSFileImpl::read to use both read/fread (#6456)
* Edited VFSFileImpl::read to use both read/fread

* Added missing include
2022-03-28 11:44:10 +03:00
905f8f2991 Warns about SSP only available for ESP32 (#6455) 2022-03-28 11:43:10 +03:00
c25feca639 Change "python" to "python3" (#6448)
First aid for ESP32 builds not passing in Arduino IDE on macOS Monterey 12.3 that obsolete "python2.7".
2022-03-28 11:42:14 +03:00
6014ff433f Fixes USB CDC setRxBufferSize(), begin(), _onRX() (#6413)
* Fixes USB CDC setRxBufferSize(), begin(), _onRX()

* Fixes SetRxBufferSize(0) with end()

* Fixes reset when 2x call to end()

* Adds RX_OVERFLOW_EVENT and Queue Copy in setBufferSize

* changed event name to ARDUINO_USB_CDC_RX_OVERFLOW_EVENT
2022-03-28 11:40:02 +03:00
77e95311e0 Adds HardwareSerial::setTxBufferSize() (#6383)
* Adds HardwareSerial::setTxBufferSize()

* uartBegin def fix

* checks TXBufferSize  as defined in IDF

Makes sure that the buffer size will not cause a reset to the board.

* Removes double value in Rx/Tx Buffer Size 

Keeps Rx/Tx buffer size as set, not doubling it. It makes the process more clear.

Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
2022-03-28 11:37:12 +03:00
8fe0efe8c0 Fix boot freeze when trying to init PSRAM on Pico D4 (#6434)
* Fix boot freeze when trying to init PSRAM on Pico D4

* Don't deconfigure GPIO16/17 in Pico D4
2022-03-23 13:10:21 +02:00
0b10c8b79e [Docs] Added the guideline for documentation (#6409)
* [Docs] Added the guideline for documentation

* [Docs] Added more descriptions about the API documenting process

* [Docs] PR review

* [Docs] PR review and minor typos and grammar fixes
2022-03-18 18:28:18 +02:00
d977359e34 Added another overloaded WiFiSTAClass::begin() function that provides… (#6398)
Summary

The examples demonstrate how to create a WPA2 Enterprise connection, but it requires using various direct esp_idf functions. This patch is intended to create another overloaded version of the WiFi.begin() function that allows a user to create a WPA2 Enterprise connection in much the same way as different kinds of connections.

My only question for the core maintainers is whether I should leave those #ifdef's in there. I added them so that it was easy to disable all the code I added via defines from my platformio.ini file, but they technically aren't necessary.

Impact

This should make it easier for novice users to create WPA2 Enterprise connections. For my university, I didn't need a root certificate or the client certificate or client key, so I haven't been able to debug those scenarios, but I built the begin functions to allow any one of those to be used, if needed.

I can confirm that eduroam-style WPA2 Enterprise networks that only require authentication with a username and password works as expected.
2022-03-15 16:34:15 +02:00
ba8024c0d2 Some board variant fixes (#6411)
* make work with rev C pcb

* use #define for easy testing
2022-03-14 12:45:16 +02:00
e87b87d04c Add missing include in AsyncUDP.h (#6412)
In my project I'm getting the error 
```
In file included from lib/Discovery/Discovery.cpp:2:
C:/Users/David/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src/AsyncUDP.h:47:1: error: expected class-name before '{' token
```

Adding a reference to Stream.h fixes it.
2022-03-14 12:44:24 +02:00
9b9744f25f publish.yml: Limit the running scope of the publish Workflow. (#6428)
1. Don't run the publish test result workflow on the master
branch.
2. Run only on Pull Requests to be able to publish the result as a PR comment.
3. Avoid running when the triggering workflow was skipped, this will
   cause a failure as no file will be uploaded.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2022-03-14 12:30:33 +02:00
68daea4a4a Implemented tone and noTone; fixes #980 (#6402)
* Implemented tone
* Tone uses queue; implemented setToneChannel
2022-03-10 17:26:30 +02:00
52e018198b publish.yml: Remove the debug job and fix an error in the workflow. (#6408)
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2022-03-10 15:41:02 +02:00
883241229e Allows setting only one pin (rx or tx) in the first begin() (#6394) 2022-03-10 15:33:27 +02:00
9b00d4ae6b Fixed the antenna GPIO argument (#6392) 2022-03-10 15:32:13 +02:00
66596fa581 Fix ledc panic’ed when wrong setup of frequency and bit width (#6371)
* Fixed LEDC panic when wrong bit widht / frequency set.

* Fixed ledc example to be working on all SOCs
2022-03-10 15:30:57 +02:00
02a3a71e7c CameraWebServer fix (#6370) 2022-03-10 15:29:56 +02:00
3a7dfa14db Fixes rmtDeinit() and tests RX/TX before operations (#6369)
* Fixes rmtDeinit() and tests RX/TX before operations

* Optimizes final binary size

* Typo
2022-03-10 15:19:15 +02:00
96f8f5e3ef Add initial hardware testing support (#6313)
- Added workflow triggered by cron or label "hil_test"
- Added examples with both pytest and unity
2022-03-10 14:45:26 +02:00
4da1051266 Bugfix of the following problems: Invalid variable argument list used to retrieve length. If length is greater or equal than the available buffer, a memory leak will happen because va_end() is missing. (#6360) 2022-03-02 15:25:59 +02:00
7d4992a811 Adds C++ std::function to Serial.onReceive() (#6364)
* Adds C++ std::function to Serial.onReceive()

* fixes LOCK macro when disabled
2022-03-02 15:20:43 +02:00
95b8e7e42b Fixes DHCP Server Lease Range for any AP Server Static IP Address (#6296)
* Fixes DHCP Server Lease Range for any AP Server Static IP Address

* Fixes DHCP in APMode when Static IP is out of subnet range
2022-03-02 15:19:05 +02:00
e8d6050a7b Implemented new types of SmartConfig (#6367) 2022-03-02 15:18:20 +02:00
683dbf3b1b Added ESP32-WROOM-DA module to boards.txt (#6361)
Added dual antenna configuration based on the module selection
Added warning to the example on how to use the DA
2022-03-02 15:17:18 +02:00
c2e5957f35 Update esp32-hal-log.h (#6358)
#ifdef added, to avoid compiler redefinition warnings for LOG_LOCAL_LEVEL if defined by application, and we USE_ESP_IDF_LOG
2022-02-28 16:50:07 +02:00
eae67a9fb4 WiFi DA: Added Dual Antenna to the docs and example created (#6357)
Summary

Added the Dual Antenna documentation.
Added the DA example.
2022-02-28 16:48:51 +02:00
52575d63f4 Fixed wifiBegin to fail wfile connecting to same AP without previous disconnecting (#6359) 2022-02-28 16:47:06 +02:00
d1f0d6c0fc Added more details about PlatformIO (#5540)
* Added more details about PlatformIO

* Fixed typo
2022-02-28 15:06:28 +02:00
bf58ab65e9 Because QName max. size is 256, the QNameLength range must be able to address it. Therefore the datatype was changed to uint16_t. (#6354) 2022-02-28 14:42:48 +02:00
c280225738 fix final rev pins (#6353)
fix uarts

Co-authored-by: ladyada <support@adafruit.com>
2022-02-28 14:31:00 +02:00
4f7e88a177 Fixes build error if TAG is const (#6351) 2022-02-28 14:30:33 +02:00
b254765ef8 add lolin s2 pico board def (#6325) 2022-02-24 01:03:03 +02:00
8899de760a Add new board (Deneyap Kart 1A) (#6324)
* Add new board (Deneyap Kart 1A)

* Update pins_arduino.h
2022-02-24 01:02:35 +02:00
524279d468 Merge pull request #6343 from Ouss4/dummy-selfhosted
.github/workflows: Remove the slefhost runner test.
2022-02-24 01:00:48 +02:00
f319804521 .github/workflows: Remove the slefhost runner test.
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2022-02-23 23:23:34 +01:00
2884215f85 Documentation for DAC peripheral (#6337) 2022-02-23 16:00:16 +02:00
a57cac63e4 Timer API docs + esp32-hal-timer.h edit (#6335) 2022-02-23 15:59:20 +02:00
de6994187d LEDC & SigmaDelta documentation (#6330)
* LEDC preripheral doc

* SigmaDelta peripheral doc

* Added missing symbol

* Edited grammar, mistakes

* quick edit
2022-02-23 15:58:27 +02:00
491444c15a [Docs] Added more details about embedded FLASH and PSRAM on ESP32-S3. (#6321)
* [Docs] Added more information about embedded PSRAM and Flash for ESP32-S3

* [Docs] Fixed some typos

* [Docs] Fixed some spacing issues
2022-02-23 15:57:31 +02:00
a135169176 Added ADC API doc + simple example (#6301)
* Added ADC API doc + simple example

* Added attenuation input voltage range + conf.py added tabs extension

* Update requirements.txt

* Update adc.rst
2022-02-23 15:45:19 +02:00
b5f3d6c836 Update doc: Arduino as IDF component; fixes #5833 (#6299)
Summary

Updated documentation describing the usage of Arduino-esp32 core as ESP-IDF component.

Impact

Removed confusing mentions of advanced menuconfig options.
Extended process of installation, setup, and usage.

Related links

Closes #5833
2022-02-23 15:24:40 +02:00
d5e8c9dddc Make USBHIDKeyboard::sendReport() public (#6322)
Exposing this method makes it easier to integrate non-espressif USB-based projects (e.g. led/modifiers examples from USB Host Shield 2.0)
2022-02-21 15:16:24 +02:00
65cfab7868 add lolin s2 mini board def (#6320) 2022-02-21 14:18:09 +02:00
4517b9c8fc The M5Core2 and M5Tough have 40 pins (#6315)
Summary

The M5Core2 and the very similar M5Tough have 40 digital pins

See reference here: https://docs.m5stack.com/en/core/core2 as well as the constant declarations in the bottom part of the file.

Impact

Without this, Code that needs the total number of pins (e.g. firmata) doesn't show the higher pin numbers correctly.
2022-02-21 10:24:14 +02:00
dad946a641 Add partition scheme menu for AI Thinker ESP-CAM boards (#6310)
Sometimes you dont need the full 3M but want OTA instead
2022-02-21 10:23:33 +02:00
7c58696223 add lolin c3 mini board def (#6306)
add lolin c3 mini board def
2022-02-21 10:22:43 +02:00
02a70bbd21 fixed http.end taking too long (#6277)
http end takes 20-30 seconds if there is a large amount of data
replacing this read loop with flush fixes that problem
2022-02-21 10:03:25 +02:00
50e9772ecf Fixes UART pin setting + adds CTS/RTS HW Flow Control (#6272)
* fixes setPins and begin to keep rx/tx unmodified

* adds Hardware Flow Control mode and CTS/RTS pin setting

* adds Hardware Flow Control mode and CTS/RTS pin setting

* adds Hardware Flow Control mode and CTS/RTS pin setting

* adds Hardware Flow Control mode and CTS/RTS pin setting

* Code Review
2022-02-17 03:28:46 +02:00
01303b700d ADC esp32s2 attenuation fix for DAC pins (#6282)
* ADC esp32s2 attenuation fix for DAC pins

* Use soc define instead config target
2022-02-16 15:45:06 +02:00
4900979906 Added documentation for the Arduino IDE tools menu (#6284)
* Added the Tools Options into the docs.

* Added more options

* Deleted wrong file.

* [Docs] Added image to show the MSC and some grammar fixes

* [Docs] Added more information about the core selection

* Deleted wrong file.

* [Docs] Added more information about the core selection

* [Docs] Changes according to the PR review
2022-02-16 15:43:21 +02:00
c7cc5c90eb GPIO refactoring (#6259)
* GPIO refactoring

GPIO now using ESP-IDF API on all chips.
LEDC interrupt fix removed - no longer needed.
Edited pins_arduino.h in variants according to changes in gpio.

* Edited analog channels functions
2022-02-16 14:43:38 +02:00
70b7c3afcb Add Ethernet to CMakeLists (#6261) 2022-02-16 14:29:13 +02:00
e83a9b5f60 Adds BLE examples to ESP32-C3 CI cycle (#6285) 2022-02-16 14:25:39 +02:00
7be846cb23 Fixes softAPConfig() return (#6294) 2022-02-16 13:51:21 +02:00
2c7052a64c Installing.rst_update (#6292)
Co-authored-by: Pedro Minatel <pminatel@gmail.com>
2022-02-16 13:34:51 +02:00
c99f594b63 Fix Check for _cookieJar in HTTPClient (#6266) (#6280)
* Check for cookieJar before setting cookies

* Return as soon as possible w/o _cookieJar
2022-02-16 12:08:24 +02:00
05d8cddee7 Fix CDC+JTAG is disabled when WiFi is used on ESP32-C3 (#6287)
Fixes: https://github.com/espressif/arduino-esp32/issues/6264
Thanks @Spritetm
2022-02-16 09:30:59 +02:00
c4954dd582 Fix compile with Arduino lib builder (#6244) 2022-02-07 16:31:38 +02:00
4cbb7389db Support the updated MbedTLS in ESP-IDF v4.4 (#6243) 2022-02-07 13:42:22 +02:00
ab6e010c20 HttpClient: Add cookie support (cookie jar) (#6216)
* Support concatenation of headers (as in 1de0c341b5 (diff-977435a9cc4619fa0b8b995085f6ae683485cf563722756bab57108b362da316) for ESP8266, fixes https://github.com/espressif/arduino-esp32/issues/4069)

* Add support for receiving, storing and sending cookies (cookie jar)

* Cookie support: Respect `secure` attribute when sending a request

* Fix missing `_secure` flag

* Comment out support concatenation of headers (not needed anymore when using cookie jar)
2022-02-05 13:04:57 +02:00
7eec41dcb5 Fixes Touch Sensor for ESP32-S3 and any future SoC (#6234)
* Fixes digitalPinToTouchChannel() for ESP32-S3
2022-02-05 11:54:01 +02:00
9dbc908784 FIX ledc on ESP32C3 (#6229) 2022-02-04 15:55:28 +02:00
9b066ea61c Added dual antenna for WiFi (based on the ESP32-WROOM-DA module) (#6226)
* Added dual antenna for WiFi (based on the ESP32-WROOM-DA module)

* Fixed build error

* Fixed indentation and renamed function to setDualAntennaConfig

* Added the RX and TX selection modes as configuration

* Mode code optimization
2022-02-03 20:56:25 +02:00
bb4d9027dd add feather esp32 v2 and qtpy c3 board def (#6223)
* add feather esp32 v2 and qtpy c3 board def
update some pin names
add variant.cpp's to auto-enable i2c, tft, neopixels on boot

* add auto-enable for i2c!
2022-02-03 20:10:54 +02:00
1046f59f6b Upload to the component registry (#6203)
Co-authored-by: Sergei Silnov <sergei.silnov@espressif.com>
2022-02-03 20:09:18 +02:00
6591f5bd4c Fix replace() failing (#6224) 2022-02-03 20:07:34 +02:00
0ea485e518 Touch Sensor IDF Refactoring (#6194)
Summary

Touch Sensor refactoring to be based on IDF 4.4.
Adds support to ESP32S2 and future ESP32S3.

Adds some new APIs:

For all chips:

void touchAttachInterruptArg(uint8_t pin, void (*userFunc)(void*), void *arg, uint32_t threshold);
This function allows the user to add and pass a void* parameter to the ISR user callback.

void touchDetachInterrupt(uint8_t pin);
This function detaches ISR call back for the touch pad pin.

Only ESP32 chip

void touchInterruptSetThresholdDirection(bool mustbeLower);
This function allows the user to set if the ISR callback will be activated when the touch sensor readings are lower or higher than the threshold defined. See example TouchButton.ino.

Only ESP32-S2 and ESP32-S3 chips

bool touchInterruptGetLastStatus(uint8_t pin);
This function reports if the touch pad pin is touched or untouched. It can be used with ISR to identify when it is touched and untouched (released). See example TouchButtonV2.ino.

Impact

None. ll original APIs and examples now run on ESP32 and ESP32-S2.

Related links

Fix #6095
Fix #6034
Fix #5799
Fix #5745
Fix #5527
Fix #5493
Fix #4321
Fix #4044
Fix #2722
Fix #2625
2022-02-03 19:06:12 +02:00
3a96fc0e4a framebuffer location for no-psram boards (#6219)
If board has no PSRAM, we need to set the framebuffer location to DRAM:
config.fb_location = CAMERA_FB_IN_DRAM;
2022-02-01 13:59:32 +02:00
5be3ff74ea Unnecessary operation removed from map() in WMath.cpp (#6218)
* Unneccesary Operation Removed

(A) extra operation not needed and incorrect:
      wrong by 0.5 but happens to be thrown out

     ( delta * dividend + (divisor / 2) ) / divisor

        delta * dividend     divisor
    = ---------------- + -----------
        divisor                    2 * divisor

    = delta * dividend / divisor + 1/2

(B) check first before doing other computations

(C) changed to rise/run, easier for future maintainer
      since it's closer to equation of a line

(D) before: mult, shift, add, div, add
      now: mult, div, add

(E) error message easier to trace where thrown

* Update WMath.cpp

forgot to change variable name
2022-02-01 13:26:52 +02:00
dafdc05249 Docs cleanup and version updated to 2.0.2 (#6213)
* Docs cleanup and version updated to 2.0.2

* Removed issue template information

* Removed issue template file

* Added referecnces for the issue and feature request form
2022-02-01 11:24:06 +02:00
ef35baffb0 Fix random CaptivePortal.ino crashes (#6206)
CaptivePortal.ino example did randomly crash for me ... so I start investigate ;-)

Decoding stack results
0x4016faea: WiFiUDP::write(unsigned char const*, unsigned int) at C:\Users\knoeb\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.5\libraries\WiFi\src\WiFiUdp.cpp line 201
0x400d4a4a: DNSServer::replyWithIP() at C:\Users\knoeb\AppData\Local\Temp\arduino_build_486825\sketch\src\DNSServer\DNSServer.cpp line 187
0x400d4d01: DNSServer::processNextRequest() at C:\Users\knoeb\AppData\Local\Temp\arduino_build_486825\sketch\src\DNSServer\DNSServer.cpp line 117
0x400d3e81: loop() at D:\Drive\Dokumente\HTL_Lehrer\2021_22\Projekte\Stromzaehler_Patrick\arduino/arduino.ino line 1078
0x400dd545: loopTask(void*) at C:\Users\knoeb\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.5\cores\esp32\main.cpp line 37
0x4008a0de: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

I found with wireshark a possibility to trigger the crash on demand is:
nslookup 3.1o1osr0092ons87rp375p1pq8q066o8p56or1sqsps6rs17r4384q9748qr1r52.699p1r741q737393648s29917o45p16q50rn517rnsp73pp68p1q259s92693qp.s607408539s0p06p7559os0899866344r7qq7rpns960o9576q65.r5n94r5so9784pq1.i.03.s.sophosxl.net

The problem was that QNameLength is a signed byte and therefore its not possible to count up to 255. Additionally we need 256 bytes for the QName string to accommodate for the zero termination.
2022-01-31 13:25:43 +02:00
7a6dae02aa Refactor the CI scripts (#6191)
The reason behind this refactoring is that all of the sketch related functions can (and will) be used for other purposes.

Build in the sketch directory: This will make it easy to handle artifacts after the build.
Separate sketch related functions from IDE installation script. This is the main commit.
Create a separate job for the Cmake check. This check was part of one of the Linux build. I believe that it's not the best place for such a check.
Checking for the skip landmarks and validity of the the sketch directory were already done by count_sketches.
2022-01-31 13:15:10 +02:00
9f08cf4767 Update RequestHandlersImpl.h (#6179)
With LittleFS the `fs.exists(path)` returns true also on folders. A `isDirectory()` call is required to set _isFile to false on directories.
This enables serving all files from a folder like : `server->serveStatic("/", LittleFS, "/", cacheHeader.c_str());
        File f = fs.open(path);
        _isFile = (f && (! f.isDirectory()));
2022-01-31 13:09:04 +02:00
96a5ddcd0e Allow HTTPCLIENT_1_1_COMPATIBLE to be disabled (#6200)
Allow a user to disable the HTTPCLIENT_1_1_COMPATIBLE flag from the command line, or whichever means available.
2022-01-31 13:08:09 +02:00
9fe34f6553 Resolve WString TODO (#6190)
Resolve TODO (XXX) by logging warning message.
2022-01-31 13:07:37 +02:00
cbeb7c4df8 Add conditional include to WiFiProv.h (#6192)
Resolves issue #6171
2022-01-31 13:06:39 +02:00
754ceddf48 added explanatory comments to WebServer.h (#6204) 2022-01-31 13:04:29 +02:00
39a2080922 Fixes onReceive deadlock (#6201) 2022-01-31 13:03:43 +02:00
9555ed4b76 Use 8.4.0+2021r2-patch2 toolchains for CI (#6184)
with platformio
2022-01-31 13:02:34 +02:00
0d665d7e55 fix: restoring handshake timeout (#6165) (#6166) 2022-01-31 13:01:32 +02:00
bb7df04446 Fix - SD mount issue (#6162)
* sdSelectCard longer timeout for sdWait

* GO_IDLE_STATE command ignores sdWait fail
2022-01-31 13:01:01 +02:00
ce68d72157 Fixes UART1 and UART2 default pins for ESP32-S3 (#6202)
Summary

This PR fixes an issue with UART1 default pins.
When using pins RX_1 = 18 and TX_1 = 17, UART1 will display a Break Error on those pins when they are floting (not connected).

It also defines RX_2 = 19 and TX_2 = 20 as default pins for UART2.

Impact

The deaulf pins may look different from the original pinout diagram.
2022-01-31 12:46:09 +02:00
6a7bcabd6b Update Windows Toolchain 2022-01-21 01:15:38 +02:00
a61609376a .github/scripts: Fix indentation and trailing spaces. (#6157)
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2022-01-20 13:15:12 +02:00
4a1cbeb69b Add Watchy board (#6158) 2022-01-20 13:14:25 +02:00
a5932064f9 Fixing interrupts in LEDC (#6160)
Fixes: #6140
2022-01-20 13:09:25 +02:00
a45790b20e Fix variant definition for w32-eth01 (#6159) 2022-01-20 13:08:41 +02:00
0b4516eef5 Rename pins_Arduino.h to pins_arduino.h (#6153)
fixes: #6152
2022-01-19 16:26:40 +02:00
cbfcfbf970 Add certificate bundle capability to WiFiClientSecure (#6106)
* Add certificate bundle capability to WiFiClientSecure

Enable usage of the ESP32 IDF's certificate bundle for WiFiClientSecure connections.

Adds the ability to load a bundle or root certificates and use them for authenticating SSL servers.

Based on work from Onno-Dirkzwager, Duckle29, kubo6472, meltdown03, kinafu and others.

See also:
- https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_crt_bundle.html
- https://github.com/espressif/arduino-esp32/issues/3646
- libraries/WiFiClientSecure/README.md

* Fix build issues

* Clean up old bundle index when NULL bundle is attached
2022-01-19 15:42:36 +02:00
c9b0dc99d3 Add LionBit Dev Board. (#6151)
* Add LionBit Dev Board.

* Create lionbit in variants.
2022-01-18 17:41:39 +02:00
a134088a0b Implement Ticker::active() (#6148) 2022-01-18 17:40:03 +02:00
78b2df74f5 IDF release/v4.4 f3e0c8bc41 (#6075)
esp-dsp: master 6b25cbb
esp-face: master 925c72e
esp-rainmaker: f1b82c7
esp32-camera: master 221d24d
esp_littlefs: master 5a13cd6

fixes: #5948
2022-01-18 17:28:10 +02:00
77756d8a06 ci: Miscellaneous improvements (#6132)
Cache downloaded tools.
Cancel duplicate jobs.
Use current repo when linking the core, this allows users to test their code when creating PRs against their forks (for instance an error in an example sketch will build successfully in a fork workflow.)
Cache Arduino IDE.
Add workflow_dispatch to be able to trigger the workflow manually.
2022-01-17 23:29:28 +02:00
c6e30e0027 Add Core Debug Level option to Tools menu for all boards in boards.txt (#6110) 2022-01-17 16:40:27 +02:00
41d972564c Proposed fix for #2501 (#6113)
Reliability fix for autoReconnect when assoc_fail, autoReconnect did not work before for these failures.

Changes behavior of WIFI_REASON_ASSOC_FAIL event when autoReconnect is set, removes WIFI_REASON_ASSOC_FAIL/WL_CONNECT_FAILED so retry waitforconnectresult loop stays active for the retry, was not working before.
2022-01-17 16:39:16 +02:00
a0beb81a4c Consistently change device index to singed integer in BluetoothSerial lib (#6109)
* change parameter to signed int

As of wrong paramater, the following problem existed, that will be fixed now with this change.

BTScanResultsSet.cpp:67:8: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
if (i < 0)

* Change parameter and variable to int

As of wrong paramater, the following problem existed, that will be fixed now with this change.

BTScanResultsSet.cpp:67:8: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
if (i < 0)
2022-01-17 16:31:58 +02:00
460af2e1a5 Fix I2C Slave Compile (#6108)
I2C Slave currently doesn't compile for projects where Arduino is an IDF component.  This adds missing conditionals.

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2022-01-17 16:29:50 +02:00
48a722aae8 Versions and feature Request Template updates (#6096)
* Update of versions and Feature request template

* Update of versions and Feature request template

* Formatting
2022-01-17 16:17:18 +02:00
702db50627 BUGFIX - Sd check status (#6103)
* Edit sd_diskio to check card status

* Bugfix of ff_sd_status
2022-01-17 16:15:16 +02:00
1ac3aefa61 Add KSZ8041 support (#6087) 2022-01-17 16:14:09 +02:00
e84e9c153e Print.flush() - Arduino API conformance (#6084) 2022-01-17 16:12:22 +02:00
1d3ff0520a Add variantInit setups for adafruit boards (#6076) 2022-01-17 16:10:53 +02:00
b3b3403296 NTP Examples: revert obsolete comment and updated Time example (#6073)
* Revert "Examples update, add a note for configTime() that only one ntp server is supported by lwip",
fixed in espressif/esp32-arduino-lib-builder#51

This reverts commit 6b1020967a171c549b3d956825fd0d395de9cce0.

* SimpleTime: add NTPoDHCP option and TimeZone env variable
2022-01-17 16:09:58 +02:00
c014eaf352 Adds UART RX IRQ Callback with onReceive() (#6134)
* Adds UART RX IRQ Callback with onReceive()
2022-01-17 16:04:12 +02:00
5ae3886c66 Fixes UART MODBUS and Loopback issue (#6133) 2022-01-17 14:54:13 +02:00
1bbe61ab6f Allows user to bypass PSRAM test and boot faster with WROVER (#6135)
Fixes #5737
2022-01-17 14:47:08 +02:00
841599c248 Fixes String(float) issue with Stack Smashing (#6138)
Fixes #5873
2022-01-17 14:44:49 +02:00
caef4006af Implement SigmaDelta based on ESP-IDF API (#6053)
Summary

This PR is refactoring of SigmaDelta HAL in order to use IDF instead of current Register manipulation approach.

Impact

Change in API:

uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq);
changed to -->
uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq);

void sigmaDeltaAttachPin(uint8_t pin); removed, no longer needed. Pin is attached in sigmaDeltaSetup()
2021-12-22 16:41:52 +02:00
44fbde0189 Fixes Lib Builder compiling errors (#6052) 2021-12-22 14:37:40 +02:00
8c88ecbf77 add GPIO defines for C3 (#6005) 2021-12-22 14:36:54 +02:00
5724275cd8 fix tft feather pins for final version, qtpy spi pins, and add reversetft start (#6050)
SPI fix for QT Py, TFT fix for TFT Feather
2021-12-22 14:09:53 +02:00
1c94c38dbb IDF release/v4.4 a79dc75f0a (#6048) 2021-12-21 15:14:41 +02:00
7cf162346a RMT refactoring based on IDF (#6024)
Summary

RMT HAL refactoring based on IDF.

Impact

Improves RMT by adding IDF v4.4 support.
Receiving RMT can handle any size of data.
rmtInit() has a new parameter - RxBufferSize - to hold any number of data when receiving RMT.
rmtWrite() has a new parameter - wait_tx_done - to block writing until sending all data.

Related links

fix #5905
2021-12-21 15:02:40 +02:00
c66c7fe27e [Examples] README revision to include missing and remove old entries (#6049) 2021-12-21 15:00:37 +02:00
7ba11cc1ae [Docs] Added USB documentation (#6036)
Summary

Added USB documentation.

Closes: #5784
2021-12-21 12:51:38 +02:00
c3d41c9b54 Fixes baudrate with CPU Freq < 80MHz (#6037)
This PR fixes an issue with UART when CPUFreq is lower than 80MHz (APB Freq)
2021-12-21 10:10:31 +02:00
d6934a5289 Implement LEDC based on ESP-IDF API (#6045)
This PR is refactoring of LEDC HAL in order to use IDF instead of current Register manipulation approach.
Fixing duty -> if all bits in resolution are set -> FULL ON
2021-12-20 14:58:49 +02:00
6b90627b21 HID_BRAILLE_DISPLAY (#6043)
23 Braille Display Page (0x41)
Braille display allow visually impaired computer users to read out text using raised pins. The pins are electro-mechanically
activated. These devices also have support for controls that help navigate the computer screen. Typically, braille displays
interface with software known as a screen reader in order to perform this navigation.
2021-12-20 13:22:58 +02:00
063119ac87 fix variant wt32-eth01 (initializer not constant) (#6040)
fix not constant definitions in variant wt32-eth01 (error: initializer element is not constant)
2021-12-20 13:21:53 +02:00
7b96374ea6 [Fix] Added the Win32 not supported notice/warning (#6031)
Related to:
#6012
#5994
#5991
2021-12-20 13:11:22 +02:00
82ec74a072 Adds support to change LoopTask Stack size (#6025)
## Summary
Arduino ```setup()``` and ```loop()``` run under a Task with a fixed Stack size of 8KB.
Users may want to change this size.

This PR adds this possibility by just adding a line of code, as for example:
``` dart
ESP_LOOP_TASK_STACK_SIZE(16384);

void setup() { 
}

void loop() { 
}
```
## Impact
None. It adds a new functionality to ESP32 Arduino.
If ```ESP_LOOP_TASK_STACK_SIZE(newSize);``` is not declared/used, it will compile the sketch with the default stack size of 8KB.

## Related links
fix #6010 

https://github.com/espressif/arduino-esp32/issues/6010#issuecomment-992701658
Thanks @igrr for the suggestion!
2021-12-20 13:10:36 +02:00
5940d89e67 Fix wrongly applied patch to WiFi STA Init 2021-12-20 10:17:25 +02:00
bb09615391 Fix Arduino Core config for ESP32-S2
Fixes: https://github.com/espressif/arduino-esp32/issues/6019
2021-12-20 10:11:53 +02:00
c2c8d18992 Forces UART Flush() to wait until all bits are sent (#6026)
HardwareSerial flush() was returning before all data was sent out through serial port.
This is a problem to some RS485 libraries that depend on it to signaling.

This PR solves the issue by forcing it to block flush() until all data is sent.
2021-12-15 11:08:49 +02:00
39b9e1e533 Implement DAC based on ESP-IDF API (#5959)
This PR is refactoring of DAC HAL in order to use IDF instead of current Register manipulation approach.

Edited dacWrite() to use ESP-IDF api.
Added dacDisable() so there is an option to disable dac channel.

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2021-12-14 21:10:30 +02:00
40a5c1e461 Change default WiFi encryption to WIFI_AUTH_WPA2_PSK (#6022)
Fixes: https://github.com/espressif/arduino-esp32/issues/6020
2021-12-14 20:07:08 +02:00
2981bde88f Add some more adafruit boards and fix some board typos (#6014)
Co-authored-by: caternuson <caternuson@gmail.com>
Co-authored-by: Kattni Rembor <kattni@adafruit.com>
Co-authored-by: Jeff Epler <jeff@adafruit.com>
Co-authored-by: Jeff Epler <jepler@gmail.com>
Co-authored-by: Ha Thach <thach@tinyusb.org>
2021-12-14 18:17:04 +02:00
6d400df952 IDF release/v4.4 f23dcd3555 (#5996)
esp-dsp: master 6b25cbb
esp-face: master d141502
esp-rainmaker: f1b82c7
esp32-camera: master 61400bc
esp_littlefs: master 3c29afc
2021-12-14 16:38:06 +02:00
7bb30b3cf8 Refactoring TwoWire::requestFrom() headers in Wire.cpp (#5935)
* Refactoring function headers

Changing the header so the main TwoWire::requestFrom() definition uses a `size_t` instead of a `uint8_t`, removing the 255 bytes limit on I2C requests.

Co-authored-by: Flaviu Tamas <me@flaviutamas.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2021-12-14 16:25:01 +02:00
4b638de19d using ksz8081 only from ESP-IDF 4.4 onwards (#5918)
* using ksz8081 only from ESP-IDF 4.4 onwards

The previous assertion only considerate the existance of ESP-IDF 4.3, but with the ESP-IDF 4.3.1 release this assertion would generate errors. Now only includes from ESP-IDF 4.4 onwards.

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2021-12-14 16:09:01 +02:00
2463f57246 Adding Issue and Feature template (#5999)
Summary

This PR contains adding:

Issue template using forms
Feature Template using forms
Update of Pull Request template
All yaml files have been checked by online validator.

Pages are rendered here (for easier review):
Feature Request template
Issue Template

Impact

These templates can help with more accurate issue/PR explanations which can improve handling these contribution and in overall have a positive influence on User experience.

Related links

This PR closed issue #5956
2021-12-14 16:05:36 +02:00
f29f4485b5 Fix memory leaks when SSL/TLS connection fails (#5945) 2021-12-14 15:59:26 +02:00
8a8f87d3a0 Fix for BluetoothSerial build when using nimBLE instead of Bluedroid (#5920) 2021-12-14 15:56:25 +02:00
082491d552 Add DPU ESP32 (#5884)
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2021-12-14 15:53:09 +02:00
794de50bf4 Migrate MD5Builder to use esp_rom functions directly rather than rely on wrappers that can be omitted from compilation based on sdkconfig. (#5941) 2021-12-14 15:49:43 +02:00
5e7db8dfac Timer based od ESP-IDF (#5931) 2021-12-14 15:46:39 +02:00
fb00b51f99 [DOCS] Writing a new Arduino documentation about GPIO (#5894)
* add new documation GPIO

Co-authored-by: pedro.minatel <pedro.minatel@espressif.com>
2021-12-14 15:39:54 +02:00
5dc8fb83c9 add board and variant for WT32-ETH01 (variant wt32-eth01) from Wireless-Tag (#5946)
- supports the WiFi/Ethernet board with WT32-S1 module and LAN8720A Ethernet PHY
- documentation available at http://www.wireless-tag.com/portfolio/wt32-eth01/
2021-12-14 15:37:59 +02:00
cb25fe8c7e Don't clear headers on redirect (#5973)
Current implementation clears _headers when request was sent. If the
user added custom request headers, they will be lost and the redirected
request will not contain them. This commit changes the scope of cleanup
so that the headers survive redirects but don't survive connection
reuse.
2021-12-14 15:37:31 +02:00
f5b04b9197 Use WIFI_FAST_SCAN if a specific channel was used (#5975)
1.0.6 changed scanning method to always scan all available channels during connect. This results in results in connect taking about ~3 seconds instead of ~1. This patch changes the behavior to use WIFI_FAST_SCAN if client used a specific channel.
2021-12-14 15:37:00 +02:00
8c5d18dd85 Merged all TTGO-LoRa32 Board profiles (see #5933) (#5961)
* Merged all TTGO-LoRa32 Board profiles (see #5933)

* Fix for LORA_RST (see #5966)
2021-12-14 14:55:55 +02:00
fa03966fcf [Feature] Added Sonoff DUALR3 support with RainMaker example (#5980)
* [Feature] Added Sonoff DUALR3 support with RainMaker example

* [Feature] Added skip files for C3 and S2
2021-12-14 14:35:10 +02:00
3750b14d74 Prevent self hosted jobs to run on forks. (#5983)
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2021-12-14 14:26:59 +02:00
cebac569de Update Boards.txt (#5984)
fix boad error : "--elf-gcc.path}/bin/--elf-g++": file does not exist
and fix follow esp32 dev module
2021-12-14 14:26:10 +02:00
d0e73bd269 .github/workflows: Update checkout and setup-python actions to their V2 (#5985)
(latest) version.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2021-12-14 14:25:11 +02:00
26dddc5f94 Fix the execute bit of some files. (#5986)
- Remove the execute bit from source and text files.
- on-pages.sh script needs the execute bit to be set.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2021-12-14 14:24:44 +02:00
c87ede88df Delete .travis.yml file. (#5987)
All the workflows are now migrated to Github Actions.
Update the on-push.sh script to remove references to TravisCI variables.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2021-12-14 14:24:01 +02:00
c90dffef44 Edit sd_diskio to check card status (#5988) 2021-12-14 14:22:30 +02:00
1945fae795 update boards.txt for adafruit feather esp32s2 (#6006)
also update tinyuf2 bootloader for adafruit boards to 0.6.2
2021-12-14 13:58:18 +02:00
6e0b57784f [Docs] Update on the Windows install procedures (#6018) 2021-12-14 13:56:26 +02:00
399f4ecbb3 [DOCS] Editing usage of Arduino as a component in ESP-IDF (#5896)
* Editing esp-idf_component docs

* Changed idt to ESP-IDF

Co-authored-by: Pedro Minatel <pminatel@gmail.com>
2021-11-22 13:37:06 +00:00
a5002c86a0 IDF release/v4.4 ddc44956bf (#5911)
esp-dsp: master 6b25cbb
esp-face: master 859f32a
esp-rainmaker: f1b82c7
esp32-camera: master 61400bc
esp_littlefs: master 3c29afc
2021-11-22 15:02:37 +02:00
c9916c463f Fix I2C clock stretching issue with ESP32 (#5910)
It was found that when I2C device is holding the clock LOW, ESP32 master is failing to wait for the clock to be released.

Fixes: #5875
Fixes: sparkfun/SparkFun_u-blox_GNSS_Arduino_Library#77
2021-11-19 18:43:59 +02:00
bd2be80b54 cbuf: allow inheritance (#5883)
changes "private" vars to "protected" so that descendants are allowed to access them.
2021-11-18 14:25:04 +02:00
6f1f394680 Update boards.txt (#5903) 2021-11-18 13:58:03 +02:00
5de09a9a49 [Docs] Add link to supported soc list on README and ESP32-S3 datasheet (#5891)
* [Docs] Added the supported SoC table link on the README file

* [Docs] Added the ESP32-S3 datasheet link to the getting started page
2021-11-15 15:19:28 +00:00
b94b38c9d1 Fix compiler.libraries.ldflags Option (#5866)
I misplaced the additions.
2021-11-09 17:01:21 +02:00
4313 changed files with 714350 additions and 30638 deletions

View File

@ -0,0 +1,62 @@
name: Feature request
description: Suggest an idea for this project
labels: ["Type: Feature request"]
body:
- type: markdown
attributes:
value: |
* We welcome any ideas or feature requests! It is helpful if you can explain exactly why the feature would be useful.
* There are usually some outstanding feature requests in the [existing issues list](https://github.com/espressif/arduino-esp32/issues?q=is%3Aopen+is%3Aissue+label%3A%22Type%3A+Feature+request%22), feel free to add comments to them.
* If you would like to contribute, please read the [contributions guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html).
- type: input
id: Area
attributes:
label: Related area
description: Please briefly explain the area of your Feature Request.
placeholder: eg. Board support, specific Peripheral, BT, Wifi...
validations:
required: true
- type: input
id: HW
attributes:
label: Hardware specification
description: Please provide if your proposal depends on specific Hardware.
placeholder: eg. Support for ESP32 DevKitC, ESP32-C3 DevKitM...
validations:
required: true
- type: textarea
id: problem-related
attributes:
label: Is your feature request related to a problem?
description: Please provide a clear and concise description of what the problem is. Add relevant issue link.
placeholder: ex. I'm facing the issue/missing function...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: Please provide a clear and concise description of what you want to happen.
placeholder: ex. When using this function...
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: Please provide a clear and concise description of any alternative solutions or features you've considered.
placeholder: ex. Choosing other approach wouldn't work, because...
- type: textarea
id: context
attributes:
label: Additional context
description: Please add any other context or screenshots about the feature request here.
placeholder: ex. This would work only when ...
- type: checkboxes
id: confirmation
attributes:
label: I have checked existing list of Feature requests and the Contribution Guide
description: You agree to check all the resources above before opening a new Feature request.
options:
- label: I confirm I have checked existing list of Feature requests and Contribution Guide.
required: true

132
.github/ISSUE_TEMPLATE/Issue-report.yml vendored Normal file
View File

@ -0,0 +1,132 @@
name: Issue report
description: Report any problem here
labels: ["Status: Awaiting triage"]
body:
- type: markdown
attributes:
value: |
* Before reporting a new issue please check and search in [List of existing issues](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue)
* Please check [Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/index.html)
* Take a look on [Troubleshooting guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html)
* If still experiencing the issue, please provide as many details as possible below about your hardware, computer setup and code.
- type: input
id: Board
attributes:
label: Board
description: On which Board does this issue occur?
placeholder: eg. ESP32 Dev Module, ESP32-S2, LilyGo TTGO LoRa32...
validations:
required: true
- type: textarea
id: devboard
attributes:
label: Device Description
description: What development board or other hardware is the chip attached to?
placeholder: ex. DevKitC, plain module on breadboard, etc. If your hardware is custom or unusual, please attach a photo.
validations:
required: true
- type: textarea
id: other-hw
attributes:
label: Hardware Configuration
description: Is anything else attached to the development board?
placeholder: ex. GPIO 18 & 19 are connected to I2C devices.
validations:
required: true
- type: dropdown
id: version
attributes:
label: Version
description: What version of Arduino ESP32 are you running? If possible, consider updating to the latest version.
options:
- latest master (checkout manually)
- latest development Release Candidate (RC-X)
- v2.0.2
- v2.0.1
- v2.0.0
- v1.0.6
- other
validations:
required: true
- type: input
id: IDE
attributes:
label: IDE Name
description: What IDE are you using?
placeholder: eg. Arduino IDE, PlatformIO, Sloeber...
validations:
required: true
- type: input
id: os
attributes:
label: Operating System
description: On which OS does this issue occur?
placeholder: ex. macOS 12.1, Windows 10...
validations:
required: true
- type: input
id: Flash
attributes:
label: Flash frequency
description: What flash frequency is used?
placeholder: eg. 40Mhz
validations:
required: true
- type: dropdown
id: PSRAM
attributes:
label: PSRAM enabled
description: Is PSRAM enabled?
options:
- 'yes'
- 'no'
validations:
required: true
- type: input
id: Upload
attributes:
label: Upload speed
description: What upload speed is used?
placeholder: eg. 115200
validations:
required: true
- type: textarea
id: Description
attributes:
label: Description
description: Please describe your problem here and expected behaviour
placeholder: ex. Can't connect/weird behaviour/wrong function/missing parameter..
validations:
required: true
- type: textarea
id: sketch
attributes:
label: Sketch
description: Please provide full minimal sketch/code which can be run to reproduce your issue
placeholder: ex. Related part of the code to replicate the issue
render: cpp
validations:
required: true
- type: textarea
id: Debug
attributes:
label: Debug Message
description: Please provide a debug message or error message. If you have a Guru Meditation Error or Backtrace, please decode it with [ExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder)
placeholder: Enable Core debug level - Debug on tools menu of Arduino IDE, then put the serial output here.
render: plain
validations:
required: true
- type: textarea
id: other-remarks
attributes:
label: Other Steps to Reproduce
description: Is there any other information you can think of which will help us reproduce this problem? Any additional info can be added as well.
placeholder: ex. I also tried on other OS, HW...it works correctly on that setup.
- type: checkboxes
id: confirmation
attributes:
label: I have checked existing issues, online documentation and the Troubleshooting Guide
description: You agree to check all the resources above before opening a new issue.
options:
- label: I confirm I have checked existing issues, online documentation and Troubleshooting guide.
required: true

View File

@ -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
View 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

View File

@ -1,16 +1,23 @@
---------------------------------------------------------------------------------------------------------------------------------------------------- *By completing this PR sufficiently, you help us to review this Pull Request quicker and also help improve the quality of Release Notes*
This entire section can be deleted if all items are checked.
*By completing this PR sufficiently, you help us to improve the quality of Release Notes*
### Checklist ### Checklist
1. [ ] Please provide specific title of the PR describing the change, including the component name (*eg. „Update of Documentation link on Readme.md“*)
2. [ ] Please provide related links (*eg. Issue which will be closed by this Pull Request*)
3. [ ] Please **update relevant Documentation** if applicable
4. [ ] Please check [Contributing guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html)
1. [ ] Please provide specific title of the PR describing the change, including the component name (eg."Update of Documentation link on Readme.md") *This entire section above can be deleted if all items are checked.*
2. [ ] Please provide related links (eg. Issue, other Project, submodule PR..)
----------------------------------------------------------------------------------------------------------------------------------------------------
## Summary -----------
Please describe your proposed PR and what it contains. ## Description of Change
Please describe your proposed Pull Request and it's impact.
## Impact ## Tests scenarios
Please describe impact of your PR and it's function. Please describe on what Hardware and Software combinations you have tested this Pull Request and how.
(*eg. I have tested my Pull Request on Arduino-esp32 core v2.0.2 with ESP32 and ESP32-S2 Board with this scenario*)
## Related links
Please provide links to related issue, PRs etc.
(*eg. Closes #number of issue*)

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
# This script is for Travis. It checks all non-examples source files in libraries/ and cores/ are listed in # This script is used in the CI workflow. It checks all non-examples source files in libraries/ and cores/ are listed in
# CMakeLists.txt for the cmake-based IDF component # CMakeLists.txt for the cmake-based IDF component
# #
# If you see an error running this script, edit CMakeLists.txt and add any new source files into your PR # If you see an error running this script, edit CMakeLists.txt and add any new source files into your PR

View File

@ -2,35 +2,35 @@
export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32" export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32"
if [ ! -d "$ARDUINO_ESP32_PATH" ]; then if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
echo "Installing ESP32 Arduino Core ..." echo "Installing ESP32 Arduino Core ..."
script_init_path="$PWD" script_init_path="$PWD"
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif" mkdir -p "$ARDUINO_USR_PATH/hardware/espressif"
cd "$ARDUINO_USR_PATH/hardware/espressif" cd "$ARDUINO_USR_PATH/hardware/espressif"
echo "Installing Python Serial ..." echo "Installing Python Serial ..."
pip install pyserial > /dev/null pip install pyserial > /dev/null
if [ "$OS_IS_WINDOWS" == "1" ]; then if [ "$OS_IS_WINDOWS" == "1" ]; then
echo "Installing Python Requests ..." echo "Installing Python Requests ..."
pip install requests > /dev/null pip install requests > /dev/null
fi fi
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then if [ ! -z "$GITHUB_REPOSITORY" ]; then
echo "Linking Core..." echo "Linking Core..."
ln -s $GITHUB_WORKSPACE esp32 ln -s $GITHUB_WORKSPACE esp32
else else
echo "Cloning Core Repository..." echo "Cloning Core Repository..."
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1 git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
fi fi
#echo "Updating Submodules ..." #echo "Updating Submodules ..."
cd esp32 cd esp32
#git submodule update --init --recursive > /dev/null 2>&1 #git submodule update --init --recursive > /dev/null 2>&1
echo "Installing Platform Tools ..." echo "Installing Platform Tools ..."
cd tools && python get.py cd tools && python get.py
cd $script_init_path cd $script_init_path
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'" echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"
echo "" echo ""
fi fi

View File

@ -6,46 +6,43 @@
OSBITS=`arch` OSBITS=`arch`
if [[ "$OSTYPE" == "linux"* ]]; then if [[ "$OSTYPE" == "linux"* ]]; then
export OS_IS_LINUX="1" export OS_IS_LINUX="1"
ARCHIVE_FORMAT="tar.xz" ARCHIVE_FORMAT="tar.xz"
if [[ "$OSBITS" == "i686" ]]; then if [[ "$OSBITS" == "i686" ]]; then
OS_NAME="linux32" OS_NAME="linux32"
elif [[ "$OSBITS" == "x86_64" ]]; then elif [[ "$OSBITS" == "x86_64" ]]; then
OS_NAME="linux64" OS_NAME="linux64"
elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then
OS_NAME="linuxarm" OS_NAME="linuxarm"
else else
OS_NAME="$OSTYPE-$OSBITS" OS_NAME="$OSTYPE-$OSBITS"
echo "Unknown OS '$OS_NAME'" echo "Unknown OS '$OS_NAME'"
exit 1 exit 1
fi fi
elif [[ "$OSTYPE" == "darwin"* ]]; then elif [[ "$OSTYPE" == "darwin"* ]]; then
export OS_IS_MACOS="1" export OS_IS_MACOS="1"
ARCHIVE_FORMAT="zip" ARCHIVE_FORMAT="zip"
OS_NAME="macosx" OS_NAME="macosx"
elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
export OS_IS_WINDOWS="1" export OS_IS_WINDOWS="1"
ARCHIVE_FORMAT="zip" ARCHIVE_FORMAT="zip"
OS_NAME="windows" OS_NAME="windows"
else else
OS_NAME="$OSTYPE-$OSBITS" OS_NAME="$OSTYPE-$OSBITS"
echo "Unknown OS '$OS_NAME'" echo "Unknown OS '$OS_NAME'"
exit 1 exit 1
fi fi
export OS_NAME export OS_NAME
ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
if [ "$OS_IS_MACOS" == "1" ]; then if [ "$OS_IS_MACOS" == "1" ]; then
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java" export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java"
export ARDUINO_USR_PATH="$HOME/Documents/Arduino" export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
elif [ "$OS_IS_WINDOWS" == "1" ]; then elif [ "$OS_IS_WINDOWS" == "1" ]; then
export ARDUINO_IDE_PATH="$HOME/arduino_ide" export ARDUINO_IDE_PATH="$HOME/arduino_ide"
export ARDUINO_USR_PATH="$HOME/Documents/Arduino" export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
else else
export ARDUINO_IDE_PATH="$HOME/arduino_ide" export ARDUINO_IDE_PATH="$HOME/arduino_ide"
export ARDUINO_USR_PATH="$HOME/Arduino" export ARDUINO_USR_PATH="$HOME/Arduino"
fi fi
# Updated as of Nov 3rd 2020 # Updated as of Nov 3rd 2020
@ -55,184 +52,29 @@ ARDUINO_IDE_URL="https://github.com/espressif/arduino-esp32/releases/download/1.
#ARDUINO_IDE_URL="https://www.arduino.cc/download.php?f=/arduino-nightly-" #ARDUINO_IDE_URL="https://www.arduino.cc/download.php?f=/arduino-nightly-"
if [ ! -d "$ARDUINO_IDE_PATH" ]; then if [ ! -d "$ARDUINO_IDE_PATH" ]; then
echo "Installing Arduino IDE on $OS_NAME ..." echo "Installing Arduino IDE on $OS_NAME ..."
echo "Downloading '$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..." echo "Downloading '$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
if [ "$OS_IS_LINUX" == "1" ]; then if [ "$OS_IS_LINUX" == "1" ]; then
wget -O "arduino.$ARCHIVE_FORMAT" "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1 wget -O "arduino.$ARCHIVE_FORMAT" "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..." echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
mv arduino-nightly "$ARDUINO_IDE_PATH" mv arduino-nightly "$ARDUINO_IDE_PATH"
else else
curl -o "arduino.$ARCHIVE_FORMAT" -L "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1 curl -o "arduino.$ARCHIVE_FORMAT" -L "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..." echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
if [ "$OS_IS_MACOS" == "1" ]; then if [ "$OS_IS_MACOS" == "1" ]; then
mv "Arduino.app" "/Applications/Arduino.app" mv "Arduino.app" "/Applications/Arduino.app"
else else
mv arduino-nightly "$ARDUINO_IDE_PATH" mv arduino-nightly "$ARDUINO_IDE_PATH"
fi fi
fi fi
rm -rf "arduino.$ARCHIVE_FORMAT" rm -rf "arduino.$ARCHIVE_FORMAT"
mkdir -p "$ARDUINO_USR_PATH/libraries" mkdir -p "$ARDUINO_USR_PATH/libraries"
mkdir -p "$ARDUINO_USR_PATH/hardware" mkdir -p "$ARDUINO_USR_PATH/hardware"
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'" echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
echo "" echo ""
fi fi
function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_sketch <fqbn> <path-to-ino> [extra-options]"
return 1
fi
local fqbn="$1"
local sketch="$2"
local xtra_opts="$3"
local win_opts=""
if [ "$OS_IS_WINDOWS" == "1" ]; then
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
fi
#echo ""
#echo "Compiling '"$(basename "$sketch")"' ..."
mkdir -p "$ARDUINO_BUILD_DIR"
mkdir -p "$ARDUINO_CACHE_DIR"
$ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 \
-fqbn=$fqbn \
-warnings="all" \
-tools "$ARDUINO_IDE_PATH/tools-builder" \
-tools "$ARDUINO_IDE_PATH/tools" \
-built-in-libraries "$ARDUINO_IDE_PATH/libraries" \
-hardware "$ARDUINO_IDE_PATH/hardware" \
-hardware "$ARDUINO_USR_PATH/hardware" \
-libraries "$ARDUINO_USR_PATH/libraries" \
-build-cache "$ARDUINO_CACHE_DIR" \
-build-path "$ARDUINO_BUILD_DIR" \
$win_opts $xtra_opts "$sketch"
}
function count_sketches() # count_sketches <examples-path> <target-mcu>
{
local examples="$1"
local target="$2"
rm -rf sketches.txt
if [ ! -d "$examples" ]; then
touch sketches.txt
return 0
fi
local sketches=$(find $examples -name *.ino)
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "$sketchdirname.ino" != "$sketchname" ]]; then
continue
elif [[ -f "$sketchdir/.skip.$target" ]]; then
continue
else
echo $sketch >> sketches.txt
sketchnum=$(($sketchnum + 1))
fi
done
return $sketchnum
}
function build_sketches() # build_sketches <fqbn> <target-mcu> <examples-path> <chunk> <total-chunks> [extra-options]
{
local fqbn=$1
local target="$2"
local examples=$3
local chunk_idex=$4
local chunks_num=$5
local xtra_opts=$6
if [ "$#" -lt 3 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_sketches <fqbn> <target-mcu <examples-path> [<chunk> <total-chunks>] [extra-options]"
return 1
fi
if [ "$#" -lt 5 ]; then
chunk_idex="0"
chunks_num="1"
xtra_opts=$4
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
set +e
count_sketches "$examples" "$target"
local sketchcount=$?
set -e
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=0
local end_index=0
if [ "$chunk_idex" -ge "$chunks_num" ]; then
start_index=$chunk_idex
end_index=$sketchcount
else
start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
fi
local start_num=$(( $start_index + 1 ))
echo "Found $sketchcount Sketches for target '$target'";
echo "Chunk Index : $chunk_idex"
echo "Chunk Count : $chunks_num"
echo "Chunk Size : $chunk_size"
echo "Start Sketch: $start_num"
echo "End Sketch : $end_index"
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [ "${sketchdirname}.ino" != "$sketchname" ] \
|| [ -f "$sketchdir/.skip.$target" ]; then
continue
fi
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
echo ""
echo "Building Sketch Index $(($sketchnum - 1)) - $sketchdirname"
build_sketch "$fqbn" "$sketch" "$xtra_opts"
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
done
return 0
}

View File

@ -1,11 +1,9 @@
#!/bin/bash #!/bin/bash
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32" export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master" PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git"
XTENSA32_TOOLCHAIN_VERSION="8.4.0+2021r1" TOOLCHAIN_VERSION="8.4.0+2021r2-patch3"
XTENSA32S2_TOOLCHAIN_VERSION="8.4.0+2021r1"
RISCV_TOOLCHAIN_VERSION="8.4.0+2021r1"
ESPTOOLPY_VERSION="~1.30100.0" ESPTOOLPY_VERSION="~1.30100.0"
ESPRESSIF_ORGANIZATION_NAME="espressif" ESPRESSIF_ORGANIZATION_NAME="espressif"
@ -30,9 +28,12 @@ replace_script+="data['packages']['toolchain-xtensa-esp32']['owner']='$ESPRESSIF
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['owner']='$ESPRESSIF_ORGANIZATION_NAME';" replace_script+="data['packages']['toolchain-xtensa-esp32s2']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
replace_script+="data['packages']['toolchain-riscv32-esp']['owner']='$ESPRESSIF_ORGANIZATION_NAME';" replace_script+="data['packages']['toolchain-riscv32-esp']['owner']='$ESPRESSIF_ORGANIZATION_NAME';"
# Update versions to use the upstream # Update versions to use the upstream
replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$XTENSA32_TOOLCHAIN_VERSION';" replace_script+="data['packages']['toolchain-xtensa-esp32']['version']='$TOOLCHAIN_VERSION';"
replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$XTENSA32S2_TOOLCHAIN_VERSION';" replace_script+="data['packages']['toolchain-xtensa-esp32s2']['version']='$TOOLCHAIN_VERSION';"
replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$RISCV_TOOLCHAIN_VERSION';" replace_script+="data['packages']['toolchain-riscv32-esp']['version']='$TOOLCHAIN_VERSION';"
# Add ESP32-S3 Toolchain
replace_script+="data['packages'].update({'toolchain-xtensa-esp32s3':{'type':'toolchain','optional':True,'owner':'$ESPRESSIF_ORGANIZATION_NAME','version':'$TOOLCHAIN_VERSION'}});"
replace_script+="data['packages']['toolchain-xtensa-esp32'].update({'optional':False});"
# esptool.py may require an upstream version (for now platformio is the owner) # esptool.py may require an upstream version (for now platformio is the owner)
replace_script+="data['packages']['tool-esptoolpy']['version']='$ESPTOOLPY_VERSION';" replace_script+="data['packages']['tool-esptoolpy']['version']='$ESPTOOLPY_VERSION';"
# Save results # Save results
@ -40,11 +41,11 @@ replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close
python -c "$replace_script" python -c "$replace_script"
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
echo "Linking Core..." echo "Linking Core..."
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
else else
echo "Cloning Core Repository ..." echo "Cloning Core Repository ..."
git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
fi fi
echo "PlatformIO for ESP32 has been installed" echo "PlatformIO for ESP32 has been installed"
@ -66,8 +67,7 @@ function build_pio_sketch(){ # build_pio_sketch <board> <options> <path-to-ino>
python -m platformio ci --board "$board" "$sketch_dir" --project-option="$options" python -m platformio ci --board "$board" "$sketch_dir" --project-option="$options"
} }
function count_sketches() # count_sketches <examples-path> function count_sketches(){ # count_sketches <examples-path>
{
local examples="$1" local examples="$1"
rm -rf sketches.txt rm -rf sketches.txt
if [ ! -d "$examples" ]; then if [ ! -d "$examples" ]; then
@ -82,7 +82,7 @@ function count_sketches() # count_sketches <examples-path>
local sketchname=$(basename $sketch) local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
continue continue
fi; fi
if [[ -f "$sketchdir/.test.skip" ]]; then if [[ -f "$sketchdir/.test.skip" ]]; then
continue continue
fi fi
@ -92,8 +92,7 @@ function count_sketches() # count_sketches <examples-path>
return $sketchnum return $sketchnum
} }
function build_pio_sketches() # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks> function build_pio_sketches(){ # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks>
{
if [ "$#" -lt 3 ]; then if [ "$#" -lt 3 ]; then
echo "ERROR: Illegal number of parameters" echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketches <board> <options> <examples-path> [<chunk> <total-chunks>]" echo "USAGE: build_pio_sketches <board> <options> <examples-path> [<chunk> <total-chunks>]"

2
.github/scripts/on-pages.sh vendored Normal file → Executable file
View File

@ -71,7 +71,7 @@ function git_safe_upload_to_pages(){
local name=$(basename "$file") local name=$(basename "$file")
local size=`get_file_size "$file"` local size=`get_file_size "$file"`
local upload_res=`git_upload_to_pages "$path" "$file"` local upload_res=`git_upload_to_pages "$path" "$file"`
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
>&2 echo "ERROR: Failed to upload '$name' ($?)" >&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1 return 1
fi fi

View File

@ -2,103 +2,118 @@
set -e set -e
if [ ! -z "$TRAVIS_TAG" ]; then export ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
echo "Skipping Test: Tagged build"
exit 0
fi
if [ ! -z "$GITHUB_WORKSPACE" ]; then function build(){
export TRAVIS_BUILD_DIR="$GITHUB_WORKSPACE" local target=$1
export TRAVIS_REPO_SLUG="$GITHUB_REPOSITORY" local fqbn=$2
elif [ ! -z "$TRAVIS_BUILD_DIR" ]; then local chunk_index=$3
export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR" local chunks_cnt=$4
export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG" local sketches=$5
else
export GITHUB_WORKSPACE="$PWD" local BUILD_SKETCH="${SCRIPTS_DIR}/sketch_utils.sh build"
export GITHUB_REPOSITORY="espressif/arduino-esp32" local BUILD_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
local args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH"
args+=" \"$fqbn\""
if [ "$OS_IS_LINUX" == "1" ]; then
args+=" $target"
args+=" $ARDUINO_ESP32_PATH/libraries"
args+=" $chunk_index $chunks_cnt"
${BUILD_SKETCHES} ${args}
else
if [ "$OS_IS_WINDOWS" == "1" ]; then
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version
-prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
args+=" ${win_opts}"
fi
for sketch in ${sketches}; do
${BUILD_SKETCH} ${args} ${sketch}
done
fi
}
if [ -z "$GITHUB_WORKSPACE" ]; then
export GITHUB_WORKSPACE="$PWD"
export GITHUB_REPOSITORY="espressif/arduino-esp32"
fi fi
CHUNK_INDEX=$1 CHUNK_INDEX=$1
CHUNKS_CNT=$2 CHUNKS_CNT=$2
BUILD_PIO=0 BUILD_PIO=0
if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then
CHUNK_INDEX=0 CHUNK_INDEX=0
CHUNKS_CNT=1 CHUNKS_CNT=1
elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ] && [ "$CHUNKS_CNT" -ge 2 ]; then elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ] && [ "$CHUNKS_CNT" -ge 2 ]; then
CHUNK_INDEX=$CHUNKS_CNT CHUNK_INDEX=$CHUNKS_CNT
elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
BUILD_PIO=1 BUILD_PIO=1
fi fi
#echo "Updating submodules ..." #echo "Updating submodules ..."
#git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1 #git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
SCRIPTS_DIR="./.github/scripts"
if [ "$BUILD_PIO" -eq 0 ]; then if [ "$BUILD_PIO" -eq 0 ]; then
# ArduinoIDE ESP32 Test source ${SCRIPTS_DIR}/install-arduino-ide.sh
TARGET="esp32" source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
source ./.github/scripts/install-arduino-ide.sh
source ./.github/scripts/install-arduino-core-esp32.sh
if [ "$OS_IS_WINDOWS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
elif [ "$OS_IS_MACOS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
else
# CMake Test
if [ "$CHUNK_INDEX" -eq 0 ]; then
bash "$ARDUINO_ESP32_PATH/.github/scripts/check-cmakelists.sh"
fi
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
fi
# ArduinoIDE ESP32S2 Test FQBN_ESP32="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
TARGET="esp32s2" FQBN_ESP32S2="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
FQBN="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app" FQBN_ESP32S3="espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
if [ "$OS_IS_WINDOWS" == "1" ]; then FQBN_ESP32C3="espressif:esp32:esp32c3:PartitionScheme=huge_app"
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
elif [ "$OS_IS_MACOS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
else
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
fi
# ArduinoIDE ESP32C3 Test SKETCHES_ESP32="\
TARGET="esp32c3" $ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\
FQBN="espressif:esp32:esp32c3:PartitionScheme=huge_app" $ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino\
if [ "$OS_IS_WINDOWS" == "1" ]; then $ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ "
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
elif [ "$OS_IS_MACOS" == "1" ]; then SKETCHES_ESP32XX="\
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ $ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" $ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino\
else "
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
fi build "esp32s3" $FQBN_ESP32S3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32
build "esp32s2" $FQBN_ESP32S2 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX
build "esp32c3" $FQBN_ESP32C3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX
build "esp32" $FQBN_ESP32 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32
else else
source ./.github/scripts/install-platformio-esp32.sh source ${SCRIPTS_DIR}/install-platformio-esp32.sh
# PlatformIO ESP32 Test # PlatformIO ESP32 Test
BOARD="esp32dev" BOARD="esp32dev"
OPTIONS="board_build.partitions = huge_app.csv" OPTIONS="board_build.partitions = huge_app.csv"
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
# PlatformIO ESP32 Test # PlatformIO ESP32 Test
# OPTIONS="board_build.mcu = esp32s2" # OPTIONS="board_build.mcu = esp32s2"
# build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ # build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
# build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" # build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s2" --project-option="board_build.partitions = huge_app.csv" python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s2" --project-option="board_build.partitions = huge_app.csv"
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32c3" --project-option="board_build.partitions = huge_app.csv"
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
echo "Hacking in S3 support ..."
replace_script="import json; import os;"
replace_script+="fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+');"
replace_script+="data=json.load(fp);"
replace_script+="data['packages']['toolchain-xtensa-esp32']['optional']=True;"
replace_script+="data['packages']['toolchain-xtensa-esp32s3']['optional']=False;"
replace_script+="data['packages']['tool-esptoolpy']['owner']='tasmota';"
replace_script+="data['packages']['tool-esptoolpy']['version']='https://github.com/tasmota/esptool/releases/download/v3.3/esptool-3.3.zip';"
replace_script+="fp.seek(0);fp.truncate();json.dump(data, fp, indent=2);fp.close()"
python -c "$replace_script"
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s3" --project-option="board_build.partitions = huge_app.csv"
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
fi fi

View File

@ -33,7 +33,7 @@ PACKAGE_JSON_DEV="package_esp32_dev_index.json"
PACKAGE_JSON_REL="package_esp32_index.json" PACKAGE_JSON_REL="package_esp32_index.json"
echo "Event: $GITHUB_EVENT_NAME, Repo: $GITHUB_REPOSITORY, Path: $GITHUB_WORKSPACE, Ref: $GITHUB_REF" echo "Event: $GITHUB_EVENT_NAME, Repo: $GITHUB_REPOSITORY, Path: $GITHUB_WORKSPACE, Ref: $GITHUB_REF"
echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID" echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID"
echo "Tag: $RELEASE_TAG, Draft: $draft, Pre-Release: $RELEASE_PRE" echo "Tag: $RELEASE_TAG, Draft: $draft, Pre-Release: $RELEASE_PRE"
function get_file_size(){ function get_file_size(){
@ -60,7 +60,7 @@ function git_safe_upload_asset(){
local name=$(basename "$file") local name=$(basename "$file")
local size=`get_file_size "$file"` local size=`get_file_size "$file"`
local upload_res=`git_upload_asset "$file"` local upload_res=`git_upload_asset "$file"`
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
>&2 echo "ERROR: Failed to upload '$name' ($?)" >&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1 return 1
fi fi
@ -112,7 +112,7 @@ function git_safe_upload_to_pages(){
local name=$(basename "$file") local name=$(basename "$file")
local size=`get_file_size "$file"` local size=`get_file_size "$file"`
local upload_res=`git_upload_to_pages "$path" "$file"` local upload_res=`git_upload_to_pages "$path" "$file"`
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
>&2 echo "ERROR: Failed to upload '$name' ($?)" >&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1 return 1
fi fi
@ -131,7 +131,7 @@ function merge_package_json(){
local jsonOut=$2 local jsonOut=$2
local old_json=$OUTPUT_DIR/oldJson.json local old_json=$OUTPUT_DIR/oldJson.json
local merged_json=$OUTPUT_DIR/mergedJson.json local merged_json=$OUTPUT_DIR/mergedJson.json
echo "Downloading previous JSON $jsonLink ..." echo "Downloading previous JSON $jsonLink ..."
curl -L -o "$old_json" "https://github.com/$GITHUB_REPOSITORY/releases/download/$jsonLink?access_token=$GITHUB_TOKEN" 2>/dev/null curl -L -o "$old_json" "https://github.com/$GITHUB_REPOSITORY/releases/download/$jsonLink?access_token=$GITHUB_TOKEN" 2>/dev/null
if [ $? -ne 0 ]; then echo "ERROR: Download Failed! $?"; exit 1; fi if [ $? -ne 0 ]; then echo "ERROR: Download Failed! $?"; exit 1; fi
@ -140,7 +140,7 @@ function merge_package_json(){
set +e set +e
stdbuf -oL python "$PACKAGE_JSON_MERGE" "$jsonOut" "$old_json" > "$merged_json" stdbuf -oL python "$PACKAGE_JSON_MERGE" "$jsonOut" "$old_json" > "$merged_json"
set -e set -e
set -v set -v
if [ ! -s $merged_json ]; then if [ ! -s $merged_json ]; then
rm -f "$merged_json" rm -f "$merged_json"
@ -172,6 +172,7 @@ mkdir -p "$PKG_DIR/tools"
# Copy all core files to the package folder # Copy all core files to the package folder
echo "Copying files for packaging ..." echo "Copying files for packaging ..."
cp -f "$GITHUB_WORKSPACE/boards.txt" "$PKG_DIR/" cp -f "$GITHUB_WORKSPACE/boards.txt" "$PKG_DIR/"
cp -f "$GITHUB_WORKSPACE/package.json" "$PKG_DIR/"
cp -f "$GITHUB_WORKSPACE/programmers.txt" "$PKG_DIR/" cp -f "$GITHUB_WORKSPACE/programmers.txt" "$PKG_DIR/"
cp -Rf "$GITHUB_WORKSPACE/cores" "$PKG_DIR/" cp -Rf "$GITHUB_WORKSPACE/cores" "$PKG_DIR/"
cp -Rf "$GITHUB_WORKSPACE/libraries" "$PKG_DIR/" cp -Rf "$GITHUB_WORKSPACE/libraries" "$PKG_DIR/"
@ -317,7 +318,7 @@ releaseNotes=""
relNotesRaw=`git -C "$GITHUB_WORKSPACE" show -s --format=%b $RELEASE_TAG` relNotesRaw=`git -C "$GITHUB_WORKSPACE" show -s --format=%b $RELEASE_TAG`
readarray -t msgArray <<<"$relNotesRaw" readarray -t msgArray <<<"$relNotesRaw"
arrLen=${#msgArray[@]} arrLen=${#msgArray[@]}
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
ind=3 ind=3
while [ $ind -lt $arrLen ]; do while [ $ind -lt $arrLen ]; do
if [ $ind -eq 3 ]; then if [ $ind -eq 3 ]; then
@ -327,7 +328,7 @@ if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')" oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')"
if [ ${#oneLine} -gt 0 ]; then if [ ${#oneLine} -gt 0 ]; then
if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi
if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi
releaseNotes+="$oneLine" releaseNotes+="$oneLine"
releaseNotes+=$'\r\n' releaseNotes+=$'\r\n'
fi fi
@ -368,9 +369,9 @@ done
rm -f $commitFile rm -f $commitFile
# Prepend the original release body # Prepend the original release body
if [ "${RELEASE_BODY: -1}" == $'\r' ]; then if [ "${RELEASE_BODY: -1}" == $'\r' ]; then
RELEASE_BODY="${RELEASE_BODY:0:-1}" RELEASE_BODY="${RELEASE_BODY:0:-1}"
else else
RELEASE_BODY="$RELEASE_BODY" RELEASE_BODY="$RELEASE_BODY"
fi fi
RELEASE_BODY+=$'\r\n' RELEASE_BODY+=$'\r\n'

192
.github/scripts/sketch_utils.sh vendored Executable file
View File

@ -0,0 +1,192 @@
#!/bin/bash
function build_sketch(){ # build_sketch <ide_path> <user_path> <fqbn> <path-to-ino> [extra-options]
if [ "$#" -lt 4 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: ${0} build <ide_path> <user_path> <fqbn> <path-to-ino> [extra-options]"
return 1
fi
local ide_path=$1
local usr_path=$2
local fqbn=$3
local sketch=$4
local xtra_opts=$5
local win_opts=$6
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
if [ -z "$ARDUINO_BUILD_DIR" ]; then
build_dir="$(dirname $sketch)/build"
else
build_dir="$ARDUINO_BUILD_DIR"
fi
echo $sketch
rm -rf "$build_dir"
mkdir -p "$build_dir"
mkdir -p "$ARDUINO_CACHE_DIR"
$ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \
-fqbn=$fqbn \
-warnings="all" \
-tools "$ide_path/tools-builder" \
-tools "$ide_path/tools" \
-built-in-libraries "$ide_path/libraries" \
-hardware "$ide_path/hardware" \
-hardware "$usr_path/hardware" \
-libraries "$usr_path/libraries" \
-build-cache "$ARDUINO_CACHE_DIR" \
-build-path "$build_dir" \
$win_opts $xtra_opts "$sketch"
}
function count_sketches(){ # count_sketches <path> [target]
local path=$1
local target=$2
if [ $# -lt 1 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: ${0} count <path> [target]"
fi
rm -rf sketches.txt
if [ ! -d "$path" ]; then
touch sketches.txt
return 0
fi
local sketches=$(find $path -name *.ino | sort)
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "$sketchdirname.ino" != "$sketchname" ]]; then
continue
elif [[ -n $target ]] && [[ -f "$sketchdir/.skip.$target" ]]; then
continue
else
echo $sketch >> sketches.txt
sketchnum=$(($sketchnum + 1))
fi
done
return $sketchnum
}
function build_sketches(){ # build_sketches <ide_path> <user_path> <fqbn> <target> <path> <chunk> <total-chunks> [extra-options]
local ide_path=$1
local usr_path=$2
local fqbn=$3
local target=$4
local path=$5
local chunk_idex=$6
local chunks_num=$7
local xtra_opts=$8
if [ "$#" -lt 7 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: ${0} chunk_build <ide_path> <user_path> <fqbn> <target> <path> [<chunk> <total-chunks>] [extra-options]"
return 1
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
set +e
count_sketches "$path" "$target"
local sketchcount=$?
set -e
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=0
local end_index=0
if [ "$chunk_idex" -ge "$chunks_num" ]; then
start_index=$chunk_idex
end_index=$sketchcount
else
start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
fi
local start_num=$(( $start_index + 1 ))
echo "Found $sketchcount Sketches for target '$target'";
echo "Chunk Index : $chunk_idex"
echo "Chunk Count : $chunks_num"
echo "Chunk Size : $chunk_size"
echo "Start Sketch: $start_num"
echo "End Sketch : $end_index"
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
echo ""
echo "Building Sketch Index $(($sketchnum - 1)) - $sketchdirname"
build_sketch "$ide_path" "$usr_path" "$fqbn" "$sketch" "$xtra_opts"
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
done
return 0
}
USAGE="
USAGE: ${0} [command] [options]
Available commands:
count: Count sketches.
build: Build a sketch.
chunk_build: Build a chunk of sketches.
"
cmd=$1
shift
if [ -z $cmd ]; then
echo "ERROR: No command supplied"
echo "$USAGE"
exit 2
fi
case "$cmd" in
"count")
count_sketches $*
;;
"build")
build_sketch $*
;;
"chunk_build")
build_sketches $*
;;
*)
echo "ERROR: Unrecognized command"
echo "$USAGE"
exit 2
esac

58
.github/scripts/tests_build.sh vendored Executable file
View File

@ -0,0 +1,58 @@
#!/bin/bash
SCRIPTS_DIR="./.github/scripts"
BUILD_CMD=""
if [ $# -eq 3 ]; then
chunk_build=1
elif [ $# -eq 2 ]; then
chunk_build=0
else
echo "ERROR: Illegal number of parameters"
echo "USAGE:
${0} <target> <sketch_dir>
${0} <target> <chunk> <total_chunks>
"
exit 0
fi
target=$1
case "$target" in
"esp32") fqbn="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
;;
"esp32s2") fqbn="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
;;
"esp32c3") fqbn="espressif:esp32:esp32c3:PartitionScheme=huge_app"
;;
"esp32s3") fqbn="espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
;;
esac
if [ -z $fqbn ]; then
echo "Unvalid chip $1"
exit 0
fi
source ${SCRIPTS_DIR}/install-arduino-ide.sh
source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH \"$fqbn\""
if [ $chunk_build -eq 1 ]; then
chunk_index=$2
chunk_max=$3
if [ "$chunk_index" -gt "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then
chunk_index=$chunk_max
fi
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
args+=" $target $PWD/tests $chunk_index $chunk_max"
else
sketchdir=$2
BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh build"
args+=" $PWD/tests/$sketchdir/$sketchdir.ino"
fi
${BUILD_CMD} ${args}

71
.github/scripts/tests_run.sh vendored Executable file
View File

@ -0,0 +1,71 @@
#!/bin/bash
target=$1
chunk_idex=$2
chunks_num=$3
SCRIPTS_DIR="./.github/scripts"
COUNT_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh count"
source ${SCRIPTS_DIR}/install-arduino-ide.sh
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
set +e
${COUNT_SKETCHES} $PWD/tests $target
sketchcount=$?
set -e
sketches=$(cat sketches.txt)
rm -rf sketches.txt
chunk_size=$(( $sketchcount / $chunks_num ))
all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
start_index=0
end_index=0
if [ "$chunk_idex" -ge "$chunks_num" ]; then
start_index=$chunk_idex
end_index=$sketchcount
else
start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
fi
start_num=$(( $start_index + 1 ))
sketchnum=0
for sketch in $sketches; do
sketchdir=$(dirname $sketch)
sketchdirname=$(basename $sketchdir)
sketchname=$(basename $sketch)
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
echo ""
echo "Test for Sketch Index $(($sketchnum - 1)) - $sketchdirname"
pytest tests -k test_$sketchdirname --junit-xml=tests/$sketchdirname/$sketchdirname.xml
result=$?
if [ $result -ne 0 ]; then
return $result
fi
done

39
.github/scripts/update-version.sh vendored Executable file
View File

@ -0,0 +1,39 @@
#!/bin/bash
# For reference: add tools for all boards by replacing one line in each board
# "[board].upload.tool=esptool_py" to "[board].upload.tool=esptool_py\n[board].upload.tool.default=esptool_py\n[board].upload.tool.network=esp_ota"
#cat boards.txt | sed "s/\([a-zA-Z0-9_\-]*\)\.upload\.tool\=esptool_py/\1\.upload\.tool\=esptool_py\\n\1\.upload\.tool\.default\=esptool_py\\n\1\.upload\.tool\.network\=esp_ota/"
if [ ! $# -eq 3 ]; then
echo "Bad number of arguments: $#" >&2
echo "usage: $0 <major> <minor> <patch>" >&2
exit 1
fi
re='^[0-9]+$'
if [[ ! $1 =~ $re ]] || [[ ! $2 =~ $re ]] || [[ ! $3 =~ $re ]] ; then
echo "error: Not a valid version: $1.$2.$3" >&2
echo "usage: $0 <major> <minor> <patch>" >&2
exit 1
fi
ESP_ARDUINO_VERSION_MAJOR="$1"
ESP_ARDUINO_VERSION_MINOR="$2"
ESP_ARDUINO_VERSION_PATCH="$3"
ESP_ARDUINO_VERSION="$ESP_ARDUINO_VERSION_MAJOR.$ESP_ARDUINO_VERSION_MINOR.$ESP_ARDUINO_VERSION_PATCH"
echo "New Arduino Version: $ESP_ARDUINO_VERSION"
echo "Updating platform.txt..."
cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > __platform.txt && mv __platform.txt platform.txt
echo "Updating package.json..."
cat package.json | sed "s/.*\"version\":.*/ \"version\": \"$ESP_ARDUINO_VERSION\",/g" > __package.json && mv __package.json package.json
echo "Updating cores/esp32/esp_arduino_version.h..."
cat cores/esp32/esp_arduino_version.h | \
sed "s/#define ESP_ARDUINO_VERSION_MAJOR.*/#define ESP_ARDUINO_VERSION_MAJOR $ESP_ARDUINO_VERSION_MAJOR/g" | \
sed "s/#define ESP_ARDUINO_VERSION_MINOR.*/#define ESP_ARDUINO_VERSION_MINOR $ESP_ARDUINO_VERSION_MINOR/g" | \
sed "s/#define ESP_ARDUINO_VERSION_PATCH.*/#define ESP_ARDUINO_VERSION_PATCH $ESP_ARDUINO_VERSION_PATCH/g" > __esp_arduino_version.h && mv __esp_arduino_version.h cores/esp32/esp_arduino_version.h
exit 0

26
.github/stale.yml vendored
View File

@ -1,26 +0,0 @@
# This workflow firstly warns and then closes issues that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information can be found here: https://github.com/actions/stale
name: Mark stale issues
on:
schedule:
- cron: '30 9 * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.'
days-before-stale: 60
days-before-close: 14
exempt-issue-labels: 'Type: For reference,Type: To be implemented,Type: Feature request'
stale-issue-label: 'Status: Stale'

View File

@ -16,7 +16,7 @@ jobs:
name: Build GitHub Pages name: Build GitHub Pages
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- name: Copy Files - name: Copy Files
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

121
.github/workflows/hil.yml vendored Normal file
View File

@ -0,0 +1,121 @@
name: Run tests in hardware
on:
pull_request:
types: [opened, reopened, synchronize, labeled]
schedule:
- cron: '0 2 * * *'
env:
MAX_CHUNKS: 15
concurrency:
group: hil-${{github.event.pull_request.number || github.ref}}
cancel-in-progress: true
jobs:
gen_chunks:
if: |
contains(github.event.pull_request.labels.*.name, 'hil_test') ||
github.event_name == 'schedule'
name: Generate Chunks matrix
runs-on: ubuntu-latest
outputs:
chunks: ${{ steps.gen-chunks.outputs.chunks }}
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Generate Chunks matrix
id: gen-chunks
run: |
set +e
bash .github/scripts/sketch_utils.sh count tests
sketches=$((? - 1))
if [[ $sketches -gt ${{env.MAX_CHUNKS}} ]]; then
$sketches=${{env.MAX_CHUNKS}}
fi
set -e
rm sketches.txt
CHUNKS=$(jq -c -n '$ARGS.positional' --args `seq 0 1 $sketches`)
echo "::set-output name=chunks::${CHUNKS}"
Build:
needs: gen_chunks
name: ${{matrix.chip}}-Build#${{matrix.chunks}}
runs-on: ubuntu-latest
strategy:
matrix:
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Build sketches
run: |
bash .github/scripts/tests_build.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
- name: Upload ${{matrix.chip}}-${{matrix.chunks}} artifacts
uses: actions/upload-artifact@v2
with:
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
path: |
tests/*/build/*.bin
tests/*/build/*.json
Test:
needs: [gen_chunks, Build]
name: ${{matrix.chip}}-Test#${{matrix.chunks}}
runs-on:
- ESP32
- ESP32-S2
- ESP32-S3
- ESP32-C3
strategy:
fail-fast: false
matrix:
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
container:
image: python:3.10.1-bullseye
options: --privileged
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Download ${{matrix.chip}}-${{matrix.chunks}} artifacts
uses: actions/download-artifact@v2
with:
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
path: tests/
- name: Install dependencies
run: |
pip install -U pip
pip install -r tests/requirements.txt
- name: Run Tests
run: |
bash .github/scripts/tests_run.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
- name: Upload test result artifacts
uses: actions/upload-artifact@v2
if: always()
with:
name: test_results-${{matrix.chip}}-${{matrix.chunks}}
path: tests/*/*.xml
event_file:
name: "Event File"
if: ${{ always() }}
needs: Test
runs-on: ubuntu-latest
steps:
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Event File
path: ${{github.event_path}}

38
.github/workflows/publish.yml vendored Normal file
View File

@ -0,0 +1,38 @@
name: Unit Test Results
on:
workflow_run:
workflows: [Run tests in hardware]
branches-ignore: [master]
types:
- completed
jobs:
unit-test-results:
name: Unit Test Results
runs-on: ubuntu-latest
if: |
github.event.workflow_run.event == 'pull_request' &&
(github.event.workflow_run.conclusion == 'success' ||
github.event.workflow_run.conclusion == 'failure')
steps:
- name: Download and Extract Artifacts
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
mkdir -p artifacts && cd artifacts
artifacts_url=${{ github.event.workflow_run.artifacts_url }}
gh api "$artifacts_url" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact
do
IFS=$'\t' read name url <<< "$artifact"
gh api $url > "$name.zip"
unzip -d "$name" "$name.zip"
done
- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v1
with:
commit: ${{ github.event.workflow_run.head_sha }}
event_file: artifacts/Event File/event.json
event_name: ${{ github.event.workflow_run.event }}
files: "artifacts/**/*.xml"

View File

@ -1,14 +1,26 @@
name: ESP32 Arduino CI name: ESP32 Arduino CI
on: on:
workflow_dispatch:
push: push:
branches: branches:
- master - master
- release/* - release/*
pull_request: pull_request:
concurrency:
group: build-${{github.event.pull_request.number || github.ref}}
cancel-in-progress: true
jobs: jobs:
cmake-check:
name: Check cmake file
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: bash ./.github/scripts/check-cmakelists.sh
# Ubuntu # Ubuntu
build-arduino-linux: build-arduino-linux:
name: Arduino ${{ matrix.chunk }} on ubuntu-latest name: Arduino ${{ matrix.chunk }} on ubuntu-latest
@ -16,12 +28,22 @@ jobs:
strategy: strategy:
matrix: matrix:
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- uses: actions/setup-python@v1 - uses: actions/setup-python@v2
with: with:
python-version: '3.x' python-version: '3.x'
- name: Cache tools
id: cache-linux
uses: actions/cache@v2
with:
path: |
./tools/dist
~/arduino_ide
key: ${{ runner.os }}-${{ hashFiles('package/package_esp32_index.template.json',
'tools/get.py',
'.github/scripts/install-arduino-ide.sh') }}
- name: Build Sketches - name: Build Sketches
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} 15 run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} 15
@ -32,10 +54,10 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [windows-latest, macOS-latest] os: [windows-latest, macOS-latest]
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- uses: actions/setup-python@v1 - uses: actions/setup-python@v2
with: with:
python-version: '3.x' python-version: '3.x'
- name: Build Sketches - name: Build Sketches
@ -48,11 +70,38 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest, windows-latest, macOS-latest] os: [ubuntu-latest, windows-latest, macOS-latest]
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- uses: actions/setup-python@v1 - uses: actions/setup-python@v2
with: with:
python-version: '3.x' python-version: '3.x'
- name: Build Sketches - name: Build Sketches
run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO
build-esp-idf-component:
name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
runs-on: ubuntu-20.04
strategy:
matrix:
# The version names here correspond to the versions of espressif/idf Docker image.
# See https://hub.docker.com/r/espressif/idf/tags and
# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html
# for details.
idf_ver: ["release-v4.4"]
idf_target: ["esp32", "esp32s2", "esp32s3", "esp32c3"]
container: espressif/idf:${{ matrix.idf_ver }}
steps:
- name: Check out arduino-esp32 as a component
uses: actions/checkout@v2
with:
submodules: recursive
path: components/arduino-esp32
- name: Build
env:
IDF_TARGET: ${{ matrix.idf_target }}
shell: bash
run: |
. ${IDF_PATH}/export.sh
idf.py create-project test
idf.py -C test -DEXTRA_COMPONENT_DIRS=$PWD/components build

View File

@ -10,10 +10,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@v1 - uses: actions/setup-python@v2
with: with:
python-version: '3.x' python-version: '3.x'
- name: Build Release - name: Build Release

View File

@ -1,27 +0,0 @@
name: Test Github action on self hosted RPI runnes
on:
push:
branches:
- master
pull_request:
jobs:
build:
name: Dummy test - self hosted GHR
runs-on: self-hosted
steps:
- name: Check out repo
uses: actions/checkout@v2
- name: Test message 1
run: echo "This is test message"
- name: Test message 2
run: echo "This is test message2"
- name: List directory
run: ls
- name: Create copy of README
run: cp README.md README2.md
- name: Read README2
run: cat README2.md
- name: Delete README2
run: rm README2.md

View File

@ -0,0 +1,19 @@
name: Push components to https://components.espressif.com
on:
push:
tags:
- v*
jobs:
upload_components:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: "recursive"
- name: Upload components to the component registry
uses: espressif/github-actions/upload_components@master
with:
name: arduino-esp32
namespace: espressif
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}

4
.gitignore vendored
View File

@ -1,5 +1,6 @@
tools/xtensa-esp32-elf tools/xtensa-esp32-elf
tools/xtensa-esp32s2-elf tools/xtensa-esp32s2-elf
tools/xtensa-esp32s3-elf
tools/riscv32-esp-elf tools/riscv32-esp-elf
tools/dist tools/dist
tools/esptool tools/esptool
@ -22,3 +23,6 @@ boards.sloeber.txt
# Ignore docs build (Sphinx) # Ignore docs build (Sphinx)
docs/build docs/build
docs/source/_build docs/source/_build
# Test log files
*.log

View File

@ -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

View File

@ -57,6 +57,7 @@ set(CORE_SRCS
cores/esp32/stdlib_noniso.c cores/esp32/stdlib_noniso.c
cores/esp32/Stream.cpp cores/esp32/Stream.cpp
cores/esp32/StreamString.cpp cores/esp32/StreamString.cpp
cores/esp32/Tone.cpp
cores/esp32/HWCDC.cpp cores/esp32/HWCDC.cpp
cores/esp32/USB.cpp cores/esp32/USB.cpp
cores/esp32/USBCDC.cpp cores/esp32/USBCDC.cpp
@ -86,6 +87,7 @@ set(LIBRARY_SRCS
libraries/HTTPClient/src/HTTPClient.cpp libraries/HTTPClient/src/HTTPClient.cpp
libraries/HTTPUpdate/src/HTTPUpdate.cpp libraries/HTTPUpdate/src/HTTPUpdate.cpp
libraries/LittleFS/src/LittleFS.cpp libraries/LittleFS/src/LittleFS.cpp
libraries/I2S/src/I2S.cpp
libraries/NetBIOS/src/NetBIOS.cpp libraries/NetBIOS/src/NetBIOS.cpp
libraries/Preferences/src/Preferences.cpp libraries/Preferences/src/Preferences.cpp
libraries/RainMaker/src/RMaker.cpp libraries/RainMaker/src/RMaker.cpp
@ -115,6 +117,7 @@ set(LIBRARY_SRCS
libraries/WebServer/src/Parsing.cpp libraries/WebServer/src/Parsing.cpp
libraries/WebServer/src/detail/mimetable.cpp libraries/WebServer/src/detail/mimetable.cpp
libraries/WiFiClientSecure/src/ssl_client.cpp libraries/WiFiClientSecure/src/ssl_client.cpp
libraries/WiFiClientSecure/src/esp_crt_bundle.c
libraries/WiFiClientSecure/src/WiFiClientSecure.cpp libraries/WiFiClientSecure/src/WiFiClientSecure.cpp
libraries/WiFi/src/WiFiAP.cpp libraries/WiFi/src/WiFiAP.cpp
libraries/WiFi/src/WiFiClient.cpp libraries/WiFi/src/WiFiClient.cpp
@ -161,7 +164,6 @@ set(BLE_SRCS
libraries/BLE/src/GeneralUtils.cpp libraries/BLE/src/GeneralUtils.cpp
) )
set(includedirs set(includedirs
variants/${IDF_TARGET}/ variants/${IDF_TARGET}/
cores/esp32/ cores/esp32/
@ -173,11 +175,13 @@ set(includedirs
libraries/EEPROM/src libraries/EEPROM/src
libraries/ESP32/src libraries/ESP32/src
libraries/ESPmDNS/src libraries/ESPmDNS/src
libraries/Ethernet/src
libraries/FFat/src libraries/FFat/src
libraries/FS/src libraries/FS/src
libraries/HTTPClient/src libraries/HTTPClient/src
libraries/HTTPUpdate/src libraries/HTTPUpdate/src
libraries/LittleFS/src libraries/LittleFS/src
libraries/I2S/src
libraries/NetBIOS/src libraries/NetBIOS/src
libraries/Preferences/src libraries/Preferences/src
libraries/RainMaker/src libraries/RainMaker/src
@ -198,7 +202,7 @@ set(includedirs
set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS}) set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS})
set(priv_includes cores/esp32/libb64) set(priv_includes cores/esp32/libb64)
set(requires spi_flash mbedtls mdns esp_adc_cal wifi_provisioning nghttp) set(requires spi_flash mbedtls mdns esp_adc_cal wifi_provisioning nghttp wpa_supplicant)
set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support openssl bt esp_ipc esp_hid) set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support openssl bt esp_ipc esp_hid)
idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires}) idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires})
@ -233,7 +237,9 @@ function(maybe_add_component component_name)
endif() endif()
endfunction() endfunction()
if(IDF_TARGET MATCHES "esp32" AND CONFIG_ESP_RMAKER_TASK_STACK) maybe_add_component(esp-dsp)
if(CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK)
maybe_add_component(esp_rainmaker) maybe_add_component(esp_rainmaker)
maybe_add_component(qrcode) maybe_add_component(qrcode)
endif() endif()

View File

@ -1,7 +0,0 @@
BOOT_APP_BIN_ROOT := $(call dequote,$(COMPONENT_PATH))
ifndef CONFIG_PARTITION_TABLE_CUSTOM
PARTITION_TABLE_CSV_PATH = $(call dequote,$(abspath $(BOOT_APP_BIN_ROOT)/$(subst $(quote),,tools/partitions/$(CONFIG_ARDUHAL_PARTITION_SCHEME).csv)))
endif
CPPFLAGS += -DARDUINO=10800 -DESP32=1 -DARDUINO_ARCH_ESP32=1 -DBOARD_HAS_PSRAM

View File

@ -1,14 +1,18 @@
# Arduino core for the ESP32, ESP32-S2 and ESP32-C3 # Arduino core for the ESP32, ESP32-S2, ESP32-S3 and ESP32-C3
![Build Status](https://github.com/espressif/arduino-esp32/workflows/ESP32%20Arduino%20CI/badge.svg) [![Documentation Status](https://readthedocs.com/projects/espressif-arduino-esp32/badge/?version=latest)](https://docs.espressif.com/projects/arduino-esp32/en/latest/?badge=latest) ![Build Status](https://github.com/espressif/arduino-esp32/workflows/ESP32%20Arduino%20CI/badge.svg) [![Documentation Status](https://readthedocs.com/projects/espressif-arduino-esp32/badge/?version=latest)](https://docs.espressif.com/projects/arduino-esp32/en/latest/?badge=latest)
### Need help or have a question? Join the chat at [![https://gitter.im/espressif/arduino-esp32](https://badges.gitter.im/espressif/arduino-esp32.svg)](https://gitter.im/espressif/arduino-esp32?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ### Need help or have a question? Join the chat at [![https://gitter.im/espressif/arduino-esp32](https://badges.gitter.im/espressif/arduino-esp32.svg)](https://gitter.im/espressif/arduino-esp32?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) or [open a new Discussion](https://github.com/espressif/arduino-esp32/discussions)
## Contents ## Contents
- [Development Status](#development-status) - [Development Status](#development-status)
- [Decoding Exceptions](#decoding-exceptions) - [Development Planning](#development-planning)
- [Issue/Bug report template](#issuebug-report-template) - [Documentation](#documentation)
- [Supported Chips](#supported-chips)
- [Decoding exceptions](#decoding-exceptions)
- [Issue/Bug report template](#issuebug-report-template)
- [Contributing](#contributing)
### Development Status ### Development Status
@ -16,9 +20,15 @@ Latest Stable Release [![Release Version](https://img.shields.io/github/release
Latest Development Release [![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/) [![Release Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/) [![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/) Latest Development Release [![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/) [![Release Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/) [![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/)
### Development Planning
Our Development is fully tracked on this public **[Roadmap 🎉](https://github.com/orgs/espressif/projects/3)**
For even more information you can take a look at [Sprint Meeting notes](https://github.com/espressif/arduino-esp32/discussions/categories/sprints-meeting-notes) or join [Monthly Community Meetings 🔔](https://github.com/espressif/arduino-esp32/discussions/categories/monthly-community-meetings)
### Documentation ### Documentation
You can use [Arduino-ESP32 Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/) to get all information about this project. You can use the [Arduino-ESP32 Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/) to get all information about this project.
* [Getting Started](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html) * [Getting Started](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html)
* [Installing (Windows, Linux and macOS)](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html) * [Installing (Windows, Linux and macOS)](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html)
@ -27,14 +37,19 @@ You can use [Arduino-ESP32 Online Documentation](https://docs.espressif.com/proj
* [FAQ](https://docs.espressif.com/projects/arduino-esp32/en/latest/faq.html) * [FAQ](https://docs.espressif.com/projects/arduino-esp32/en/latest/faq.html)
* [Troubleshooting](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html) * [Troubleshooting](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html)
### Supported Chips
Visit the [supported chips](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html#supported-soc-s) documentation to see the list of current supported ESP32 SoCs.
### Decoding exceptions ### Decoding exceptions
You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder) to get meaningful call trace. You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder) to get meaningful call trace.
### Issue/Bug report template ### Issue/Bug report template
Before reporting an issue, make sure you've searched for similar one that was already created. Also make sure to go through all the issues labelled as [Type: For reference](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue+label%3A%22Type%3A+For+reference%22+). Before reporting an issue, make sure you've searched for similar one that was already created. Also make sure to go through all the issues labelled as [Type: For reference](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue+label%3A%22Type%3A+For+reference%22+).
Finally, if you are sure no one else had the issue, follow the [issue template](docs/ISSUE_TEMPLATE.md) while reporting any issue. Finally, if you are sure no one else had the issue, follow the **Issue template** or **Feature request template** while reporting any [new Issue](https://github.com/espressif/arduino-esp32/issues/new/choose).
### Contributing ### Contributing

5071
boards.txt

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +0,0 @@
ARDUINO_ALL_LIBRARIES := $(patsubst $(COMPONENT_PATH)/libraries/%,%,$(wildcard $(COMPONENT_PATH)/libraries/*))
# Macro returns non-empty if Arduino library $(1) should be included in the build
# (either because selective compilation is of, or this library is enabled
define ARDUINO_LIBRARY_ENABLED
$(if $(CONFIG_ARDUINO_SELECTIVE_COMPILATION),$(CONFIG_ARDUINO_SELECTIVE_$(1)),y)
endef
ARDUINO_ENABLED_LIBRARIES := $(foreach LIBRARY,$(sort $(ARDUINO_ALL_LIBRARIES)),$(if $(call ARDUINO_LIBRARY_ENABLED,$(LIBRARY)),$(LIBRARY)))
$(info Arduino libraries in build: $(ARDUINO_ENABLED_LIBRARIES))
# Expand all subdirs under $(1)
define EXPAND_SUBDIRS
$(sort $(dir $(wildcard $(1)/* $(1)/*/* $(1)/*/*/* $(1)/*/*/*/* $(1)/*/*/*/*/*)))
endef
# Macro returns SRCDIRS for library
define ARDUINO_LIBRARY_GET_SRCDIRS
$(if $(wildcard $(COMPONENT_PATH)/libraries/$(1)/src/.), \
$(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)/src), \
$(filter-out $(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)/examples), \
$(call EXPAND_SUBDIRS,$(COMPONENT_PATH)/libraries/$(1)) \
) \
)
endef
# Make a list of all srcdirs in enabled libraries
ARDUINO_LIBRARY_SRCDIRS := $(patsubst $(COMPONENT_PATH)/%,%,$(foreach LIBRARY,$(ARDUINO_ENABLED_LIBRARIES),$(call ARDUINO_LIBRARY_GET_SRCDIRS,$(LIBRARY))))
#$(info Arduino libraries src dirs: $(ARDUINO_LIBRARY_SRCDIRS))
COMPONENT_ADD_INCLUDEDIRS := cores/esp32 variants/esp32 $(ARDUINO_LIBRARY_SRCDIRS)
COMPONENT_PRIV_INCLUDEDIRS := cores/esp32/libb64
COMPONENT_SRCDIRS := cores/esp32/libb64 cores/esp32 variants/esp32 $(ARDUINO_LIBRARY_SRCDIRS)
CXXFLAGS += -fno-rtti

View File

@ -166,6 +166,7 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
#include "Udp.h" #include "Udp.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "Esp.h" #include "Esp.h"
#include "esp32/spiram.h"
using std::abs; using std::abs;
using std::isinf; using std::isinf;
@ -179,6 +180,12 @@ uint16_t makeWord(uint8_t h, uint8_t l);
#define word(...) makeWord(__VA_ARGS__) #define word(...) makeWord(__VA_ARGS__)
size_t getArduinoLoopTaskStackSize(void);
#define SET_LOOP_TASK_STACK_SIZE(sz) size_t getArduinoLoopTaskStackSize() { return sz;}
// allows user to bypass esp_spiram_test()
#define BYPASS_SPIRAM_TEST(bypass) bool testSPIRAM(void) { if (bypass) return true; else return esp_spiram_test(); }
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
@ -188,6 +195,10 @@ extern "C" void configTime(long gmtOffset_sec, int daylightOffset_sec,
extern "C" void configTzTime(const char* tz, extern "C" void configTzTime(const char* tz,
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr); const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);
void setToneChannel(uint8_t channel = 0);
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);
// WMath prototypes // WMath prototypes
long random(long); long random(long);
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -40,6 +40,10 @@ extern "C" {
#include "esp32s2/rom/spi_flash.h" #include "esp32s2/rom/spi_flash.h"
#include "soc/efuse_reg.h" #include "soc/efuse_reg.h"
#define ESP_FLASH_IMAGE_BASE 0x1000 #define ESP_FLASH_IMAGE_BASE 0x1000
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/spi_flash.h"
#include "soc/efuse_reg.h"
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32s3 is located at 0x0000
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/spi_flash.h" #include "esp32c3/rom/spi_flash.h"
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32c3 is located at 0x0000 #define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32c3 is located at 0x0000

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "USB.h" #include "USB.h"
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
#include "esp32-hal.h" #include "esp32-hal.h"
#include "HWCDC.h" #include "HWCDC.h"
@ -167,19 +167,21 @@ void HWCDC::begin(unsigned long baud)
setRxBufferSize(256);//default if not preset setRxBufferSize(256);//default if not preset
setTxBufferSize(256);//default if not preset setTxBufferSize(256);//default if not preset
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET); usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET); usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
if(!intr_handle && esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, 0, hw_cdc_isr_handler, NULL, &intr_handle) != ESP_OK){ if(!intr_handle && esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, 0, hw_cdc_isr_handler, NULL, &intr_handle) != ESP_OK){
isr_log_e("HW USB CDC failed to init interrupts"); isr_log_e("HW USB CDC failed to init interrupts");
end(); end();
return; return;
} }
usb_serial_jtag_ll_txfifo_flush();
} }
void HWCDC::end() void HWCDC::end()
{ {
//Disable tx/rx interrupt. //Disable tx/rx interrupt.
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET); usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
esp_intr_free(intr_handle); esp_intr_free(intr_handle);
intr_handle = NULL; intr_handle = NULL;
if(tx_lock != NULL) { if(tx_lock != NULL) {
@ -379,10 +381,12 @@ void HWCDC::setDebugOutput(bool en)
} }
} }
#if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC #if ARDUINO_USB_MODE
#if ARDUINO_USB_CDC_ON_BOOT//Serial used for USB CDC
HWCDC Serial; HWCDC Serial;
#else #else
HWCDC USBSerial; HWCDC USBSerial;
#endif #endif
#endif
#endif /* CONFIG_TINYUSB_CDC_ENABLED */ #endif /* CONFIG_TINYUSB_CDC_ENABLED */

View File

@ -14,7 +14,7 @@
#pragma once #pragma once
#include "sdkconfig.h" #include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
#include <inttypes.h> #include <inttypes.h>
#include "esp_event.h" #include "esp_event.h"
@ -98,10 +98,12 @@ public:
}; };
#if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC #if ARDUINO_USB_MODE
#if ARDUINO_USB_CDC_ON_BOOT//Serial used for USB CDC
extern HWCDC Serial; extern HWCDC Serial;
#else #else
extern HWCDC USBSerial; extern HWCDC USBSerial;
#endif #endif
#endif
#endif /* CONFIG_IDF_TARGET_ESP32C3 */ #endif /* CONFIG_IDF_TARGET_ESP32C3 */

View File

@ -6,11 +6,13 @@
#include "pins_arduino.h" #include "pins_arduino.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "driver/uart.h"
#include "freertos/queue.h"
#ifndef SOC_RX0 #ifndef SOC_RX0
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
#define SOC_RX0 3 #define SOC_RX0 3
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define SOC_RX0 44 #define SOC_RX0 44
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#define SOC_RX0 20 #define SOC_RX0 20
@ -20,7 +22,7 @@
#ifndef SOC_TX0 #ifndef SOC_TX0
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
#define SOC_TX0 1 #define SOC_TX0 1
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define SOC_TX0 43 #define SOC_TX0 43
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#define SOC_TX0 21 #define SOC_TX0 21
@ -39,6 +41,8 @@ void serialEvent(void) {}
#define RX1 18 #define RX1 18
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#define RX1 18 #define RX1 18
#elif CONFIG_IDF_TARGET_ESP32S3
#define RX1 15
#endif #endif
#endif #endif
@ -49,6 +53,8 @@ void serialEvent(void) {}
#define TX1 17 #define TX1 17
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#define TX1 19 #define TX1 19
#elif CONFIG_IDF_TARGET_ESP32S3
#define TX1 16
#endif #endif
#endif #endif
@ -60,12 +66,16 @@ void serialEvent1(void) {}
#ifndef RX2 #ifndef RX2
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
#define RX2 16 #define RX2 16
#elif CONFIG_IDF_TARGET_ESP32S3
#define RX2 19
#endif #endif
#endif #endif
#ifndef TX2 #ifndef TX2
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
#define TX2 17 #define TX2 17
#elif CONFIG_IDF_TARGET_ESP32S3
#define TX2 20
#endif #endif
#endif #endif
@ -76,8 +86,6 @@ void serialEvent2(void) {}
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC #if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
HardwareSerial Serial0(0); HardwareSerial Serial0(0);
#elif ARDUINO_HW_CDC_ON_BOOT
HardwareSerial Serial0(0);
#else #else
HardwareSerial Serial(0); HardwareSerial Serial(0);
#endif #endif
@ -92,8 +100,6 @@ void serialEventRun(void)
{ {
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC #if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
if(Serial0.available()) serialEvent(); if(Serial0.available()) serialEvent();
#elif ARDUINO_HW_CDC_ON_BOOT
if(Serial0.available()) serialEvent();
#else #else
if(Serial.available()) serialEvent(); if(Serial.available()) serialEvent();
#endif #endif
@ -106,8 +112,167 @@ void serialEventRun(void)
} }
#endif #endif
#if !CONFIG_DISABLE_HAL_LOCKS
#define HSERIAL_MUTEX_LOCK() do {} while (xSemaphoreTake(_lock, portMAX_DELAY) != pdPASS)
#define HSERIAL_MUTEX_UNLOCK() xSemaphoreGive(_lock)
#else
#define HSERIAL_MUTEX_LOCK()
#define HSERIAL_MUTEX_UNLOCK()
#endif
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL), _rxBufferSize(256) {} HardwareSerial::HardwareSerial(int uart_nr) :
_uart_nr(uart_nr),
_uart(NULL),
_rxBufferSize(256),
_txBufferSize(0),
_onReceiveCB(NULL),
_onReceiveErrorCB(NULL),
_onReceiveTimeout(true),
_rxTimeout(10),
_eventTask(NULL)
#if !CONFIG_DISABLE_HAL_LOCKS
,_lock(NULL)
#endif
{
#if !CONFIG_DISABLE_HAL_LOCKS
if(_lock == NULL){
_lock = xSemaphoreCreateMutex();
if(_lock == NULL){
log_e("xSemaphoreCreateMutex failed");
return;
}
}
#endif
}
HardwareSerial::~HardwareSerial()
{
end();
#if !CONFIG_DISABLE_HAL_LOCKS
if(_lock != NULL){
vSemaphoreDelete(_lock);
}
#endif
}
void HardwareSerial::_createEventTask(void *args)
{
// Creating UART event Task
xTaskCreate(_uartEventTask, "uart_event_task", 2048, this, configMAX_PRIORITIES - 1, &_eventTask);
if (_eventTask == NULL) {
log_e(" -- UART%d Event Task not Created!", _uart_nr);
}
}
void HardwareSerial::_destroyEventTask(void)
{
if (_eventTask != NULL) {
vTaskDelete(_eventTask);
_eventTask = NULL;
}
}
void HardwareSerial::onReceiveError(OnReceiveErrorCb function)
{
HSERIAL_MUTEX_LOCK();
// function may be NULL to cancel onReceive() from its respective task
_onReceiveErrorCB = function;
// this can be called after Serial.begin(), therefore it shall create the event task
if (function != NULL && _uart != NULL && _eventTask == NULL) {
_createEventTask(this);
}
HSERIAL_MUTEX_UNLOCK();
}
void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout)
{
HSERIAL_MUTEX_LOCK();
// function may be NULL to cancel onReceive() from its respective task
_onReceiveCB = function;
// When Rx timeout is Zero (disabled), there is only one possible option that is callback when FIFO reaches 120 bytes
_onReceiveTimeout = _rxTimeout > 0 ? onlyOnTimeout : false;
// this can be called after Serial.begin(), therefore it shall create the event task
if (function != NULL && _uart != NULL && _eventTask == NULL) {
_createEventTask(this); // Create event task
}
HSERIAL_MUTEX_UNLOCK();
}
// timout is calculates in time to receive UART symbols at the UART baudrate.
// the estimation is about 11 bits per symbol (SERIAL_8N1)
void HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
{
HSERIAL_MUTEX_LOCK();
// Zero disables timeout, thus, onReceive callback will only be called when RX FIFO reaches 120 bytes
// Any non-zero value will activate onReceive callback based on UART baudrate with about 11 bits per symbol
_rxTimeout = symbols_timeout;
if (!symbols_timeout) _onReceiveTimeout = false; // only when RX timeout is disabled, we also must disable this flag
if(_uart != NULL) uart_set_rx_timeout(_uart_nr, _rxTimeout); // Set new timeout
HSERIAL_MUTEX_UNLOCK();
}
void HardwareSerial::eventQueueReset()
{
QueueHandle_t uartEventQueue = NULL;
if (_uart == NULL) {
return;
}
uartGetEventQueue(_uart, &uartEventQueue);
if (uartEventQueue != NULL) {
xQueueReset(uartEventQueue);
}
}
void HardwareSerial::_uartEventTask(void *args)
{
HardwareSerial *uart = (HardwareSerial *)args;
uart_event_t event;
QueueHandle_t uartEventQueue = NULL;
uartGetEventQueue(uart->_uart, &uartEventQueue);
if (uartEventQueue != NULL) {
for(;;) {
//Waiting for UART event.
if(xQueueReceive(uartEventQueue, (void * )&event, (portTickType)portMAX_DELAY)) {
switch(event.type) {
case UART_DATA:
if(uart->_onReceiveCB && uart->available() > 0 &&
((uart->_onReceiveTimeout && event.timeout_flag) || !uart->_onReceiveTimeout) )
uart->_onReceiveCB();
break;
case UART_FIFO_OVF:
log_w("UART%d FIFO Overflow. Consider adding Hardware Flow Control to your Application.", uart->_uart_nr);
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_FIFO_OVF_ERROR);
break;
case UART_BUFFER_FULL:
log_w("UART%d Buffer Full. Consider increasing your buffer size of your Application.", uart->_uart_nr);
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_BUFFER_FULL_ERROR);
break;
case UART_BREAK:
log_w("UART%d RX break.", uart->_uart_nr);
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_BREAK_ERROR);
break;
case UART_PARITY_ERR:
log_w("UART%d parity error.", uart->_uart_nr);
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_PARITY_ERROR);
break;
case UART_FRAME_ERR:
log_w("UART%d frame error.", uart->_uart_nr);
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_FRAME_ERROR);
break;
default:
log_w("UART%d unknown event type %d.", uart->_uart_nr, event.type);
break;
}
}
}
}
vTaskDelete(NULL);
}
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd) void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd)
{ {
@ -115,29 +280,54 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1); log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1);
return; return;
} }
#if !CONFIG_DISABLE_HAL_LOCKS
if(_lock == NULL){
log_e("MUTEX Lock failed. Can't begin.");
return;
}
#endif
HSERIAL_MUTEX_LOCK();
// First Time or after end() --> set default Pins
if (!uartIsDriverInstalled(_uart)) {
switch (_uart_nr) {
case UART_NUM_0:
if (rxPin < 0 && txPin < 0) {
rxPin = SOC_RX0;
txPin = SOC_TX0;
}
break;
#if SOC_UART_NUM > 1 // may save some flash bytes...
case UART_NUM_1:
if (rxPin < 0 && txPin < 0) {
rxPin = RX1;
txPin = TX1;
}
break;
#endif
#if SOC_UART_NUM > 2 // may save some flash bytes...
case UART_NUM_2:
if (rxPin < 0 && txPin < 0) {
rxPin = RX2;
txPin = TX2;
}
break;
#endif
default:
log_e("Bad UART Number");
return;
}
}
if(_uart) { if(_uart) {
// in this case it is a begin() over a previous begin() - maybe to change baud rate // in this case it is a begin() over a previous begin() - maybe to change baud rate
// thus do not disable debug output // thus do not disable debug output
end(false); end(false);
} }
if(_uart_nr == 0 && rxPin < 0 && txPin < 0) {
rxPin = SOC_RX0;
txPin = SOC_TX0;
}
#if SOC_UART_NUM > 1
if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
rxPin = RX1;
txPin = TX1;
}
#endif
#if SOC_UART_NUM > 2
if(_uart_nr == 2 && rxPin < 0 && txPin < 0) {
rxPin = RX2;
txPin = TX2;
}
#endif
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd); // IDF UART driver keeps Pin setting on restarting. Negative Pin number will keep it unmodified.
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, _rxBufferSize, _txBufferSize, invert, rxfifo_full_thrhd);
if (!baud) { if (!baud) {
// using baud rate as zero, forces it to try to detect the current baud rate in place // using baud rate as zero, forces it to try to detect the current baud rate in place
uartStartDetectBaudrate(_uart); uartStartDetectBaudrate(_uart);
@ -151,12 +341,24 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
if(detectedBaudRate) { if(detectedBaudRate) {
delay(100); // Give some time... delay(100); // Give some time...
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd); _uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, _txBufferSize, invert, rxfifo_full_thrhd);
} else { } else {
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible"); log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
_uart = NULL; _uart = NULL;
} }
} }
// create a task to deal with Serial Events when, for example, calling begin() twice to change the baudrate,
// or when setting the callback before calling begin()
if (_uart != NULL && (_onReceiveCB != NULL || _onReceiveErrorCB != NULL) && _eventTask == NULL) {
_createEventTask(this);
}
// Set UART RX timeout
if (_uart != NULL) {
uart_set_rx_timeout(_uart_nr, _rxTimeout);
}
HSERIAL_MUTEX_UNLOCK();
} }
void HardwareSerial::updateBaudRate(unsigned long baud) void HardwareSerial::updateBaudRate(unsigned long baud)
@ -164,14 +366,21 @@ void HardwareSerial::updateBaudRate(unsigned long baud)
uartSetBaudRate(_uart, baud); uartSetBaudRate(_uart, baud);
} }
void HardwareSerial::end(bool turnOffDebug) void HardwareSerial::end(bool fullyTerminate)
{ {
if(turnOffDebug && uartGetDebug() == _uart_nr) { // default Serial.end() will completely disable HardwareSerial,
uartSetDebug(0); // including any tasks or debug message channel (log_x()) - but not for IDF log messages!
if(fullyTerminate) {
_onReceiveCB = NULL;
_onReceiveErrorCB = NULL;
if (uartGetDebug() == _uart_nr) {
uartSetDebug(0);
}
} }
delay(10); delay(10);
uartEnd(_uart); uartEnd(_uart);
_uart = 0; _uart = 0;
_destroyEventTask();
} }
void HardwareSerial::setDebugOutput(bool en) void HardwareSerial::setDebugOutput(bool en)
@ -267,9 +476,16 @@ void HardwareSerial::setRxInvert(bool invert)
uartSetRxInvert(_uart, invert); uartSetRxInvert(_uart, invert);
} }
void HardwareSerial::setPins(uint8_t rxPin, uint8_t txPin) // negative Pin value will keep it unmodified
void HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
{ {
uartSetPins(_uart, rxPin, txPin); uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin);
}
// Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
void HardwareSerial::setHwFlowCtrlMode(uint8_t mode, uint8_t threshold)
{
uartSetHwFlowCtrlMode(_uart, mode, threshold);
} }
size_t HardwareSerial::setRxBufferSize(size_t new_size) { size_t HardwareSerial::setRxBufferSize(size_t new_size) {
@ -280,10 +496,26 @@ size_t HardwareSerial::setRxBufferSize(size_t new_size) {
} }
if (new_size <= SOC_UART_FIFO_LEN) { if (new_size <= SOC_UART_FIFO_LEN) {
log_e("RX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN); log_e("RX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN); // ESP32, S2, S3 and C3 means higher than 128
return 0; return 0;
} }
_rxBufferSize = new_size; _rxBufferSize = new_size;
return _rxBufferSize; return _rxBufferSize;
} }
size_t HardwareSerial::setTxBufferSize(size_t new_size) {
if (_uart) {
log_e("TX Buffer can't be resized when Serial is already running.\n");
return 0;
}
if (new_size <= SOC_UART_FIFO_LEN) {
log_e("TX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN); // ESP32, S2, S3 and C3 means higher than 128
return 0;
}
_txBufferSize = new_size;
return _txBufferSize;
}

View File

@ -46,19 +46,61 @@
#define HardwareSerial_h #define HardwareSerial_h
#include <inttypes.h> #include <inttypes.h>
#include <functional>
#include "Stream.h" #include "Stream.h"
#include "esp32-hal.h" #include "esp32-hal.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "HWCDC.h" #include "HWCDC.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
typedef enum {
UART_BREAK_ERROR,
UART_BUFFER_FULL_ERROR,
UART_FIFO_OVF_ERROR,
UART_FRAME_ERROR,
UART_PARITY_ERROR
} hardwareSerial_error_t;
typedef std::function<void(void)> OnReceiveCb;
typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb;
class HardwareSerial: public Stream class HardwareSerial: public Stream
{ {
public: public:
HardwareSerial(int uart_nr); HardwareSerial(int uart_nr);
~HardwareSerial();
// setRxTimeout sets the timeout after which onReceive callback will be called (after receiving data, it waits for this time of UART rx inactivity to call the callback fnc)
// param symbols_timeout defines a timeout threshold in uart symbol periods. Setting 0 symbol timeout disables the callback call by timeout.
// Maximum timeout setting is calculacted automatically by IDF. If set above the maximum, it is ignored and an error is printed on Serial0 (check console).
// Examples: Maximum for 11 bits symbol is 92 (SERIAL_8N2, SERIAL_8E1, SERIAL_8O1, etc), Maximum for 10 bits symbol is 101 (SERIAL_8N1).
// For example symbols_timeout=1 defines a timeout equal to transmission time of one symbol (~11 bit) on current baudrate.
// For a baudrate of 9600, SERIAL_8N1 (10 bit symbol) and symbols_timeout = 3, the timeout would be 3 / (9600 / 10) = 3.125 ms
void setRxTimeout(uint8_t symbols_timeout);
// onReceive will setup a callback that will be called whenever an UART interruption occurs (UART_INTR_RXFIFO_FULL or UART_INTR_RXFIFO_TOUT)
// UART_INTR_RXFIFO_FULL interrupt triggers at UART_FULL_THRESH_DEFAULT bytes received (defined as 120 bytes by default in IDF)
// UART_INTR_RXFIFO_TOUT interrupt triggers at UART_TOUT_THRESH_DEFAULT symbols passed without any reception (defined as 10 symbos by default in IDF)
// onlyOnTimeout parameter will define how onReceive will behave:
// Default: true -- The callback will only be called when RX Timeout happens.
// Whole stream of bytes will be ready for being read on the callback function at once.
// This option may lead to Rx Overflow depending on the Rx Buffer Size and number of bytes received in the streaming
// false -- The callback will be called when FIFO reaches 120 bytes and also on RX Timeout.
// The stream of incommig bytes will be "split" into blocks of 120 bytes on each callback.
// This option avoid any sort of Rx Overflow, but leaves the UART packet reassembling work to the Application.
void onReceive(OnReceiveCb function, bool onlyOnTimeout = true);
// onReceive will be called on error events (see hardwareSerial_error_t)
void onReceiveError(OnReceiveErrorCb function);
// eventQueueReset clears all events in the queue (the events that trigger onReceive and onReceiveError) - maybe usefull in some use cases
void eventQueueReset();
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112); void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);
void end(bool turnOffDebug = true); void end(bool fullyTerminate = true);
void updateBaudRate(unsigned long baud); void updateBaudRate(unsigned long baud);
int available(void); int available(void);
int availableForWrite(void); int availableForWrite(void);
@ -103,13 +145,34 @@ public:
void setDebugOutput(bool); void setDebugOutput(bool);
void setRxInvert(bool); void setRxInvert(bool);
void setPins(uint8_t rxPin, uint8_t txPin);
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
// SetPins shall be called after Serial begin()
void setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin = -1, int8_t rtsPin = -1);
// Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
void setHwFlowCtrlMode(uint8_t mode = HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64); // 64 is half FIFO Length
size_t setRxBufferSize(size_t new_size); size_t setRxBufferSize(size_t new_size);
size_t setTxBufferSize(size_t new_size);
protected: protected:
int _uart_nr; int _uart_nr;
uart_t* _uart; uart_t* _uart;
size_t _rxBufferSize; size_t _rxBufferSize;
size_t _txBufferSize;
OnReceiveCb _onReceiveCB;
OnReceiveErrorCb _onReceiveErrorCB;
// _onReceive and _rxTimeout have be consistent when timeout is disabled
bool _onReceiveTimeout;
uint8_t _rxTimeout;
TaskHandle_t _eventTask;
#if !CONFIG_DISABLE_HAL_LOCKS
SemaphoreHandle_t _lock;
#endif
void _createEventTask(void *args);
void _destroyEventTask(void);
static void _uartEventTask(void *args);
}; };
extern void serialEventRun(void) __attribute__((weak)); extern void serialEventRun(void) __attribute__((weak));
@ -119,10 +182,10 @@ extern void serialEventRun(void) __attribute__((weak));
#define ARDUINO_USB_CDC_ON_BOOT 0 #define ARDUINO_USB_CDC_ON_BOOT 0
#endif #endif
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC #if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
#if !ARDUINO_USB_MODE
#include "USB.h" #include "USB.h"
#include "USBCDC.h" #include "USBCDC.h"
extern HardwareSerial Serial0; #endif
#elif ARDUINO_HW_CDC_ON_BOOT
extern HardwareSerial Serial0; extern HardwareSerial Serial0;
#else #else
extern HardwareSerial Serial; extern HardwareSerial Serial;

View File

@ -120,3 +120,6 @@ bool IPAddress::fromString(const char *address)
_address.bytes[3] = acc; _address.bytes[3] = acc;
return true; return true;
} }
// declared one time - as external in IPAddress.h
IPAddress INADDR_NONE(0, 0, 0, 0);

View File

@ -91,6 +91,6 @@ public:
friend class DNSClient; friend class DNSClient;
}; };
const IPAddress INADDR_NONE(0, 0, 0, 0); // changed to extern because const declaration creates copies in BSS of INADDR_NONE for each CPP unit that includes it
extern IPAddress INADDR_NONE;
#endif #endif

View File

@ -19,7 +19,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <MD5Builder.h> #include <MD5Builder.h>
uint8_t hex_char_to_byte(uint8_t c) static uint8_t hex_char_to_byte(uint8_t c)
{ {
return (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) : return (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) :
(c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) : (c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) :
@ -28,13 +28,13 @@ uint8_t hex_char_to_byte(uint8_t c)
void MD5Builder::begin(void) void MD5Builder::begin(void)
{ {
memset(_buf, 0x00, 16); memset(_buf, 0x00, ESP_ROM_MD5_DIGEST_LEN);
MD5Init(&_ctx); esp_rom_md5_init(&_ctx);
} }
void MD5Builder::add(uint8_t * data, uint16_t len) void MD5Builder::add(uint8_t * data, uint16_t len)
{ {
MD5Update(&_ctx, data, len); esp_rom_md5_update(&_ctx, data, len);
} }
void MD5Builder::addHexString(const char * data) void MD5Builder::addHexString(const char * data)
@ -82,7 +82,7 @@ bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
} }
// Update MD5 with buffer payload // Update MD5 with buffer payload
MD5Update(&_ctx, buf, numBytesRead); esp_rom_md5_update(&_ctx, buf, numBytesRead);
// update available number of bytes // update available number of bytes
maxLengthLeft -= numBytesRead; maxLengthLeft -= numBytesRead;
@ -94,24 +94,24 @@ bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
void MD5Builder::calculate(void) void MD5Builder::calculate(void)
{ {
MD5Final(_buf, &_ctx); esp_rom_md5_final(_buf, &_ctx);
} }
void MD5Builder::getBytes(uint8_t * output) void MD5Builder::getBytes(uint8_t * output)
{ {
memcpy(output, _buf, 16); memcpy(output, _buf, ESP_ROM_MD5_DIGEST_LEN);
} }
void MD5Builder::getChars(char * output) void MD5Builder::getChars(char * output)
{ {
for(uint8_t i = 0; i < 16; i++) { for(uint8_t i = 0; i < ESP_ROM_MD5_DIGEST_LEN; i++) {
sprintf(output + (i * 2), "%02x", _buf[i]); sprintf(output + (i * 2), "%02x", _buf[i]);
} }
} }
String MD5Builder::toString(void) String MD5Builder::toString(void)
{ {
char out[33]; char out[(ESP_ROM_MD5_DIGEST_LEN * 2) + 1];
getChars(out); getChars(out);
return String(out); return String(out);
} }

View File

@ -23,25 +23,13 @@
#include <Stream.h> #include <Stream.h>
#include "esp_system.h" #include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ #include "esp_rom_md5.h"
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/md5_hash.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/md5_hash.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/md5_hash.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/md5_hash.h"
#endif
class MD5Builder class MD5Builder
{ {
private: private:
struct MD5Context _ctx; md5_context_t _ctx;
uint8_t _buf[16]; uint8_t _buf[ESP_ROM_MD5_DIGEST_LEN];
public: public:
void begin(void); void begin(void);
void add(uint8_t * data, uint16_t len); void add(uint8_t * data, uint16_t len);

View File

@ -108,6 +108,9 @@ public:
size_t println(const Printable&); size_t println(const Printable&);
size_t println(struct tm * timeinfo, const char * format = NULL); size_t println(struct tm * timeinfo, const char * format = NULL);
size_t println(void); size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ }
}; };
#endif #endif

View File

@ -48,7 +48,6 @@ public:
virtual int available() = 0; virtual int available() = 0;
virtual int read() = 0; virtual int read() = 0;
virtual int peek() = 0; virtual int peek() = 0;
virtual void flush() = 0;
Stream():_startMillis(0) Stream():_startMillis(0)
{ {

131
cores/esp32/Tone.cpp Normal file
View File

@ -0,0 +1,131 @@
#include <Arduino.h>
#include "esp32-hal-ledc.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
static TaskHandle_t _tone_task = NULL;
static QueueHandle_t _tone_queue = NULL;
static uint8_t _channel = 0;
typedef enum{
TONE_START,
TONE_END,
TONE_SET_CHANNEL
} tone_cmd_t;
typedef struct{
tone_cmd_t tone_cmd;
uint8_t pin;
unsigned int frequency;
unsigned long duration;
uint8_t channel;
} tone_msg_t;
static void tone_task(void*){
tone_msg_t tone_msg;
while(1){
xQueueReceive(_tone_queue, &tone_msg, portMAX_DELAY);
switch(tone_msg.tone_cmd){
case TONE_START:
log_d("Task received from queue TONE_START: _pin=%d, frequency=%u Hz, duration=%u ms", tone_msg.pin, tone_msg.frequency, tone_msg.duration);
log_d("Setup LED controll on channel %d", _channel);
// ledcSetup(_channel, tone_msg.frequency, 11);
// ledcAttachPin(tone_msg.pin, _channel);
// ledcWrite(_channel, 1024);
ledcWriteTone(_channel, tone_msg.frequency);
ledcAttachPin(tone_msg.pin, _channel);
if(tone_msg.duration){
delay(tone_msg.duration);
ledcDetachPin(tone_msg.pin);
ledcWriteTone(_channel, 0);
}
break;
case TONE_END:
log_d("Task received from queue TONE_END: pin=%d", tone_msg.pin);
ledcDetachPin(tone_msg.pin);
ledcWriteTone(_channel, 0);
break;
case TONE_SET_CHANNEL:
log_d("Task received from queue TONE_SET_CHANNEL: channel=%d", tone_msg.channel);
_channel = tone_msg.channel;
break;
default: ; // do nothing
} // switch
} // infinite loop
}
static int tone_init(){
if(_tone_queue == NULL){
log_v("Creating tone queue");
_tone_queue = xQueueCreate(128, sizeof(tone_msg_t));
if(_tone_queue == NULL){
log_e("Could not create tone queue");
return 0; // ERR
}
log_v("Tone queue created");
}
if(_tone_task == NULL){
log_v("Creating tone task");
xTaskCreate(
tone_task, // Function to implement the task
"toneTask", // Name of the task
3500, // Stack size in words
NULL, // Task input parameter
1, // Priority of the task
&_tone_task // Task handle.
);
if(_tone_task == NULL){
log_e("Could not create tone task");
return 0; // ERR
}
log_v("Tone task created");
}
return 1; // OK
}
void setToneChannel(uint8_t channel){
log_d("channel=%d", channel);
if(tone_init()){
tone_msg_t tone_msg = {
.tone_cmd = TONE_SET_CHANNEL,
.channel = channel
};
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
}
}
void noTone(uint8_t _pin){
log_d("noTone was called");
if(tone_init()){
tone_msg_t tone_msg = {
.tone_cmd = TONE_END,
.pin = _pin
};
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
}
}
// parameters:
// _pin - pin number which will output the signal
// frequency - PWM frequency in Hz
// duration - time in ms - how long will the signal be outputted.
// If not provided, or 0 you must manually call noTone to end output
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration){
log_d("_pin=%d, frequency=%u Hz, duration=%u ms", _pin, frequency, duration);
if(tone_init()){
tone_msg_t tone_msg = {
.tone_cmd = TONE_START,
.pin = _pin,
.frequency = frequency,
.duration = duration
};
xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY);
}
}

View File

@ -19,6 +19,7 @@
#include "esp32-hal.h" #include "esp32-hal.h"
#include "esp32-hal-tinyusb.h" #include "esp32-hal-tinyusb.h"
#include "common/tusb_common.h" #include "common/tusb_common.h"
#include "StreamString.h"
#ifndef USB_VID #ifndef USB_VID
#define USB_VID USB_ESPRESSIF_VID #define USB_VID USB_ESPRESSIF_VID
@ -33,8 +34,12 @@
#define USB_PRODUCT ARDUINO_BOARD #define USB_PRODUCT ARDUINO_BOARD
#endif #endif
#ifndef USB_SERIAL #ifndef USB_SERIAL
#if CONFIG_IDF_TARGET_ESP32S3
#define USB_SERIAL "__MAC__"
#else
#define USB_SERIAL "0" #define USB_SERIAL "0"
#endif #endif
#endif
#ifndef USB_WEBUSB_ENABLED #ifndef USB_WEBUSB_ENABLED
#define USB_WEBUSB_ENABLED false #define USB_WEBUSB_ENABLED false
#endif #endif
@ -155,6 +160,15 @@ ESPUSB::~ESPUSB(){
bool ESPUSB::begin(){ bool ESPUSB::begin(){
if(!_started){ if(!_started){
#if CONFIG_IDF_TARGET_ESP32S3
if(serial_number == "__MAC__"){
StreamString s;
uint8_t m[6];
esp_efuse_mac_get_default(m);
s.printf("%02X:%02X:%02X:%02X:%02X:%02X", m[0], m[1], m[2], m[3], m[4], m[5]);
serial_number = s;
}
#endif
tinyusb_device_config_t tinyusb_device_config = { tinyusb_device_config_t tinyusb_device_config = {
.vid = vid, .vid = vid,
.pid = pid, .pid = pid,

View File

@ -114,16 +114,42 @@ void USBCDC::onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback
} }
size_t USBCDC::setRxBufferSize(size_t rx_queue_len){ size_t USBCDC::setRxBufferSize(size_t rx_queue_len){
if(rx_queue){ size_t currentQueueSize = rx_queue ?
if(!rx_queue_len){ uxQueueSpacesAvailable(rx_queue) + uxQueueMessagesWaiting(rx_queue) : 0;
vQueueDelete(rx_queue);
rx_queue = NULL; if (rx_queue_len != currentQueueSize) {
xQueueHandle new_rx_queue = NULL;
if (rx_queue_len) {
new_rx_queue = xQueueCreate(rx_queue_len, sizeof(uint8_t));
if(!new_rx_queue){
log_e("CDC Queue creation failed.");
return 0;
}
if (rx_queue) {
size_t copySize = uxQueueMessagesWaiting(rx_queue);
if (copySize > 0) {
for(size_t i = 0; i < copySize; i++) {
uint8_t ch = 0;
xQueueReceive(rx_queue, &ch, 0);
if (!xQueueSend(new_rx_queue, &ch, 0)) {
arduino_usb_cdc_event_data_t p;
p.rx_overflow.dropped_bytes = copySize - i;
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_OVERFLOW_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
log_e("CDC RX Overflow.");
break;
}
}
}
vQueueDelete(rx_queue);
}
rx_queue = new_rx_queue;
return rx_queue_len;
} else {
if (rx_queue) {
vQueueDelete(rx_queue);
rx_queue = NULL;
}
} }
return 0;
}
rx_queue = xQueueCreate(rx_queue_len, sizeof(uint8_t));
if(!rx_queue){
return 0;
} }
return rx_queue_len; return rx_queue_len;
} }
@ -133,7 +159,8 @@ void USBCDC::begin(unsigned long baud)
if(tx_lock == NULL) { if(tx_lock == NULL) {
tx_lock = xSemaphoreCreateMutex(); tx_lock = xSemaphoreCreateMutex();
} }
setRxBufferSize(256);//default if not preset // if rx_queue was set before begin(), keep it
if (!rx_queue) setRxBufferSize(256); //default if not preset
devices[itf] = this; devices[itf] = this;
} }
@ -144,6 +171,7 @@ void USBCDC::end()
setRxBufferSize(0); setRxBufferSize(0);
if(tx_lock != NULL) { if(tx_lock != NULL) {
vSemaphoreDelete(tx_lock); vSemaphoreDelete(tx_lock);
tx_lock = NULL;
} }
} }
@ -244,16 +272,22 @@ void USBCDC::_onLineCoding(uint32_t _bit_rate, uint8_t _stop_bits, uint8_t _pari
} }
void USBCDC::_onRX(){ void USBCDC::_onRX(){
arduino_usb_cdc_event_data_t p;
uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE+1]; uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE+1];
uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE); uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE);
for(uint32_t i=0; i<count; i++){ for(uint32_t i=0; i<count; i++){
if(rx_queue == NULL || !xQueueSend(rx_queue, buf+i, 0)){ if(rx_queue == NULL || !xQueueSend(rx_queue, buf+i, 10)) {
return; p.rx_overflow.dropped_bytes = count - i;
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_OVERFLOW_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
log_e("CDC RX Overflow.");
count = i;
break;
} }
} }
arduino_usb_cdc_event_data_t p; if (count) {
p.rx.len = count; p.rx.len = count;
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY); arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
}
} }
void USBCDC::_onTX(){ void USBCDC::_onTX(){
@ -412,7 +446,7 @@ USBCDC::operator bool() const
return connected; return connected;
} }
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC #if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE //Serial used for USB CDC
USBCDC Serial(0); USBCDC Serial(0);
#endif #endif

View File

@ -33,6 +33,7 @@ typedef enum {
ARDUINO_USB_CDC_LINE_CODING_EVENT, ARDUINO_USB_CDC_LINE_CODING_EVENT,
ARDUINO_USB_CDC_RX_EVENT, ARDUINO_USB_CDC_RX_EVENT,
ARDUINO_USB_CDC_TX_EVENT, ARDUINO_USB_CDC_TX_EVENT,
ARDUINO_USB_CDC_RX_OVERFLOW_EVENT,
ARDUINO_USB_CDC_MAX_EVENT, ARDUINO_USB_CDC_MAX_EVENT,
} arduino_usb_cdc_event_t; } arduino_usb_cdc_event_t;
@ -50,6 +51,9 @@ typedef union {
struct { struct {
size_t len; size_t len;
} rx; } rx;
struct {
size_t dropped_bytes;
} rx_overflow;
} arduino_usb_cdc_event_data_t; } arduino_usb_cdc_event_data_t;
class USBCDC: public Stream class USBCDC: public Stream
@ -134,7 +138,7 @@ protected:
}; };
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC #if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE //Serial used for USB CDC
extern USBCDC Serial; extern USBCDC Serial;
#endif #endif

View File

@ -67,14 +67,14 @@ long random(long howsmall, long howbig)
} }
long map(long x, long in_min, long in_max, long out_min, long out_max) { long map(long x, long in_min, long in_max, long out_min, long out_max) {
const long dividend = out_max - out_min; const long run = in_max - in_min;
const long divisor = in_max - in_min; if(run == 0){
const long delta = x - in_min; log_e("map(): Invalid input range, min == max");
if(divisor == 0){ return -1; // AVR returns -1, SAM returns 0
log_e("Invalid map input range, min == max");
return -1; //AVR returns -1, SAM returns 0
} }
return (delta * dividend + (divisor / 2)) / divisor + out_min; const long rise = out_max - out_min;
const long delta = x - in_min;
return (delta * rise) / run + out_min;
} }
uint16_t makeWord(uint16_t w) uint16_t makeWord(uint16_t w)

View File

@ -24,6 +24,7 @@
#include <Arduino.h> #include <Arduino.h>
#include "WString.h" #include "WString.h"
#include "stdlib_noniso.h" #include "stdlib_noniso.h"
#include "esp32-hal-log.h"
/*********************************************/ /*********************************************/
/* Constructors */ /* Constructors */
@ -112,16 +113,28 @@ String::String(unsigned long value, unsigned char base) {
*this = buf; *this = buf;
} }
String::String(float value, unsigned char decimalPlaces) { String::String(float value, unsigned int decimalPlaces) {
init(); init();
char buf[33]; char *buf = (char*)malloc(decimalPlaces + 42);
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); if (buf) {
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
free(buf);
} else {
*this = "nan";
log_e("No enought memory for the operation.");
}
} }
String::String(double value, unsigned char decimalPlaces) { String::String(double value, unsigned int decimalPlaces) {
init(); init();
char buf[33]; char *buf = (char*)malloc(decimalPlaces + 312);
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); if (buf) {
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
free(buf);
} else {
*this = "nan";
log_e("No enought memory for the operation.");
}
} }
String::~String() { String::~String() {
@ -761,8 +774,10 @@ void String::replace(const String& find, const String& replace) {
} }
if(size == len()) if(size == len())
return; return;
if(size > capacity() && !changeBuffer(size)) if(size > capacity() && !changeBuffer(size)) {
return; // XXX: tell user! log_w("String.Replace() Insufficient space to replace string");
return;
}
int index = len() - 1; int index = len() - 1;
while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) { while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = wbuffer() + index + find.len(); readFrom = wbuffer() + index + find.len();

View File

@ -71,8 +71,8 @@ class String {
explicit String(unsigned int, unsigned char base = 10); explicit String(unsigned int, unsigned char base = 10);
explicit String(long, unsigned char base = 10); explicit String(long, unsigned char base = 10);
explicit String(unsigned long, unsigned char base = 10); explicit String(unsigned long, unsigned char base = 10);
explicit String(float, unsigned char decimalPlaces = 2); explicit String(float, unsigned int decimalPlaces = 2);
explicit String(double, unsigned char decimalPlaces = 2); explicit String(double, unsigned int decimalPlaces = 2);
~String(void); ~String(void);
// memory management // memory management

View File

@ -62,7 +62,7 @@ public:
cbuf *next; cbuf *next;
private: protected:
inline char* wrap_if_bufend(char* ptr) const inline char* wrap_if_bufend(char* ptr) const
{ {
return (ptr == _bufend) ? _buf : ptr; return (ptr == _bufend) ? _buf : ptr;

View File

@ -27,6 +27,7 @@
#include "soc/rtc_io_reg.h" #include "soc/rtc_io_reg.h"
#include "esp32/rom/ets_sys.h" #include "esp32/rom/ets_sys.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "soc/dac_channel.h"
#define DEFAULT_VREF 1100 #define DEFAULT_VREF 1100
static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL}; static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL};
static uint16_t __analogVRef = 0; static uint16_t __analogVRef = 0;
@ -35,6 +36,11 @@ static uint8_t __analogVRefPin = 0;
#include "esp32s2/rom/ets_sys.h" #include "esp32s2/rom/ets_sys.h"
#include "soc/sens_reg.h" #include "soc/sens_reg.h"
#include "soc/rtc_io_reg.h" #include "soc/rtc_io_reg.h"
#include "soc/dac_channel.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/ets_sys.h"
#include "soc/sens_reg.h"
#include "soc/rtc_io_reg.h"
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/ets_sys.h" #include "esp32c3/rom/ets_sys.h"
#else #else
@ -141,10 +147,10 @@ bool __adcAttachPin(uint8_t pin){
} }
#endif #endif
} }
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #if SOC_DAC_SUPPORTED
else if(pin == 25){ else if(pin == DAC_CHANNEL_1_GPIO_NUM){
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);//stop dac1 CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);//stop dac1
} else if(pin == 26){ } else if(pin == DAC_CHANNEL_2_GPIO_NUM){
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);//stop dac2 CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);//stop dac2
} }
#endif #endif

View File

@ -33,6 +33,9 @@
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
#include "freertos/xtensa_timer.h" #include "freertos/xtensa_timer.h"
#include "esp32s2/rom/rtc.h" #include "esp32s2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "freertos/xtensa_timer.h"
#include "esp32s3/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/rtc.h" #include "esp32c3/rom/rtc.h"
#else #else
@ -144,7 +147,7 @@ bool removeApbChangeCallback(void * arg, apb_change_cb_t cb){
} }
static uint32_t calculateApb(rtc_cpu_freq_config_t * conf){ static uint32_t calculateApb(rtc_cpu_freq_config_t * conf){
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
return APB_CLK_FREQ; return APB_CLK_FREQ;
#else #else
if(conf->freq_mhz >= 80){ if(conf->freq_mhz >= 80){
@ -228,6 +231,8 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
//Update FreeRTOS Tick Divisor //Update FreeRTOS Tick Divisor
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3
#elif CONFIG_IDF_TARGET_ESP32S3
#else #else
uint32_t fcpu = (conf.freq_mhz >= 80)?(conf.freq_mhz * MHZ):(apb); uint32_t fcpu = (conf.freq_mhz >= 80)?(conf.freq_mhz * MHZ):(apb);
_xt_tick_divisor = fcpu / XT_TICK_PER_SEC; _xt_tick_divisor = fcpu / XT_TICK_PER_SEC;

View File

@ -13,51 +13,37 @@
// limitations under the License. // limitations under the License.
#include "esp32-hal.h" #include "esp32-hal.h"
#include "soc/soc_caps.h"
#if CONFIG_IDF_TARGET_ESP32 #ifndef SOC_DAC_SUPPORTED
#include "soc/rtc_io_reg.h"
#define DAC1 25
#define DAC2 26
#elif CONFIG_IDF_TARGET_ESP32S2
#include "soc/rtc_io_reg.h"
#define DAC1 17
#define DAC2 18
#elif CONFIG_IDF_TARGET_ESP32C3
#define NODAC #define NODAC
#else #else
#error Target CONFIG_IDF_TARGET is not supported #include "soc/dac_channel.h"
#endif #include "driver/dac_common.h"
#ifndef NODAC
#include "esp_attr.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_periph.h"
#include "soc/sens_reg.h"
#include "soc/sens_struct.h"
#include "driver/dac.h"
void ARDUINO_ISR_ATTR __dacWrite(uint8_t pin, uint8_t value) void ARDUINO_ISR_ATTR __dacWrite(uint8_t pin, uint8_t value)
{ {
if(pin < DAC1 || pin > DAC2){ if(pin < DAC_CHANNEL_1_GPIO_NUM || pin > DAC_CHANNEL_2_GPIO_NUM){
return;//not dac pin return;//not dac pin
} }
pinMode(pin, ANALOG);
uint8_t channel = pin - DAC1; uint8_t channel = pin - DAC_CHANNEL_1_GPIO_NUM;
#if CONFIG_IDF_TARGET_ESP32 dac_output_enable(channel);
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN); dac_output_voltage(channel, value);
#elif CONFIG_IDF_TARGET_ESP32S2
SENS.sar_dac_ctrl1.dac_clkgate_en = 1; }
#endif
RTCIO.pad_dac[channel].dac_xpd_force = 1; void ARDUINO_ISR_ATTR __dacDisable(uint8_t pin)
RTCIO.pad_dac[channel].xpd_dac = 1; {
if (channel == 0) { if(pin < DAC_CHANNEL_1_GPIO_NUM || pin > DAC_CHANNEL_2_GPIO_NUM){
SENS.sar_dac_ctrl2.dac_cw_en1 = 0; return;//not dac pin
} else if (channel == 1) {
SENS.sar_dac_ctrl2.dac_cw_en2 = 0;
} }
RTCIO.pad_dac[channel].dac = value;
uint8_t channel = pin - DAC_CHANNEL_1_GPIO_NUM;
dac_output_disable(channel);
} }
extern void dacWrite(uint8_t pin, uint8_t value) __attribute__ ((weak, alias("__dacWrite"))); extern void dacWrite(uint8_t pin, uint8_t value) __attribute__ ((weak, alias("__dacWrite")));
extern void dacDisable(uint8_t pin) __attribute__ ((weak, alias("__dacDisable")));
#endif #endif

View File

@ -28,6 +28,7 @@ extern "C" {
#include "driver/gpio.h" #include "driver/gpio.h"
void dacWrite(uint8_t pin, uint8_t value); void dacWrite(uint8_t pin, uint8_t value);
void dacDisable(uint8_t pin);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -13,138 +13,70 @@
// limitations under the License. // limitations under the License.
#include "esp32-hal-gpio.h" #include "esp32-hal-gpio.h"
#include "pins_arduino.h" #include "hal/gpio_hal.h"
#include "freertos/FreeRTOS.h" #include "soc/soc_caps.h"
#include "freertos/task.h"
#include "esp_attr.h"
#include "soc/gpio_reg.h"
#include "soc/io_mux_reg.h"
#include "soc/gpio_struct.h"
#include "driver/gpio.h"
#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ // It fixes lack of pin definition for S3 and for any future SoC
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 // this function works for ESP32, ESP32-S2 and ESP32-S3 - including the C3, it will return -1 for any pin
#include "esp32/rom/ets_sys.h" #if SOC_TOUCH_SENSOR_NUM > 0
#include "esp32/rom/gpio.h" #include "soc/touch_sensor_periph.h"
#include "esp_intr_alloc.h"
#include "soc/rtc_io_reg.h" int8_t digitalPinToTouchChannel(uint8_t pin)
#define GPIO_FUNC 2 {
#elif CONFIG_IDF_TARGET_ESP32S2 int8_t ret = -1;
#include "esp32s2/rom/ets_sys.h" if (pin < SOC_GPIO_PIN_COUNT) {
#include "esp32s2/rom/gpio.h" for (uint8_t i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
#include "esp_intr_alloc.h" if (touch_sensor_channel_io_map[i] == pin) {
#include "soc/periph_defs.h" ret = i;
#include "soc/rtc_io_reg.h" break;
#define GPIO_FUNC 1 }
#else }
#define USE_ESP_IDF_GPIO 1 }
#endif return ret;
#else // ESP32 Before IDF 4.0 }
#include "rom/ets_sys.h" #else
#include "rom/gpio.h" // No Touch Sensor available
#include "esp_intr.h" int8_t digitalPinToTouchChannel(uint8_t pin)
{
return -1;
}
#endif #endif
#if CONFIG_IDF_TARGET_ESP32 #ifdef SOC_ADC_SUPPORTED
const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26}; #include "soc/adc_periph.h"
#elif CONFIG_IDF_TARGET_ESP32S2
const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
#endif
const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT]={ int8_t digitalPinToAnalogChannel(uint8_t pin)
#if CONFIG_IDF_TARGET_ESP32 {
{0x44, 11, 11, 1}, uint8_t channel = 0;
{0x88, -1, -1, -1}, if (pin < SOC_GPIO_PIN_COUNT) {
{0x40, 12, 12, 2}, for (uint8_t i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
{0x84, -1, -1, -1}, for (uint8_t j = 0; j < SOC_ADC_MAX_CHANNEL_NUM; j++) {
{0x48, 10, 10, 0}, if (adc_channel_io_map[i][j] == pin) {
{0x6c, -1, -1, -1}, return channel;
{0x60, -1, -1, -1}, }
{0x64, -1, -1, -1}, channel++;
{0x68, -1, -1, -1}, }
{0x54, -1, -1, -1}, }
{0x58, -1, -1, -1}, }
{0x5c, -1, -1, -1}, return -1;
{0x34, 15, 15, 5}, }
{0x38, 14, 14, 4},
{0x30, 16, 16, 6}, int8_t analogChannelToDigitalPin(uint8_t channel)
{0x3c, 13, 13, 3}, {
{0x4c, -1, -1, -1}, if (channel >= (SOC_ADC_PERIPH_NUM * SOC_ADC_MAX_CHANNEL_NUM)) {
{0x50, -1, -1, -1}, return -1;
{0x70, -1, -1, -1}, }
{0x74, -1, -1, -1}, uint8_t adc_unit = (channel / SOC_ADC_MAX_CHANNEL_NUM);
{0x78, -1, -1, -1}, uint8_t adc_chan = (channel % SOC_ADC_MAX_CHANNEL_NUM);
{0x7c, -1, -1, -1}, return adc_channel_io_map[adc_unit][adc_chan];
{0x80, -1, -1, -1}, }
{0x8c, -1, -1, -1}, #else
{0, -1, -1, -1}, // No Analog channels availible
{0x24, 6, 18, -1}, //DAC1 int8_t analogChannelToDigitalPin(uint8_t channel)
{0x28, 7, 19, -1}, //DAC2 {
{0x2c, 17, 17, 7}, return -1;
{0, -1, -1, -1}, }
{0, -1, -1, -1},
{0, -1, -1, -1},
{0, -1, -1, -1},
{0x1c, 9, 4, 8},
{0x20, 8, 5, 9},
{0x14, 4, 6, -1},
{0x18, 5, 7, -1},
{0x04, 0, 0, -1},
{0x08, 1, 1, -1},
{0x0c, 2, 2, -1},
{0x10, 3, 3, -1}
#elif CONFIG_IDF_TARGET_ESP32S2
{0x04, 0, -1, -1},
{0x08, 1, 0, 1},
{0x0c, 2, 1, 2},
{0x10, 3, 2, 3},
{0x14, 4, 3, 4},
{0x18, 5, 4, 5},
{0x1c, 6, 5, 6},
{0x20, 7, 6, 7},
{0x24, 8, 7, 8},
{0x28, 9, 8, 9},//FSPI_HD
{0x2c, 10, 9, 10},//FSPI_CS0 / FSPI_D4
{0x30, 11, 10, 11},//FSPI_D / FSPI_D5
{0x34, 12, 11, 12},//FSPI_CLK / FSPI_D6
{0x38, 13, 12, 13},//FSPI_Q / FSPI_D7
{0x3c, 14, 13, 14},//FSPI_WP / FSPI_DQS
{0x40, 15, 14, -1},//32K+ / RTS0
{0x44, 16, 15, -1},//32K- / CTS0
{0x48, 17, 16, -1},//DAC1 / TXD1
{0x4c, 18, 17, -1},//DAC2 / RXD1
{0x50, 19, 18, -1},//USB D- / RTS1
{0x54, 20, 19, -1},//USB D+ / CTS1
{0x58, 21, -1, -1},//SDA?
{ 0, -1, -1, -1},//UNAVAILABLE
{ 0, -1, -1, -1},//UNAVAILABLE
{ 0, -1, -1, -1},//UNAVAILABLE
{ 0, -1, -1, -1},//UNAVAILABLE
{0x6c, -1, -1, -1},//RESERVED SPI_CS1
{0x70, -1, -1, -1},//RESERVED SPI_HD
{0x74, -1, -1, -1},//RESERVED SPI_WP
{0x78, -1, -1, -1},//RESERVED SPI_CS0
{0x7c, -1, -1, -1},//RESERVED SPI_CLK
{0x80, -1, -1, -1},//RESERVED SPI_Q
{0x84, -1, -1, -1},//RESERVED SPI_D
{0x88, -1, -1, -1},//FSPI_HD
{0x8c, -1, -1, -1},//FSPI_CS0
{0x90, -1, -1, -1},//FSPI_D
{0x94, -1, -1, -1},//FSPI_CLK
{0x98, -1, -1, -1},//FSPI_Q
{0x9c, -1, -1, -1},//FSPI_WP
{0xa0, -1, -1, -1},//MTCK
{0xa4, -1, -1, -1},//MTDO
{0xa8, -1, -1, -1},//MTDI
{0xac, -1, -1, -1},//MTMS
{0xb0, -1, -1, -1},//TXD0
{0xb4, -1, -1, -1},//RXD0
{0xb8, -1, -1, -1},//SCL?
{0xbc, -1, -1, -1},//INPUT ONLY
{0, -1, -1, -1}
#endif #endif
};
typedef void (*voidFuncPtr)(void); typedef void (*voidFuncPtr)(void);
typedef void (*voidFuncPtrArg)(void*); typedef void (*voidFuncPtrArg)(void*);
@ -159,8 +91,8 @@ static InterruptHandle_t __pinInterruptHandlers[SOC_GPIO_PIN_COUNT] = {0,};
extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode) extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
{ {
#if USE_ESP_IDF_GPIO
if (!GPIO_IS_VALID_GPIO(pin)) { if (!GPIO_IS_VALID_GPIO(pin)) {
log_e("Invalid pin selected");
return; return;
} }
gpio_config_t conf = { gpio_config_t conf = {
@ -182,157 +114,23 @@ extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
conf.pull_down_en = GPIO_PULLDOWN_ENABLE; conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
} }
} }
gpio_config(&conf); if(gpio_config(&conf) != ESP_OK)
{
if(mode == SPECIAL){ log_e("GPIO config failed");
#if CONFIG_IDF_TARGET_ESP32
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pin], (uint32_t)(((pin)==RX||(pin)==TX)?0:1));
#elif CONFIG_IDF_TARGET_ESP32S2
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pin], (uint32_t)(((pin)==RX||(pin)==TX)?0:2));
#endif
} else if(mode == ANALOG){
#if !CONFIG_IDF_TARGET_ESP32C3
//adc_gpio_init(ADC_UNIT_1, ADC_CHANNEL_0);
#endif
} else if(mode >= 0x20 && mode < ANALOG) {//function
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pin], mode >> 5);
}
#else
if(!digitalPinIsValid(pin)) {
return; return;
} }
int8_t rtc_io = esp32_gpioMux[pin].rtc;
uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
if(mode == ANALOG) {
if(!rtc_reg) {
return;//not rtc pin
}
#if CONFIG_IDF_TARGET_ESP32S2
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
#endif
SET_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, (rtc_io_desc[rtc_io].mux));
SET_PERI_REG_BITS(rtc_io_desc[rtc_io].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0, rtc_io_desc[rtc_io].func);
RTCIO.pin[rtc_io].pad_driver = 0;//OD = 1
RTCIO.enable_w1tc.w1tc = (1U << rtc_io);
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].ie);
if (rtc_io_desc[rtc_io].pullup) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pullup);
}
if (rtc_io_desc[rtc_io].pulldown) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pulldown);
}
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = ((uint32_t)GPIO_FUNC << MCU_SEL_S) | ((uint32_t)2 << FUN_DRV_S) | FUN_IE;
return;
}
//RTC pins PULL settings
if(rtc_reg) {
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
if(mode & PULLUP) {
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[rtc_io].pullup) & ~(rtc_io_desc[rtc_io].pulldown);
} else if(mode & PULLDOWN) {
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[rtc_io].pulldown) & ~(rtc_io_desc[rtc_io].pullup);
} else {
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
}
}
uint32_t pinFunction = 0, pinControl = 0;
if(mode & INPUT) {
if(pin < 32) {
GPIO.enable_w1tc = ((uint32_t)1 << pin);
} else {
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
}
} else if(mode & OUTPUT) {
if(pin >= NUM_OUPUT_PINS){
return;
} else if(pin < 32) {
GPIO.enable_w1ts = ((uint32_t)1 << pin);
} else {
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
}
}
if(mode & PULLUP) {
pinFunction |= FUN_PU;
} else if(mode & PULLDOWN) {
pinFunction |= FUN_PD;
}
pinFunction |= ((uint32_t)2 << FUN_DRV_S);//what are the drivers?
pinFunction |= FUN_IE;//input enable but required for output as well?
if(mode & (INPUT | OUTPUT)) {
pinFunction |= ((uint32_t)PIN_FUNC_GPIO << MCU_SEL_S);
} else if(mode == SPECIAL) {
#if CONFIG_IDF_TARGET_ESP32
pinFunction |= ((uint32_t)(((pin)==RX||(pin)==TX)?0:1) << MCU_SEL_S);
#elif CONFIG_IDF_TARGET_ESP32S2
pinFunction |= ((uint32_t)(((pin)==RX||(pin)==TX)?0:2) << MCU_SEL_S);
#endif
} else {
pinFunction |= ((uint32_t)(mode >> 5) << MCU_SEL_S);
}
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
if(mode & OPEN_DRAIN) {
pinControl = (1 << GPIO_PIN0_PAD_DRIVER_S);
}
GPIO.pin[pin].val = pinControl;
#endif
} }
extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val) extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val)
{ {
#if USE_ESP_IDF_GPIO
gpio_set_level((gpio_num_t)pin, val); gpio_set_level((gpio_num_t)pin, val);
#elif CONFIG_IDF_TARGET_ESP32C3
if (val) {
GPIO.out_w1ts.out_w1ts = (1 << pin);
} else {
GPIO.out_w1tc.out_w1tc = (1 << pin);
}
#else
if(val) {
if(pin < 32) {
GPIO.out_w1ts = ((uint32_t)1 << pin);
} else if(pin < NUM_OUPUT_PINS) {
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
}
} else {
if(pin < 32) {
GPIO.out_w1tc = ((uint32_t)1 << pin);
} else if(pin < NUM_OUPUT_PINS) {
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
}
}
#endif
} }
extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin) extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin)
{ {
#if USE_ESP_IDF_GPIO
return gpio_get_level((gpio_num_t)pin); return gpio_get_level((gpio_num_t)pin);
#elif CONFIG_IDF_TARGET_ESP32C3
return (GPIO.in.data >> pin) & 0x1;
#else
if(pin < 32) {
return (GPIO.in >> pin) & 0x1;
} else if(pin < GPIO_PIN_COUNT) {
return (GPIO.in1.val >> (pin - 32)) & 0x1;
}
return 0;
#endif
} }
#if USE_ESP_IDF_GPIO
static void ARDUINO_ISR_ATTR __onPinInterrupt(void * arg) { static void ARDUINO_ISR_ATTR __onPinInterrupt(void * arg) {
InterruptHandle_t * isr = (InterruptHandle_t*)arg; InterruptHandle_t * isr = (InterruptHandle_t*)arg;
if(isr->fn) { if(isr->fn) {
@ -343,49 +141,6 @@ static void ARDUINO_ISR_ATTR __onPinInterrupt(void * arg) {
} }
} }
} }
#else
static intr_handle_t gpio_intr_handle = NULL;
static void ARDUINO_ISR_ATTR __onPinInterrupt()
{
uint32_t gpio_intr_status_l=0;
uint32_t gpio_intr_status_h=0;
gpio_intr_status_l = GPIO.status;
gpio_intr_status_h = GPIO.status1.val;
GPIO.status_w1tc = gpio_intr_status_l;//Clear intr for gpio0-gpio31
GPIO.status1_w1tc.val = gpio_intr_status_h;//Clear intr for gpio32-39
uint8_t pin=0;
if(gpio_intr_status_l) {
do {
if(gpio_intr_status_l & ((uint32_t)1 << pin)) {
if(__pinInterruptHandlers[pin].fn) {
if(__pinInterruptHandlers[pin].arg){
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
} else {
__pinInterruptHandlers[pin].fn();
}
}
}
} while(++pin<32);
}
if(gpio_intr_status_h) {
pin=32;
do {
if(gpio_intr_status_h & ((uint32_t)1 << (pin - 32))) {
if(__pinInterruptHandlers[pin].fn) {
if(__pinInterruptHandlers[pin].arg){
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
} else {
__pinInterruptHandlers[pin].fn();
}
}
}
} while(++pin<GPIO_PIN_COUNT);
}
}
#endif
extern void cleanupFunctional(void* arg); extern void cleanupFunctional(void* arg);
@ -394,13 +149,8 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc,
static bool interrupt_initialized = false; static bool interrupt_initialized = false;
if(!interrupt_initialized) { if(!interrupt_initialized) {
#if USE_ESP_IDF_GPIO
esp_err_t err = gpio_install_isr_service((int)ARDUINO_ISR_FLAG); esp_err_t err = gpio_install_isr_service((int)ARDUINO_ISR_FLAG);
interrupt_initialized = (err == ESP_OK) || (err == ESP_ERR_INVALID_STATE); interrupt_initialized = (err == ESP_OK) || (err == ESP_ERR_INVALID_STATE);
#else
interrupt_initialized = true;
esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, __onPinInterrupt, NULL, &gpio_intr_handle);
#endif
} }
if(!interrupt_initialized) { if(!interrupt_initialized) {
log_e("GPIO ISR Service Failed To Start"); log_e("GPIO ISR Service Failed To Start");
@ -416,27 +166,18 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc,
__pinInterruptHandlers[pin].arg = arg; __pinInterruptHandlers[pin].arg = arg;
__pinInterruptHandlers[pin].functional = functional; __pinInterruptHandlers[pin].functional = functional;
#if USE_ESP_IDF_GPIO
gpio_set_intr_type((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7)); gpio_set_intr_type((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
if(intr_type & 0x8){ if(intr_type & 0x8){
gpio_wakeup_enable((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7)); gpio_wakeup_enable((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
} }
gpio_isr_handler_add((gpio_num_t)pin, __onPinInterrupt, &__pinInterruptHandlers[pin]); gpio_isr_handler_add((gpio_num_t)pin, __onPinInterrupt, &__pinInterruptHandlers[pin]);
gpio_intr_enable((gpio_num_t)pin);
#else
esp_intr_disable(gpio_intr_handle); //FIX interrupts on peripherals outputs (eg. LEDC,...)
#if CONFIG_IDF_TARGET_ESP32 //Enable input in GPIO register
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU gpio_hal_context_t gpiohal;
#endif gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
GPIO.pin[pin].int_ena = 1; gpio_hal_input_enable(&gpiohal, pin);
#if CONFIG_IDF_TARGET_ESP32
} else { //PRO_CPU
GPIO.pin[pin].int_ena = 4;
}
#endif
GPIO.pin[pin].int_type = intr_type;
esp_intr_enable(gpio_intr_handle);
#endif
} }
extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type) extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type)
@ -450,13 +191,9 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
extern void __detachInterrupt(uint8_t pin) extern void __detachInterrupt(uint8_t pin)
{ {
#if USE_ESP_IDF_GPIO gpio_isr_handler_remove((gpio_num_t)pin); //remove handle and disable isr for pin
gpio_intr_disable((gpio_num_t)pin);
gpio_isr_handler_remove((gpio_num_t)pin);
gpio_wakeup_disable((gpio_num_t)pin); gpio_wakeup_disable((gpio_num_t)pin);
#else
esp_intr_disable(gpio_intr_handle);
#endif
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg) if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg)
{ {
cleanupFunctional(__pinInterruptHandlers[pin].arg); cleanupFunctional(__pinInterruptHandlers[pin].arg);
@ -465,13 +202,7 @@ extern void __detachInterrupt(uint8_t pin)
__pinInterruptHandlers[pin].arg = NULL; __pinInterruptHandlers[pin].arg = NULL;
__pinInterruptHandlers[pin].functional = false; __pinInterruptHandlers[pin].functional = false;
#if USE_ESP_IDF_GPIO
gpio_set_intr_type((gpio_num_t)pin, GPIO_INTR_DISABLE); gpio_set_intr_type((gpio_num_t)pin, GPIO_INTR_DISABLE);
#else
GPIO.pin[pin].int_ena = 0;
GPIO.pin[pin].int_type = 0;
esp_intr_enable(gpio_intr_handle);
#endif
} }
@ -481,4 +212,3 @@ extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt"))); extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg"))); extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));

View File

@ -42,20 +42,15 @@ extern "C" {
//GPIO FUNCTIONS //GPIO FUNCTIONS
#define INPUT 0x01 #define INPUT 0x01
#define OUTPUT 0x02 // Changed OUTPUT from 0x02 to behave the same as Arduino pinMode(pin,OUTPUT)
// where you can read the state of pin even when it is set as OUTPUT
#define OUTPUT 0x03
#define PULLUP 0x04 #define PULLUP 0x04
#define INPUT_PULLUP 0x05 #define INPUT_PULLUP 0x05
#define PULLDOWN 0x08 #define PULLDOWN 0x08
#define INPUT_PULLDOWN 0x09 #define INPUT_PULLDOWN 0x09
#define OPEN_DRAIN 0x10 #define OPEN_DRAIN 0x10
#define OUTPUT_OPEN_DRAIN 0x12 #define OUTPUT_OPEN_DRAIN 0x12
#define SPECIAL 0xF0
#define FUNCTION_1 0x00
#define FUNCTION_2 0x20
#define FUNCTION_3 0x40
#define FUNCTION_4 0x60
#define FUNCTION_5 0x80
#define FUNCTION_6 0xA0
#define ANALOG 0xC0 #define ANALOG 0xC0
//Interrupt Modes //Interrupt Modes
@ -68,22 +63,11 @@ extern "C" {
#define ONLOW_WE 0x0C #define ONLOW_WE 0x0C
#define ONHIGH_WE 0x0D #define ONHIGH_WE 0x0D
typedef struct { #define digitalPinIsValid(pin) GPIO_IS_VALID_GPIO(pin)
uint8_t reg; /*!< GPIO register offset from DR_REG_IO_MUX_BASE */ #define digitalPinCanOutput(pin) GPIO_IS_VALID_OUTPUT_GPIO(pin)
int8_t rtc; /*!< RTC GPIO number (-1 if not RTC GPIO pin) */
int8_t adc; /*!< ADC Channel number (-1 if not ADC pin) */
int8_t touch; /*!< Touch Channel number (-1 if not Touch pin) */
} esp32_gpioMux_t;
extern const esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT]; #define digitalPinToRtcPin(pin) ((RTC_GPIO_IS_VALID_GPIO(pin))?rtc_io_number_get(pin):-1)
extern const int8_t esp32_adc2gpio[20]; #define digitalPinToDacChannel(pin) (((pin) == DAC_CHANNEL_1_GPIO_NUM)?0:((pin) == DAC_CHANNEL_2_GPIO_NUM)?1:-1)
#define digitalPinIsValid(pin) ((pin) < SOC_GPIO_PIN_COUNT && esp32_gpioMux[(pin)].reg)
#define digitalPinCanOutput(pin) ((pin) < NUM_OUPUT_PINS && esp32_gpioMux[(pin)].reg)
#define digitalPinToRtcPin(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].rtc:-1)
#define digitalPinToAnalogChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].adc:-1)
#define digitalPinToTouchChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].touch:-1)
#define digitalPinToDacChannel(pin) (((pin) == PIN_DAC1)?0:((pin) == PIN_DAC2)?1:-1)
void pinMode(uint8_t pin, uint8_t mode); void pinMode(uint8_t pin, uint8_t mode);
void digitalWrite(uint8_t pin, uint8_t val); void digitalWrite(uint8_t pin, uint8_t val);
@ -93,6 +77,10 @@ void attachInterrupt(uint8_t pin, void (*)(void), int mode);
void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode); void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode);
void detachInterrupt(uint8_t pin); void detachInterrupt(uint8_t pin);
int8_t digitalPinToTouchChannel(uint8_t pin);
int8_t digitalPinToAnalogChannel(uint8_t pin);
int8_t analogChannelToDigitalPin(uint8_t channel);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

22
cores/esp32/esp32-hal-i2c-slave.c Executable file → Normal file
View File

@ -127,7 +127,7 @@ typedef enum {
static inline i2c_stretch_cause_t i2c_ll_stretch_cause(i2c_dev_t *hw) static inline i2c_stretch_cause_t i2c_ll_stretch_cause(i2c_dev_t *hw)
{ {
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
return hw->sr.stretch_cause; return hw->sr.stretch_cause;
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
return hw->status_reg.stretch_cause; return hw->status_reg.stretch_cause;
@ -164,7 +164,7 @@ static inline void i2c_ll_stretch_clr(i2c_dev_t *hw)
static inline bool i2c_ll_slave_addressed(i2c_dev_t *hw) static inline bool i2c_ll_slave_addressed(i2c_dev_t *hw)
{ {
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
return hw->sr.slave_addressed; return hw->sr.slave_addressed;
#else #else
return hw->status_reg.slave_addressed; return hw->status_reg.slave_addressed;
@ -173,7 +173,7 @@ static inline bool i2c_ll_slave_addressed(i2c_dev_t *hw)
static inline bool i2c_ll_slave_rw(i2c_dev_t *hw)//not exposed by hal_ll static inline bool i2c_ll_slave_rw(i2c_dev_t *hw)//not exposed by hal_ll
{ {
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
return hw->sr.slave_rw; return hw->sr.slave_rw;
#else #else
return hw->status_reg.slave_rw; return hw->status_reg.slave_rw;
@ -302,7 +302,7 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
i2c_ll_slave_init(i2c->dev); i2c_ll_slave_init(i2c->dev);
i2c_ll_set_fifo_mode(i2c->dev, true); i2c_ll_set_fifo_mode(i2c->dev, true);
i2c_ll_set_slave_addr(i2c->dev, slaveID, false); i2c_ll_set_slave_addr(i2c->dev, slaveID, false);
i2c_ll_set_tout(i2c->dev, 32000); i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT);
i2c_slave_set_frequency(i2c, frequency); i2c_slave_set_frequency(i2c, frequency);
if (!i2c_slave_check_line_state(sda, scl)) { if (!i2c_slave_check_line_state(sda, scl)) {
@ -360,10 +360,12 @@ esp_err_t i2cSlaveDeinit(uint8_t num){
} }
i2c_slave_struct_t * i2c = &_i2c_bus_array[num]; i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
#if !CONFIG_DISABLE_HAL_LOCKS
if(!i2c->lock){ if(!i2c->lock){
log_e("Lock is not initialized! Did you call i2c_slave_init()?"); log_e("Lock is not initialized! Did you call i2c_slave_init()?");
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
#endif
I2C_SLAVE_MUTEX_LOCK(); I2C_SLAVE_MUTEX_LOCK();
i2c_slave_free_resources(i2c); i2c_slave_free_resources(i2c);
I2C_SLAVE_MUTEX_UNLOCK(); I2C_SLAVE_MUTEX_UNLOCK();
@ -377,10 +379,12 @@ size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t tim
} }
size_t to_queue = 0, to_fifo = 0; size_t to_queue = 0, to_fifo = 0;
i2c_slave_struct_t * i2c = &_i2c_bus_array[num]; i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
#if !CONFIG_DISABLE_HAL_LOCKS
if(!i2c->lock){ if(!i2c->lock){
log_e("Lock is not initialized! Did you call i2c_slave_init()?"); log_e("Lock is not initialized! Did you call i2c_slave_init()?");
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
#endif
if(!i2c->tx_queue){ if(!i2c->tx_queue){
return 0; return 0;
} }
@ -715,10 +719,12 @@ static void i2c_slave_isr_handler(void* arg)
} }
if(slave_rw){ // READ if(slave_rw){ // READ
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
//SEND TX Event if(i2c->dev->status_reg.scl_main_state_last == 6){
i2c_slave_queue_event_t event; //SEND TX Event
event.event = I2C_SLAVE_EVT_TX; i2c_slave_queue_event_t event;
pxHigherPriorityTaskWoken |= i2c_slave_send_event(i2c, &event); event.event = I2C_SLAVE_EVT_TX;
pxHigherPriorityTaskWoken |= i2c_slave_send_event(i2c, &event);
}
#else #else
//reset TX data //reset TX data
i2c_ll_txfifo_rst(i2c->dev); i2c_ll_txfifo_rst(i2c->dev);

0
cores/esp32/esp32-hal-i2c-slave.h Executable file → Normal file
View File

View File

@ -24,6 +24,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/i2c_periph.h" #include "soc/i2c_periph.h"
#include "hal/i2c_hal.h" #include "hal/i2c_hal.h"
#include "hal/i2c_ll.h"
#include "driver/i2c.h" #include "driver/i2c.h"
typedef volatile struct { typedef volatile struct {
@ -91,6 +92,8 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency){
} else { } else {
bus[i2c_num].initialized = true; bus[i2c_num].initialized = true;
bus[i2c_num].frequency = frequency; bus[i2c_num].frequency = frequency;
//Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);
} }
} }
#if !CONFIG_DISABLE_HAL_LOCKS #if !CONFIG_DISABLE_HAL_LOCKS
@ -314,6 +317,8 @@ esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency){
hal.dev = I2C_LL_GET_HW(i2c_num); hal.dev = I2C_LL_GET_HW(i2c_num);
i2c_hal_set_bus_timing(&(hal), frequency, src_clk); i2c_hal_set_bus_timing(&(hal), frequency, src_clk);
bus[i2c_num].frequency = frequency; bus[i2c_num].frequency = frequency;
//Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);
} }
end: end:

View File

@ -13,46 +13,25 @@
// limitations under the License. // limitations under the License.
#include "esp32-hal.h" #include "esp32-hal.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp32-hal-matrix.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/ledc_reg.h" #include "driver/ledc.h"
#include "soc/ledc_struct.h"
#include "driver/periph_ctrl.h"
#include "esp_system.h" #ifdef SOC_LEDC_SUPPORT_HS_MODE
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ #define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1)
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "soc/dport_reg.h"
#include "esp32/rom/ets_sys.h"
#define LAST_CHAN (15)
#elif CONFIG_IDF_TARGET_ESP32S2
#include "soc/dport_reg.h"
#include "esp32s2/rom/ets_sys.h"
#define LAST_CHAN (7)
#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/ets_sys.h"
#define LAST_CHAN (7)
#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#endif
#if CONFIG_DISABLE_HAL_LOCKS
#define LEDC_MUTEX_LOCK()
#define LEDC_MUTEX_UNLOCK()
#else #else
#define LEDC_MUTEX_LOCK() do {} while (xSemaphoreTake(_ledc_sys_lock, portMAX_DELAY) != pdPASS) #define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM)
#define LEDC_MUTEX_UNLOCK() xSemaphoreGive(_ledc_sys_lock)
xSemaphoreHandle _ledc_sys_lock = NULL;
#endif #endif
//Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz
//Need to be fixed in ESP-IDF
#ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK
#define LEDC_DEFAULT_CLK LEDC_USE_XTAL_CLK
#else
#define LEDC_DEFAULT_CLK LEDC_AUTO_CLK
#endif
#define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM
/* /*
* LEDC Chan to Group/Channel/Timer Mapping * LEDC Chan to Group/Channel/Timer Mapping
** ledc: 0 => Group: 0, Channel: 0, Timer: 0 ** ledc: 0 => Group: 0, Channel: 0, Timer: 0
@ -72,228 +51,103 @@ xSemaphoreHandle _ledc_sys_lock = NULL;
** ledc: 14 => Group: 1, Channel: 6, Timer: 3 ** ledc: 14 => Group: 1, Channel: 6, Timer: 3
** ledc: 15 => Group: 1, Channel: 7, Timer: 3 ** ledc: 15 => Group: 1, Channel: 7, Timer: 3
*/ */
#define LEDC_CHAN(g,c) LEDC.channel_group[(g)].channel[(c)]
#define LEDC_TIMER(g,t) LEDC.timer_group[(g)].timer[(t)]
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){ uint8_t channels_resolution[LEDC_CHANNELS] = {0};
if(ev_type == APB_AFTER_CHANGE && old_apb != new_apb){
uint16_t iarg = *(uint16_t*)arg;
uint8_t chan = 0;
old_apb /= 1000000;
new_apb /= 1000000;
while(iarg){ // run though all active channels, adjusting timing configurations
if(iarg & 1) {// this channel is active
uint8_t group=(chan/8), timer=((chan/2)%4);
if(LEDC_TIMER(group, timer).conf.tick_sel){
LEDC_MUTEX_LOCK();
uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider;
uint32_t div_num = (new_apb * old_div) / old_apb;
if(div_num > LEDC_DIV_NUM_HSTIMER0_V){
div_num = ((REF_CLK_FREQ /1000000) * old_div) / old_apb;
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
}
LEDC_TIMER(group, timer).conf.tick_sel = 0;
} else if(div_num < 256) {
div_num = 256;//highest clock possible
}
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
LEDC_MUTEX_UNLOCK();
}
else {
log_d("using REF_CLK chan=%d",chan);
}
}
iarg = iarg >> 1;
chan++;
}
}
}
//uint32_t frequency = (80MHz or 1MHz)/((div_num / 256.0)*(1 << bit_num)); uint32_t ledcSetup(uint8_t chan, uint32_t freq, uint8_t bit_num)
static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, bool apb_clk)
{ {
uint8_t group=(chan/8), timer=((chan/2)%4); if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
static bool tHasStarted = false; log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
static uint16_t _activeChannels = 0;
#if CONFIG_IDF_TARGET_ESP32S2
// ESP32-S2 TRM v1.0 on Page 789 -> BIT LEDC_TICK_SEL_TIMERx is 0 for LEDC_PWM_CLK and 1 for REF_TICK
apb_clk = 0;
#endif
if(!tHasStarted) {
tHasStarted = true;
periph_module_enable(PERIPH_LEDC_MODULE);
LEDC.conf.apb_clk_sel = 1;//LS use apb clock
addApbChangeCallback((void*)&_activeChannels, _on_apb_change);
#if !CONFIG_DISABLE_HAL_LOCKS
_ledc_sys_lock = xSemaphoreCreateMutex();
#endif
}
LEDC_MUTEX_LOCK();
LEDC_TIMER(group, timer).conf.clock_divider = div_num;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part.
LEDC_TIMER(group, timer).conf.duty_resolution = bit_num;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20.
LEDC_TIMER(group, timer).conf.tick_sel = apb_clk;//apb clock
#if CONFIG_IDF_TARGET_ESP32
if(group) {
#endif
LEDC_TIMER(group, timer).conf.low_speed_update = 1;//This bit is only useful for low speed timer channels, reserved for high speed timers
#if CONFIG_IDF_TARGET_ESP32
}
#endif
LEDC_TIMER(group, timer).conf.pause = 0;
LEDC_TIMER(group, timer).conf.rst = 1;//This bit is used to reset timer the counter will be 0 after reset.
LEDC_TIMER(group, timer).conf.rst = 0;
LEDC_MUTEX_UNLOCK();
_activeChannels |= (1 << chan); // mark as active for APB callback
}
//max div_num 0x3FFFF (262143)
//max bit_num 0x1F (31)
static double _ledcSetupTimerFreq(uint8_t chan, double freq, uint8_t bit_num)
{
uint64_t clk_freq = getApbFrequency();
clk_freq <<= 8;//div_num is 8 bit decimal
uint32_t div_num = (clk_freq >> bit_num) / freq;
bool apb_clk = true;
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
clk_freq /= 80;
div_num = (clk_freq >> bit_num) / freq;
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
}
apb_clk = false;
} else if(div_num < 256) {
div_num = 256;//highest clock possible
}
_ledcSetupTimer(chan, div_num, bit_num, apb_clk);
//log_i("Fin: %f, Fclk: %uMhz, bits: %u, DIV: %u, Fout: %f",
// freq, apb_clk?80:1, bit_num, div_num, (clk_freq >> bit_num) / (double)div_num);
return (clk_freq >> bit_num) / (double)div_num;
}
static double _ledcTimerRead(uint8_t chan)
{
uint32_t div_num;
uint8_t bit_num;
bool apb_clk;
uint8_t group=(chan/8), timer=((chan/2)%4);
LEDC_MUTEX_LOCK();
div_num = LEDC_TIMER(group, timer).conf.clock_divider;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part.
bit_num = LEDC_TIMER(group, timer).conf.duty_resolution;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20.
apb_clk = LEDC_TIMER(group, timer).conf.tick_sel;//apb clock
LEDC_MUTEX_UNLOCK();
uint64_t clk_freq = 1000000;
if(apb_clk) {
clk_freq = getApbFrequency();
}
clk_freq <<= 8;//div_num is 8 bit decimal
return (clk_freq >> bit_num) / (double)div_num;
}
static void _ledcSetupChannel(uint8_t chan, uint8_t idle_level)
{
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
LEDC_MUTEX_LOCK();
LEDC_CHAN(group, channel).conf0.timer_sel = timer;//2 bit Selects the timer to attach 0-3
LEDC_CHAN(group, channel).conf0.idle_lv = idle_level;//1 bit This bit is used to control the output value when channel is off.
LEDC_CHAN(group, channel).hpoint.hpoint = 0;//20 bit The output value changes to high when timer selected by channel has reached hpoint
LEDC_CHAN(group, channel).conf1.duty_inc = 1;//1 bit This register is used to increase the duty of output signal or decrease the duty of output signal for high speed channel
LEDC_CHAN(group, channel).conf1.duty_num = 1;//10 bit This register is used to control the number of increased or decreased times for channel
LEDC_CHAN(group, channel).conf1.duty_cycle = 1;//10 bit This register is used to increase or decrease the duty every duty_cycle cycles for channel
LEDC_CHAN(group, channel).conf1.duty_scale = 0;//10 bit This register controls the increase or decrease step scale for channel.
LEDC_CHAN(group, channel).duty.duty = 0;
LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel
LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
#if CONFIG_IDF_TARGET_ESP32
if(group) {
#endif
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
#if CONFIG_IDF_TARGET_ESP32
} else {
LEDC_CHAN(group, channel).conf0.clk_en = 0;
}
#endif
LEDC_MUTEX_UNLOCK();
}
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
{
if(chan > LAST_CHAN) {
return 0; return 0;
} }
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
_ledcSetupChannel(chan, LOW); uint8_t group=(chan/8), timer=((chan/2)%4);
return res_freq;
ledc_timer_config_t ledc_timer = {
.speed_mode = group,
.timer_num = timer,
.duty_resolution = bit_num,
.freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK
};
if(ledc_timer_config(&ledc_timer) != ESP_OK)
{
log_e("ledc setup failed!");
return 0;
}
channels_resolution[chan] = bit_num;
return ledc_get_freq(group,timer);
} }
void ledcWrite(uint8_t chan, uint32_t duty) void ledcWrite(uint8_t chan, uint32_t duty)
{ {
if(chan > LAST_CHAN) { if(chan >= LEDC_CHANNELS){
return; return;
} }
uint8_t group=(chan/8), channel=(chan%8); uint8_t group=(chan/8), channel=(chan%8);
LEDC_MUTEX_LOCK();
LEDC_CHAN(group, channel).duty.duty = duty << 4;//25 bit (21.4) //Fixing if all bits in resolution is set = LEDC FULL ON
if(duty) { uint32_t max_duty = (1 << channels_resolution[chan]) - 1;
LEDC_CHAN(group, channel).conf0.sig_out_en = 1;//This is the output enable control bit for channel
LEDC_CHAN(group, channel).conf1.duty_start = 1;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware. if(duty == max_duty){
#if CONFIG_IDF_TARGET_ESP32 duty = max_duty + 1;
if(group) {
#endif
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
#if CONFIG_IDF_TARGET_ESP32
} else {
LEDC_CHAN(group, channel).conf0.clk_en = 1;
}
#endif
} else {
LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel
LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
#if CONFIG_IDF_TARGET_ESP32
if(group) {
#endif
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
#if CONFIG_IDF_TARGET_ESP32
} else {
LEDC_CHAN(group, channel).conf0.clk_en = 0;
}
#endif
} }
LEDC_MUTEX_UNLOCK();
ledc_set_duty(group, channel, duty);
ledc_update_duty(group, channel);
} }
uint32_t ledcRead(uint8_t chan) uint32_t ledcRead(uint8_t chan)
{ {
if(chan > LAST_CHAN) { if(chan >= LEDC_CHANNELS){
return 0; return 0;
} }
return LEDC.channel_group[chan/8].channel[chan%8].duty.duty >> 4; uint8_t group=(chan/8), channel=(chan%8);
return ledc_get_duty(group,channel);
} }
double ledcReadFreq(uint8_t chan) uint32_t ledcReadFreq(uint8_t chan)
{ {
if(!ledcRead(chan)){ if(!ledcRead(chan)){
return 0; return 0;
} }
return _ledcTimerRead(chan); uint8_t group=(chan/8), timer=((chan/2)%4);
return ledc_get_freq(group,timer);
} }
double ledcWriteTone(uint8_t chan, double freq) uint32_t ledcWriteTone(uint8_t chan, uint32_t freq)
{ {
if(chan > LAST_CHAN) { if(chan >= LEDC_CHANNELS){
return 0; return 0;
} }
if(!freq) { if(!freq){
ledcWrite(chan, 0); ledcWrite(chan, 0);
return 0; return 0;
} }
double res_freq = _ledcSetupTimerFreq(chan, freq, 10);
uint8_t group=(chan/8), timer=((chan/2)%4);
ledc_timer_config_t ledc_timer = {
.speed_mode = group,
.timer_num = timer,
.duty_resolution = 10,
.freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK
};
if(ledc_timer_config(&ledc_timer) != ESP_OK)
{
log_e("ledcSetup failed!");
return 0;
}
channels_resolution[chan] = 10;
uint32_t res_freq = ledc_get_freq(group,timer);
ledcWrite(chan, 0x1FF); ledcWrite(chan, 0x1FF);
return res_freq; return res_freq;
} }
double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){ uint32_t ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
const uint16_t noteFrequencyBase[12] = { const uint16_t noteFrequencyBase[12] = {
// C C# D Eb E F F# G G# A Bb B // C C# D Eb E F F# G G# A Bb B
4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902 4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902
@ -302,21 +156,27 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
if(octave > 8 || note >= NOTE_MAX){ if(octave > 8 || note >= NOTE_MAX){
return 0; return 0;
} }
double noteFreq = (double)noteFrequencyBase[note] / (double)(1 << (8-octave)); uint32_t noteFreq = (uint32_t)noteFrequencyBase[note] / (uint32_t)(1 << (8-octave));
return ledcWriteTone(chan, noteFreq); return ledcWriteTone(chan, noteFreq);
} }
void ledcAttachPin(uint8_t pin, uint8_t chan) void ledcAttachPin(uint8_t pin, uint8_t chan)
{ {
if(chan > LAST_CHAN) { if(chan >= LEDC_CHANNELS){
return; return;
} }
pinMode(pin, OUTPUT); uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
pinMatrixOutAttach(pin, LEDC_LS_SIG_OUT0_IDX + chan, false, false); ledc_channel_config_t ledc_channel = {
#else .speed_mode = group,
pinMatrixOutAttach(pin, ((chan/8)?LEDC_LS_SIG_OUT0_IDX:LEDC_HS_SIG_OUT0_IDX) + (chan%8), false, false); .channel = channel,
#endif .timer_sel = timer,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = pin,
.duty = 0,
.hpoint = 0
};
ledc_channel_config(&ledc_channel);
} }
void ledcDetachPin(uint8_t pin) void ledcDetachPin(uint8_t pin)
@ -324,23 +184,39 @@ void ledcDetachPin(uint8_t pin)
pinMatrixOutDetach(pin, false, false); pinMatrixOutDetach(pin, false, false);
} }
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num) uint32_t ledcChangeFrequency(uint8_t chan, uint32_t freq, uint8_t bit_num)
{ {
if (chan > 15) { if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
log_e("LEDC channel not available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
return 0; return 0;
} }
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num); uint8_t group=(chan/8), timer=((chan/2)%4);
return res_freq;
ledc_timer_config_t ledc_timer = {
.speed_mode = group,
.timer_num = timer,
.duty_resolution = bit_num,
.freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK
};
if(ledc_timer_config(&ledc_timer) != ESP_OK)
{
log_e("ledcChangeFrequency failed!");
return 0;
}
channels_resolution[chan] = bit_num;
return ledc_get_freq(group,timer);
} }
static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 }; static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 };
static int cnt_channel = SOC_LEDC_CHANNEL_NUM; static int cnt_channel = LEDC_CHANNELS;
void analogWrite(uint8_t pin, int value) { void analogWrite(uint8_t pin, int value) {
// Use ledc hardware for internal pins // Use ledc hardware for internal pins
if (pin < SOC_GPIO_PIN_COUNT) { if (pin < SOC_GPIO_PIN_COUNT) {
if (pin_to_channel[pin] == 0) { if (pin_to_channel[pin] == 0) {
if (!cnt_channel) { if (!cnt_channel) {
log_e("No more analogWrite channels available! You can have maximum %u", SOC_LEDC_CHANNEL_NUM); log_e("No more analogWrite channels available! You can have maximum %u", LEDC_CHANNELS);
return; return;
} }
pin_to_channel[pin] = cnt_channel--; pin_to_channel[pin] = cnt_channel--;

View File

@ -27,15 +27,15 @@ typedef enum {
} note_t; } note_t;
//channel 0-15 resolution 1-16bits freq limits depend on resolution //channel 0-15 resolution 1-16bits freq limits depend on resolution
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits); uint32_t ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
void ledcWrite(uint8_t channel, uint32_t duty); void ledcWrite(uint8_t channel, uint32_t duty);
double ledcWriteTone(uint8_t channel, double freq); uint32_t ledcWriteTone(uint8_t channel, uint32_t freq);
double ledcWriteNote(uint8_t channel, note_t note, uint8_t octave); uint32_t ledcWriteNote(uint8_t channel, note_t note, uint8_t octave);
uint32_t ledcRead(uint8_t channel); uint32_t ledcRead(uint8_t channel);
double ledcReadFreq(uint8_t channel); uint32_t ledcReadFreq(uint8_t channel);
void ledcAttachPin(uint8_t pin, uint8_t channel); void ledcAttachPin(uint8_t pin, uint8_t channel);
void ledcDetachPin(uint8_t pin); void ledcDetachPin(uint8_t pin);
double ledcChangeFrequency(uint8_t channel, double freq, uint8_t resolution_bits); uint32_t ledcChangeFrequency(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -38,9 +38,11 @@ extern "C"
#else #else
#define ARDUHAL_LOG_LEVEL CORE_DEBUG_LEVEL #define ARDUHAL_LOG_LEVEL CORE_DEBUG_LEVEL
#ifdef USE_ESP_IDF_LOG #ifdef USE_ESP_IDF_LOG
#ifndef LOG_LOCAL_LEVEL
#define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL #define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL
#endif #endif
#endif #endif
#endif
#ifndef CONFIG_ARDUHAL_LOG_COLORS #ifndef CONFIG_ARDUHAL_LOG_COLORS
#define CONFIG_ARDUHAL_LOG_COLORS 0 #define CONFIG_ARDUHAL_LOG_COLORS 0
@ -158,7 +160,7 @@ void log_print_buf(const uint8_t *b, size_t len);
#define isr_log_e(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__) #define isr_log_e(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
#define log_buf_e(b,l) do{ARDUHAL_LOG_COLOR_PRINT(E);log_print_buf(b,l);ARDUHAL_LOG_COLOR_PRINT_END;}while(0) #define log_buf_e(b,l) do{ARDUHAL_LOG_COLOR_PRINT(E);log_print_buf(b,l);ARDUHAL_LOG_COLOR_PRINT_END;}while(0)
#else #else
#define log_e(format, ...) do {log_to_esp(TAG, ESP_LOG_ERROR, format, ##__VA_ARGS__);}while(0) #define log_e(format, ...) do {ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, TAG, format, ##__VA_ARGS__);}while(0)
#define isr_log_e(format, ...) do {ets_printf(LOG_FORMAT(E, format), esp_log_timestamp(), TAG, ##__VA_ARGS__);}while(0) #define isr_log_e(format, ...) do {ets_printf(LOG_FORMAT(E, format), esp_log_timestamp(), TAG, ##__VA_ARGS__);}while(0)
#define log_buf_e(b,l) do {ESP_LOG_BUFFER_HEXDUMP(TAG, b, l, ESP_LOG_ERROR);}while(0) #define log_buf_e(b,l) do {ESP_LOG_BUFFER_HEXDUMP(TAG, b, l, ESP_LOG_ERROR);}while(0)
#endif #endif
@ -187,9 +189,9 @@ void log_print_buf(const uint8_t *b, size_t len);
#include "esp_log.h" #include "esp_log.h"
#ifdef USE_ESP_IDF_LOG #ifdef USE_ESP_IDF_LOG
#ifndef TAG //#ifndef TAG
#define TAG "ARDUINO" //#define TAG "ARDUINO"
#endif //#endif
//#define log_n(format, ...) myLog(ESP_LOG_NONE, format, ##__VA_ARGS__) //#define log_n(format, ...) myLog(ESP_LOG_NONE, format, ##__VA_ARGS__)
#else #else
#ifdef CONFIG_ARDUHAL_ESP_LOG #ifdef CONFIG_ARDUHAL_ESP_LOG
@ -204,16 +206,16 @@ void log_print_buf(const uint8_t *b, size_t len);
#undef ESP_EARLY_LOGD #undef ESP_EARLY_LOGD
#undef ESP_EARLY_LOGV #undef ESP_EARLY_LOGV
#define ESP_LOGE(tag, ...) log_e(__VA_ARGS__) #define ESP_LOGE(tag, format, ...) log_e("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_LOGW(tag, ...) log_w(__VA_ARGS__) #define ESP_LOGW(tag, format, ...) log_w("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_LOGI(tag, ...) log_i(__VA_ARGS__) #define ESP_LOGI(tag, format, ...) log_i("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_LOGD(tag, ...) log_d(__VA_ARGS__) #define ESP_LOGD(tag, format, ...) log_d("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_LOGV(tag, ...) log_v(__VA_ARGS__) #define ESP_LOGV(tag, format, ...) log_v("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGE(tag, ...) isr_log_e(__VA_ARGS__) #define ESP_EARLY_LOGE(tag, format, ...) isr_log_e("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGW(tag, ...) isr_log_w(__VA_ARGS__) #define ESP_EARLY_LOGW(tag, format, ...) isr_log_w("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGI(tag, ...) isr_log_i(__VA_ARGS__) #define ESP_EARLY_LOGI(tag, format, ...) isr_log_i("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGD(tag, ...) isr_log_d(__VA_ARGS__) #define ESP_EARLY_LOGD(tag, format, ...) isr_log_d("[%s] " format, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGV(tag, ...) isr_log_v(__VA_ARGS__) #define ESP_EARLY_LOGV(tag, format, ...) isr_log_v("[%s] " format, tag, ##__VA_ARGS__)
#endif #endif
#endif #endif

View File

@ -21,6 +21,8 @@
#include "esp32/rom/gpio.h" #include "esp32/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/gpio.h" #include "esp32s2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/gpio.h" #include "esp32c3/rom/gpio.h"
#else #else

View File

@ -41,6 +41,9 @@
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/rtc.h" #include "esp32s2/rom/rtc.h"
#include "driver/temp_sensor.h" #include "driver/temp_sensor.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/rom/rtc.h"
#include "driver/temp_sensor.h"
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/rtc.h" #include "esp32c3/rom/rtc.h"
#include "driver/temp_sensor.h" #include "driver/temp_sensor.h"
@ -232,7 +235,7 @@ void initArduino()
#endif #endif
esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL); esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL);
esp_err_t err = nvs_flash_init(); esp_err_t err = nvs_flash_init();
if(err == ESP_ERR_NVS_NO_FREE_PAGES){ if(err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND){
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
if (partition != NULL) { if (partition != NULL) {
err = esp_partition_erase_range(partition, 0, partition->size); err = esp_partition_erase_range(partition, 0, partition->size);
@ -241,6 +244,8 @@ void initArduino()
} else { } else {
log_e("Failed to format the broken NVS partition!"); log_e("Failed to format the broken NVS partition!");
} }
} else {
log_e("Could not find NVS partition");
} }
} }
if(err) { if(err) {

View File

@ -25,6 +25,9 @@
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/spiram.h" #include "esp32s2/spiram.h"
#include "esp32s2/rom/cache.h" #include "esp32s2/rom/cache.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/spiram.h"
#include "esp32s3/rom/cache.h"
#else #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif
@ -35,6 +38,13 @@
static volatile bool spiramDetected = false; static volatile bool spiramDetected = false;
static volatile bool spiramFailed = false; static volatile bool spiramFailed = false;
//allows user to bypass SPI RAM test routine
__attribute__((weak)) bool testSPIRAM(void)
{
return esp_spiram_test();
}
bool psramInit(){ bool psramInit(){
if (spiramDetected) { if (spiramDetected) {
return true; return true;
@ -60,13 +70,16 @@ bool psramInit(){
spiramFailed = true; spiramFailed = true;
log_w("PSRAM init failed!"); log_w("PSRAM init failed!");
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
pinMatrixOutDetach(16, false, false); if (pkg_ver != EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
pinMatrixOutDetach(17, false, false); pinMatrixOutDetach(16, false, false);
pinMatrixOutDetach(17, false, false);
}
#endif #endif
return false; return false;
} }
esp_spiram_init_cache(); esp_spiram_init_cache();
if (!esp_spiram_test()) { //testSPIRAM() allows user to bypass SPI RAM test routine
if (!testSPIRAM()) {
spiramFailed = true; spiramFailed = true;
log_e("PSRAM test failed!"); log_e("PSRAM test failed!");
return false; return false;
@ -76,12 +89,12 @@ bool psramInit(){
log_e("PSRAM could not be added to the heap!"); log_e("PSRAM could not be added to the heap!");
return false; return false;
} }
#if CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL && !CONFIG_ARDUINO_ISR_IRAM #if CONFIG_SPIRAM_USE_MALLOC && !CONFIG_ARDUINO_ISR_IRAM
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL); heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
#endif
#endif #endif
#endif /* CONFIG_SPIRAM_BOOT_INIT */
log_i("PSRAM enabled");
spiramDetected = true; spiramDetected = true;
log_d("PSRAM enabled");
return true; return true;
} }

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,9 @@ extern "C" {
#define RMT_FLAG_ERROR (4) #define RMT_FLAG_ERROR (4)
#define RMT_FLAGS_ALL (RMT_FLAG_TX_DONE | RMT_FLAG_RX_DONE | RMT_FLAG_ERROR) #define RMT_FLAGS_ALL (RMT_FLAG_TX_DONE | RMT_FLAG_RX_DONE | RMT_FLAG_ERROR)
#define RMT_TX_MODE true
#define RMT_RX_MODE false
struct rmt_obj_s; struct rmt_obj_s;
typedef enum { typedef enum {
@ -54,6 +57,13 @@ typedef struct {
}; };
} rmt_data_t; } rmt_data_t;
/**
* Prints object information
*
*/
void _rmtDumpStatus(rmt_obj_t* rmt);
/** /**
* Initialize the object * Initialize the object
* *
@ -69,10 +79,17 @@ float rmtSetTick(rmt_obj_t* rmt, float tick);
/** /**
* Sending data in one-go mode or continual mode * Sending data in one-go mode or continual mode
* (more data being send while updating buffers in interrupts) * (more data being send while updating buffers in interrupts)
* * Non-Blocking mode - returns right after executing
*/ */
bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size); bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
/**
* Sending data in one-go mode or continual mode
* (more data being send while updating buffers in interrupts)
* Blocking mode - only returns when data has been sent
*/
bool rmtWriteBlocking(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
/** /**
* Loop data up to the reserved memsize continuously * Loop data up to the reserved memsize continuously
* *

View File

@ -12,38 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "esp32-hal.h" #include "esp32-hal.h"
#include "freertos/FreeRTOS.h" #include "soc/soc_caps.h"
#include "freertos/task.h" #include "driver/sigmadelta.h"
#include "freertos/semphr.h"
#include "esp32-hal-matrix.h"
#include "soc/gpio_sd_reg.h"
#include "soc/gpio_sd_struct.h"
#include "esp_system.h" static uint8_t duty_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0};
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ static uint32_t prescaler_set[SOC_SIGMADELTA_CHANNEL_NUM] = {0};
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/ets_sys.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#endif
#if CONFIG_DISABLE_HAL_LOCKS
#define SD_MUTEX_LOCK()
#define SD_MUTEX_UNLOCK()
#else
#define SD_MUTEX_LOCK() do {} while (xSemaphoreTake(_sd_sys_lock, portMAX_DELAY) != pdPASS)
#define SD_MUTEX_UNLOCK() xSemaphoreGive(_sd_sys_lock)
xSemaphoreHandle _sd_sys_lock;
#endif
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
if(old_apb == new_apb){ if(old_apb == new_apb){
@ -51,82 +27,63 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb
} }
uint32_t iarg = (uint32_t)arg; uint32_t iarg = (uint32_t)arg;
uint8_t channel = iarg; uint8_t channel = iarg;
if(ev_type == APB_BEFORE_CHANGE){ if(ev_type == APB_AFTER_CHANGE){
SIGMADELTA.cg.clk_en = 0;
} else {
old_apb /= 1000000; old_apb /= 1000000;
new_apb /= 1000000; new_apb /= 1000000;
SD_MUTEX_LOCK(); uint32_t old_prescale = prescaler_set[channel] + 1;
uint32_t old_prescale = SIGMADELTA.channel[channel].prescale + 1; uint32_t new_prescale = ((new_apb * old_prescale) / old_apb) - 1;
SIGMADELTA.channel[channel].prescale = ((new_apb * old_prescale) / old_apb) - 1; sigmadelta_set_prescale(channel,new_prescale);
SIGMADELTA.cg.clk_en = 0; prescaler_set[channel] = new_prescale;
SIGMADELTA.cg.clk_en = 1;
SD_MUTEX_UNLOCK();
} }
} }
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-312500 uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq) //chan 0-x according to SOC, freq 1220-312500
{ {
if(channel > 7) { if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
return 0; return 0;
} }
#if !CONFIG_DISABLE_HAL_LOCKS
static bool tHasStarted = false;
if(!tHasStarted) {
tHasStarted = true;
_sd_sys_lock = xSemaphoreCreateMutex();
}
#endif
uint32_t apb_freq = getApbFrequency(); uint32_t apb_freq = getApbFrequency();
uint32_t prescale = (apb_freq/(freq*256)) - 1; uint32_t prescale = (apb_freq/(freq*256)) - 1;
if(prescale > 0xFF) { if(prescale > 0xFF) {
prescale = 0xFF; prescale = 0xFF;
} }
SD_MUTEX_LOCK();
#ifndef CONFIG_IDF_TARGET_ESP32 sigmadelta_config_t sigmadelta_cfg = {
SIGMADELTA.misc.function_clk_en = 1; .channel = channel,
#endif .sigmadelta_prescale = prescale,
SIGMADELTA.channel[channel].prescale = prescale; .sigmadelta_duty = 0,
SIGMADELTA.cg.clk_en = 0; .sigmadelta_gpio = pin,
SIGMADELTA.cg.clk_en = 1; };
SD_MUTEX_UNLOCK(); sigmadelta_config(&sigmadelta_cfg);
prescaler_set[channel] = prescale;
uint32_t iarg = channel; uint32_t iarg = channel;
addApbChangeCallback((void*)iarg, _on_apb_change); addApbChangeCallback((void*)iarg, _on_apb_change);
return apb_freq/((prescale + 1) * 256); return apb_freq/((prescale + 1) * 256);
} }
void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-7 duty 8 bit void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-x according to SOC duty 8 bit
{ {
if(channel > 7) { if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
return; return;
} }
duty -= 128; duty -= 128;
SD_MUTEX_LOCK();
SIGMADELTA.channel[channel].duty = duty; sigmadelta_set_duty(channel,duty);
SD_MUTEX_UNLOCK(); duty_set[channel] = duty;
} }
uint8_t sigmaDeltaRead(uint8_t channel) //chan 0-7 uint8_t sigmaDeltaRead(uint8_t channel) //chan 0-x according to SOC
{ {
if(channel > 7) { if(channel >= SOC_SIGMADELTA_CHANNEL_NUM){
return 0; return 0;
} }
SD_MUTEX_LOCK(); return duty_set[channel]+128;
uint8_t duty = SIGMADELTA.channel[channel].duty + 128;
SD_MUTEX_UNLOCK();
return duty;
}
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel) //channel 0-7
{
if(channel > 7) {
return;
}
pinMode(pin, OUTPUT);
pinMatrixOutAttach(pin, GPIO_SD0_OUT_IDX + channel, false, false);
} }
void sigmaDeltaDetachPin(uint8_t pin) void sigmaDeltaDetachPin(uint8_t pin)
{ {
pinMatrixOutDetach(pin, false, false); pinMatrixOutDetach(pin, false, false);
} }

View File

@ -23,10 +23,9 @@ extern "C" {
#include <stdbool.h> #include <stdbool.h>
//channel 0-7 freq 1220-312500 duty 0-255 //channel 0-7 freq 1220-312500 duty 0-255
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq); uint32_t sigmaDeltaSetup(uint8_t pin, uint8_t channel, uint32_t freq);
void sigmaDeltaWrite(uint8_t channel, uint8_t duty); void sigmaDeltaWrite(uint8_t channel, uint8_t duty);
uint8_t sigmaDeltaRead(uint8_t channel); uint8_t sigmaDeltaRead(uint8_t channel);
void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel);
void sigmaDeltaDetachPin(uint8_t pin); void sigmaDeltaDetachPin(uint8_t pin);

View File

@ -37,6 +37,11 @@
#include "esp32s2/rom/ets_sys.h" #include "esp32s2/rom/ets_sys.h"
#include "esp32s2/rom/gpio.h" #include "esp32s2/rom/gpio.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "soc/dport_reg.h"
#include "esp32s3/rom/ets_sys.h"
#include "esp32s3/rom/gpio.h"
#include "esp_intr_alloc.h"
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
#include "esp32c3/rom/ets_sys.h" #include "esp32c3/rom/ets_sys.h"
#include "esp32c3/rom/gpio.h" #include "esp32c3/rom/gpio.h"
@ -71,10 +76,20 @@ struct spi_struct_t {
#define SPI_FSPI_SS_IDX(n) ((n==0)?FSPICS0_OUT_IDX:((n==1)?FSPICS1_OUT_IDX:((n==2)?FSPICS2_OUT_IDX:FSPICS0_OUT_IDX))) #define SPI_FSPI_SS_IDX(n) ((n==0)?FSPICS0_OUT_IDX:((n==1)?FSPICS1_OUT_IDX:((n==2)?FSPICS2_OUT_IDX:FSPICS0_OUT_IDX)))
#define SPI_SS_IDX(p, n) ((p==0)?SPI_SPI_SS_IDX(n):((p==1)?SPI_SPI_SS_IDX(n):((p==2)?SPI_HSPI_SS_IDX(n):0))) #define SPI_SS_IDX(p, n) ((p==0)?SPI_SPI_SS_IDX(n):((p==1)?SPI_SPI_SS_IDX(n):((p==2)?SPI_HSPI_SS_IDX(n):0)))
#define SPI_INTR_SOURCE(u) ((u==0)?ETS_SPI1_INTR_SOURCE:((u==1)?ETS_SPI2_INTR_SOURCE:((u==2)?ETS_SPI3_INTR_SOURCE:0))) #elif CONFIG_IDF_TARGET_ESP32S3
// ESP32S3
#define SPI_COUNT (2)
#define SPI_CLK_IDX(p) ((p==0)?FSPICLK_OUT_IDX:((p==1)?SPI3_CLK_OUT_IDX:0))
#define SPI_MISO_IDX(p) ((p==0)?FSPIQ_OUT_IDX:((p==1)?SPI3_Q_OUT_IDX:0))
#define SPI_MOSI_IDX(p) ((p==0)?FSPID_IN_IDX:((p==1)?SPI3_D_IN_IDX:0))
#define SPI_HSPI_SS_IDX(n) ((n==0)?SPI3_CS0_OUT_IDX:((n==1)?SPI3_CS1_OUT_IDX:0))
#define SPI_FSPI_SS_IDX(n) ((n==0)?FSPICS0_OUT_IDX:((n==1)?FSPICS1_OUT_IDX:0))
#define SPI_SS_IDX(p, n) ((p==0)?SPI_FSPI_SS_IDX(n):((p==1)?SPI_HSPI_SS_IDX(n):0))
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
// ESP32S2 // ESP32C3
#define SPI_COUNT (1) #define SPI_COUNT (1)
#define SPI_CLK_IDX(p) FSPICLK_OUT_IDX #define SPI_CLK_IDX(p) FSPICLK_OUT_IDX
@ -84,8 +99,6 @@ struct spi_struct_t {
#define SPI_SPI_SS_IDX(n) ((n==0)?FSPICS0_OUT_IDX:((n==1)?FSPICS1_OUT_IDX:((n==2)?FSPICS2_OUT_IDX:FSPICS0_OUT_IDX))) #define SPI_SPI_SS_IDX(n) ((n==0)?FSPICS0_OUT_IDX:((n==1)?FSPICS1_OUT_IDX:((n==2)?FSPICS2_OUT_IDX:FSPICS0_OUT_IDX)))
#define SPI_SS_IDX(p, n) SPI_SPI_SS_IDX(n) #define SPI_SS_IDX(p, n) SPI_SPI_SS_IDX(n)
#define SPI_INTR_SOURCE(u) ETS_SPI2_INTR_SOURCE
#else #else
// ESP32 // ESP32
#define SPI_COUNT (4) #define SPI_COUNT (4)
@ -99,8 +112,6 @@ struct spi_struct_t {
#define SPI_VSPI_SS_IDX(n) ((n==0)?VSPICS0_OUT_IDX:((n==1)?VSPICS1_OUT_IDX:((n==2)?VSPICS2_OUT_IDX:VSPICS0_OUT_IDX))) #define SPI_VSPI_SS_IDX(n) ((n==0)?VSPICS0_OUT_IDX:((n==1)?VSPICS1_OUT_IDX:((n==2)?VSPICS2_OUT_IDX:VSPICS0_OUT_IDX)))
#define SPI_SS_IDX(p, n) ((p==0)?SPI_SPI_SS_IDX(n):((p==1)?SPI_SPI_SS_IDX(n):((p==2)?SPI_HSPI_SS_IDX(n):((p==3)?SPI_VSPI_SS_IDX(n):0)))) #define SPI_SS_IDX(p, n) ((p==0)?SPI_SPI_SS_IDX(n):((p==1)?SPI_SPI_SS_IDX(n):((p==2)?SPI_HSPI_SS_IDX(n):((p==3)?SPI_VSPI_SS_IDX(n):0))))
#define SPI_INTR_SOURCE(u) ((u==0)?ETS_SPI0_INTR_SOURCE:((u==1)?ETS_SPI1_INTR_SOURCE:((u==2)?ETS_SPI2_INTR_SOURCE:((p==3)?ETS_SPI3_INTR_SOURCE:0))))
#endif #endif
#if CONFIG_DISABLE_HAL_LOCKS #if CONFIG_DISABLE_HAL_LOCKS
@ -112,6 +123,11 @@ static spi_t _spi_bus_array[] = {
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0}, {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1}, {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2} {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2}
#elif CONFIG_IDF_TARGET_ESP32S3
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1}
#elif CONFIG_IDF_TARGET_ESP32C3
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0}
#else #else
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0}, {(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0},
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1}, {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1},
@ -128,8 +144,11 @@ static spi_t _spi_bus_array[] = {
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0}, {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1}, {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2} {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2}
#elif CONFIG_IDF_TARGET_ESP32S3
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 1}
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
{(volatile spi_dev_t *)(&GPSPI2), NULL, FSPI} {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0}
#else #else
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0}, {(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0},
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1}, {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1},
@ -152,6 +171,13 @@ void spiAttachSCK(spi_t * spi, int8_t sck)
log_e("HSPI Does not have default pins on ESP32S2!"); log_e("HSPI Does not have default pins on ESP32S2!");
return; return;
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) {
sck = 12;
} else {
log_e("HSPI Does not have default pins on ESP32S3!");
return;
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi->num == HSPI) { if(spi->num == HSPI) {
sck = 14; sck = 14;
@ -182,6 +208,13 @@ void spiAttachMISO(spi_t * spi, int8_t miso)
log_e("HSPI Does not have default pins on ESP32S2!"); log_e("HSPI Does not have default pins on ESP32S2!");
return; return;
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) {
miso = 13;
} else {
log_e("HSPI Does not have default pins on ESP32S3!");
return;
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi->num == HSPI) { if(spi->num == HSPI) {
miso = 12; miso = 12;
@ -207,13 +240,20 @@ void spiAttachMOSI(spi_t * spi, int8_t mosi)
return; return;
} }
if(mosi < 0) { if(mosi < 0) {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) { if(spi->num == FSPI) {
mosi = 35; mosi = 35;
} else { } else {
log_e("HSPI Does not have default pins on ESP32S2!"); log_e("HSPI Does not have default pins on ESP32S2!");
return; return;
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) {
mosi = 11;
} else {
log_e("HSPI Does not have default pins on ESP32S3!");
return;
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi->num == HSPI) { if(spi->num == HSPI) {
mosi = 13; mosi = 13;
@ -237,13 +277,20 @@ void spiDetachSCK(spi_t * spi, int8_t sck)
return; return;
} }
if(sck < 0) { if(sck < 0) {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) { if(spi->num == FSPI) {
sck = 36; sck = 36;
} else { } else {
log_e("HSPI Does not have default pins on ESP32S2!"); log_e("HSPI Does not have default pins on ESP32S2!");
return; return;
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) {
sck = 12;
} else {
log_e("HSPI Does not have default pins on ESP32S3!");
return;
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi->num == HSPI) { if(spi->num == HSPI) {
sck = 14; sck = 14;
@ -267,13 +314,20 @@ void spiDetachMISO(spi_t * spi, int8_t miso)
return; return;
} }
if(miso < 0) { if(miso < 0) {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) { if(spi->num == FSPI) {
miso = 37; miso = 37;
} else { } else {
log_e("HSPI Does not have default pins on ESP32S2!"); log_e("HSPI Does not have default pins on ESP32S2!");
return; return;
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) {
miso = 13;
} else {
log_e("HSPI Does not have default pins on ESP32S3!");
return;
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi->num == HSPI) { if(spi->num == HSPI) {
miso = 12; miso = 12;
@ -297,13 +351,20 @@ void spiDetachMOSI(spi_t * spi, int8_t mosi)
return; return;
} }
if(mosi < 0) { if(mosi < 0) {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) { if(spi->num == FSPI) {
mosi = 35; mosi = 35;
} else { } else {
log_e("HSPI Does not have default pins on ESP32S2!"); log_e("HSPI Does not have default pins on ESP32S2!");
return; return;
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) {
mosi = 11;
} else {
log_e("HSPI Does not have default pins on ESP32S3!");
return;
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi->num == HSPI) { if(spi->num == HSPI) {
mosi = 13; mosi = 13;
@ -338,6 +399,13 @@ void spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss)
log_e("HSPI Does not have default pins on ESP32S2!"); log_e("HSPI Does not have default pins on ESP32S2!");
return; return;
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) {
ss = 10;
} else {
log_e("HSPI Does not have default pins on ESP32S3!");
return;
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi->num == HSPI) { if(spi->num == HSPI) {
ss = 15; ss = 15;
@ -369,6 +437,13 @@ void spiDetachSS(spi_t * spi, int8_t ss)
log_e("HSPI Does not have default pins on ESP32S2!"); log_e("HSPI Does not have default pins on ESP32S2!");
return; return;
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi->num == FSPI) {
ss = 10;
} else {
log_e("HSPI Does not have default pins on ESP32S3!");
return;
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi->num == HSPI) { if(spi->num == HSPI) {
ss = 15; ss = 15;
@ -392,7 +467,7 @@ void spiEnableSSPins(spi_t * spi, uint8_t cs_mask)
return; return;
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.val &= ~(cs_mask & SPI_CS_MASK_ALL); spi->dev->misc.val &= ~(cs_mask & SPI_CS_MASK_ALL);
#else #else
spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL); spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL);
@ -406,7 +481,7 @@ void spiDisableSSPins(spi_t * spi, uint8_t cs_mask)
return; return;
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.val |= (cs_mask & SPI_CS_MASK_ALL); spi->dev->misc.val |= (cs_mask & SPI_CS_MASK_ALL);
#else #else
spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL); spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL);
@ -442,7 +517,7 @@ void spiSSSet(spi_t * spi)
return; return;
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.cs_keep_active = 1; spi->dev->misc.cs_keep_active = 1;
#else #else
spi->dev->pin.cs_keep_active = 1; spi->dev->pin.cs_keep_active = 1;
@ -456,7 +531,7 @@ void spiSSClear(spi_t * spi)
return; return;
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.cs_keep_active = 0; spi->dev->misc.cs_keep_active = 0;
#else #else
spi->dev->pin.cs_keep_active = 0; spi->dev->pin.cs_keep_active = 0;
@ -487,7 +562,7 @@ uint8_t spiGetDataMode(spi_t * spi)
if(!spi) { if(!spi) {
return 0; return 0;
} }
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
bool idleEdge = spi->dev->misc.ck_idle_edge; bool idleEdge = spi->dev->misc.ck_idle_edge;
#else #else
bool idleEdge = spi->dev->pin.ck_idle_edge; bool idleEdge = spi->dev->pin.ck_idle_edge;
@ -513,7 +588,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
switch (dataMode) { switch (dataMode) {
case SPI_MODE1: case SPI_MODE1:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.ck_idle_edge = 0; spi->dev->misc.ck_idle_edge = 0;
#else #else
spi->dev->pin.ck_idle_edge = 0; spi->dev->pin.ck_idle_edge = 0;
@ -521,7 +596,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
spi->dev->user.ck_out_edge = 1; spi->dev->user.ck_out_edge = 1;
break; break;
case SPI_MODE2: case SPI_MODE2:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.ck_idle_edge = 1; spi->dev->misc.ck_idle_edge = 1;
#else #else
spi->dev->pin.ck_idle_edge = 1; spi->dev->pin.ck_idle_edge = 1;
@ -529,7 +604,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
spi->dev->user.ck_out_edge = 1; spi->dev->user.ck_out_edge = 1;
break; break;
case SPI_MODE3: case SPI_MODE3:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.ck_idle_edge = 1; spi->dev->misc.ck_idle_edge = 1;
#else #else
spi->dev->pin.ck_idle_edge = 1; spi->dev->pin.ck_idle_edge = 1;
@ -538,7 +613,7 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
break; break;
case SPI_MODE0: case SPI_MODE0:
default: default:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.ck_idle_edge = 0; spi->dev->misc.ck_idle_edge = 0;
#else #else
spi->dev->pin.ck_idle_edge = 0; spi->dev->pin.ck_idle_edge = 0;
@ -587,11 +662,11 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb
static void spiInitBus(spi_t * spi) static void spiInitBus(spi_t * spi)
{ {
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->slave.trans_done = 0; spi->dev->slave.trans_done = 0;
#endif #endif
spi->dev->slave.val = 0; spi->dev->slave.val = 0;
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.val = 0; spi->dev->misc.val = 0;
#else #else
spi->dev->pin.val = 0; spi->dev->pin.val = 0;
@ -599,7 +674,7 @@ static void spiInitBus(spi_t * spi)
spi->dev->user.val = 0; spi->dev->user.val = 0;
spi->dev->user1.val = 0; spi->dev->user1.val = 0;
spi->dev->ctrl.val = 0; spi->dev->ctrl.val = 0;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->ctrl1.val = 0; spi->dev->ctrl1.val = 0;
spi->dev->ctrl2.val = 0; spi->dev->ctrl2.val = 0;
#else #else
@ -652,6 +727,14 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN); DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST); DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST);
} }
#elif CONFIG_IDF_TARGET_ESP32S3
if(spi_num == FSPI) {
periph_module_reset( PERIPH_SPI2_MODULE );
periph_module_enable( PERIPH_SPI2_MODULE );
} else if(spi_num == HSPI) {
periph_module_reset( PERIPH_SPI3_MODULE );
periph_module_enable( PERIPH_SPI3_MODULE );
}
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
if(spi_num == HSPI) { if(spi_num == HSPI) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN); DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN);
@ -670,7 +753,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spiInitBus(spi); spiInitBus(spi);
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->clk_gate.clk_en = 1; spi->dev->clk_gate.clk_en = 1;
spi->dev->clk_gate.mst_clk_sel = 1; spi->dev->clk_gate.mst_clk_sel = 1;
spi->dev->clk_gate.mst_clk_active = 1; spi->dev->clk_gate.mst_clk_active = 1;
@ -707,7 +790,7 @@ void spiWaitReady(spi_t * spi)
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
#define usr_mosi_dbitlen usr_mosi_bit_len #define usr_mosi_dbitlen usr_mosi_bit_len
#define usr_miso_dbitlen usr_miso_bit_len #define usr_miso_dbitlen usr_miso_bit_len
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
#define usr_mosi_dbitlen ms_data_bitlen #define usr_mosi_dbitlen ms_data_bitlen
#define usr_miso_dbitlen ms_data_bitlen #define usr_miso_dbitlen ms_data_bitlen
#define mosi_dlen ms_dlen #define mosi_dlen ms_dlen
@ -725,13 +808,13 @@ void spiWrite(spi_t * spi, const uint32_t *data, uint8_t len)
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1; spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
for(i=0; i<len; i++) { for(i=0; i<len; i++) {
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
} }
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -755,7 +838,7 @@ void spiTransfer(spi_t * spi, uint32_t *data, uint8_t len)
for(i=0; i<len; i++) { for(i=0; i<len; i++) {
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
} }
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -774,11 +857,11 @@ void spiWriteByte(spi_t * spi, uint8_t data)
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -796,7 +879,7 @@ uint8_t spiTransferByte(spi_t * spi, uint8_t data)
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_dbitlen = 7; spi->dev->miso_dlen.usr_miso_dbitlen = 7;
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -827,11 +910,11 @@ void spiWriteWord(spi_t * spi, uint16_t data)
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -852,7 +935,7 @@ uint16_t spiTransferWord(spi_t * spi, uint16_t data)
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
spi->dev->miso_dlen.usr_miso_dbitlen = 15; spi->dev->miso_dlen.usr_miso_dbitlen = 15;
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -876,11 +959,11 @@ void spiWriteLong(spi_t * spi, uint32_t data)
} }
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -901,7 +984,7 @@ uint32_t spiTransferLong(spi_t * spi, uint32_t data)
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
spi->dev->miso_dlen.usr_miso_dbitlen = 31; spi->dev->miso_dlen.usr_miso_dbitlen = 31;
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -944,7 +1027,7 @@ static void __spiTransferBytes(spi_t * spi, const uint8_t * data, uint8_t * out,
spi->dev->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo spi->dev->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo
} }
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1012,7 +1095,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
spi->dev->clock.val = clockDiv; spi->dev->clock.val = clockDiv;
switch (dataMode) { switch (dataMode) {
case SPI_MODE1: case SPI_MODE1:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.ck_idle_edge = 0; spi->dev->misc.ck_idle_edge = 0;
#else #else
spi->dev->pin.ck_idle_edge = 0; spi->dev->pin.ck_idle_edge = 0;
@ -1020,7 +1103,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
spi->dev->user.ck_out_edge = 1; spi->dev->user.ck_out_edge = 1;
break; break;
case SPI_MODE2: case SPI_MODE2:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.ck_idle_edge = 1; spi->dev->misc.ck_idle_edge = 1;
#else #else
spi->dev->pin.ck_idle_edge = 1; spi->dev->pin.ck_idle_edge = 1;
@ -1028,7 +1111,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
spi->dev->user.ck_out_edge = 1; spi->dev->user.ck_out_edge = 1;
break; break;
case SPI_MODE3: case SPI_MODE3:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.ck_idle_edge = 1; spi->dev->misc.ck_idle_edge = 1;
#else #else
spi->dev->pin.ck_idle_edge = 1; spi->dev->pin.ck_idle_edge = 1;
@ -1037,7 +1120,7 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
break; break;
case SPI_MODE0: case SPI_MODE0:
default: default:
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
spi->dev->misc.ck_idle_edge = 0; spi->dev->misc.ck_idle_edge = 0;
#else #else
spi->dev->pin.ck_idle_edge = 0; spi->dev->pin.ck_idle_edge = 0;
@ -1076,11 +1159,11 @@ void ARDUINO_ISR_ATTR spiWriteByteNL(spi_t * spi, uint8_t data)
return; return;
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1096,7 +1179,7 @@ uint8_t spiTransferByteNL(spi_t * spi, uint8_t data)
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_dbitlen = 7; spi->dev->miso_dlen.usr_miso_dbitlen = 7;
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1115,11 +1198,11 @@ void ARDUINO_ISR_ATTR spiWriteShortNL(spi_t * spi, uint16_t data)
MSB_16_SET(data, data); MSB_16_SET(data, data);
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1138,7 +1221,7 @@ uint16_t spiTransferShortNL(spi_t * spi, uint16_t data)
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
spi->dev->miso_dlen.usr_miso_dbitlen = 15; spi->dev->miso_dlen.usr_miso_dbitlen = 15;
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1160,11 +1243,11 @@ void ARDUINO_ISR_ATTR spiWriteLongNL(spi_t * spi, uint32_t data)
MSB_32_SET(data, data); MSB_32_SET(data, data);
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1183,7 +1266,7 @@ uint32_t spiTransferLongNL(spi_t * spi, uint32_t data)
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
spi->dev->miso_dlen.usr_miso_dbitlen = 31; spi->dev->miso_dlen.usr_miso_dbitlen = 31;
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1212,13 +1295,13 @@ void spiWriteNL(spi_t * spi, const void * data_in, uint32_t len){
c_longs = (longs > 16)?16:longs; c_longs = (longs > 16)?16:longs;
spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1; spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
for (int i=0; i<c_longs; i++) { for (int i=0; i<c_longs; i++) {
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
} }
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1258,7 +1341,7 @@ void spiTransferBytesNL(spi_t * spi, const void * data_in, uint8_t * data_out, u
spi->dev->data_buf[i] = 0xFFFFFFFF; spi->dev->data_buf[i] = 0xFFFFFFFF;
} }
} }
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1317,7 +1400,7 @@ void spiTransferBitsNL(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1); spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1);
spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1); spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1);
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1353,7 +1436,7 @@ void ARDUINO_ISR_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, uint32
l_bytes = (c_len & 3); l_bytes = (c_len & 3);
spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1; spi->dev->mosi_dlen.usr_mosi_dbitlen = (c_len*8)-1;
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
for (int i=0; i<c_longs; i++) { for (int i=0; i<c_longs; i++) {
@ -1371,7 +1454,7 @@ void ARDUINO_ISR_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, uint32
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
} }
} }
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1; spi->dev->cmd.update = 1;
while (spi->dev->cmd.update); while (spi->dev->cmd.update);
#endif #endif
@ -1397,7 +1480,7 @@ typedef union {
uint32_t clkcnt_l: 6; /*it must be equal to spi_clkcnt_N.*/ uint32_t clkcnt_l: 6; /*it must be equal to spi_clkcnt_N.*/
uint32_t clkcnt_h: 6; /*it must be floor((spi_clkcnt_N+1)/2-1).*/ uint32_t clkcnt_h: 6; /*it must be floor((spi_clkcnt_N+1)/2-1).*/
uint32_t clkcnt_n: 6; /*it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/ uint32_t clkcnt_n: 6; /*it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
uint32_t clkdiv_pre: 4; /*it is pre-divider of spi_clk.*/ uint32_t clkdiv_pre: 4; /*it is pre-divider of spi_clk.*/
uint32_t reserved: 9; /*reserved*/ uint32_t reserved: 9; /*reserved*/
#else #else
@ -1444,7 +1527,7 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
while(calPreVari++ <= 1) { while(calPreVari++ <= 1) {
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari; calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
if(calPre > 0xF) { if(calPre > 0xF) {
reg.clkdiv_pre = 0xF; reg.clkdiv_pre = 0xF;
#else #else
@ -1475,4 +1558,3 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
} }
return bestReg.value; return bestReg.value;
} }

View File

@ -25,7 +25,7 @@ extern "C" {
#define SPI_HAS_TRANSACTION #define SPI_HAS_TRANSACTION
#if CONFIG_IDF_TARGET_ESP32C3 #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
#define FSPI 0 #define FSPI 0
#define HSPI 1 #define HSPI 1
#else #else

View File

@ -44,8 +44,6 @@ static void setTimeZone(long offset, int daylight)
/* /*
* configTime * configTime
* Source: https://github.com/esp8266/Arduino/blob/master/cores/esp8266/time.c * Source: https://github.com/esp8266/Arduino/blob/master/cores/esp8266/time.c
* Note: Bundled Arduino lwip supports only ONE ntp server, 2nd and 3rd options are silently ignored
* see CONFIG_LWIP_DHCP_MAX_NTP_SERVERS define in ./tools/sdk/esp32/sdkconfig
* */ * */
void configTime(long gmtOffset_sec, int daylightOffset_sec, const char* server1, const char* server2, const char* server3) void configTime(long gmtOffset_sec, int daylightOffset_sec, const char* server1, const char* server2, const char* server3)
{ {
@ -65,8 +63,6 @@ void configTime(long gmtOffset_sec, int daylightOffset_sec, const char* server1,
/* /*
* configTzTime * configTzTime
* sntp setup using TZ environment variable * sntp setup using TZ environment variable
* Note: Bundled Arduino lwip supports only ONE ntp server, 2nd and 3rd options are silently ignored
* see CONFIG_LWIP_DHCP_MAX_NTP_SERVERS define in ./tools/sdk/esp32/sdkconfig
* */ * */
void configTzTime(const char* tz, const char* server1, const char* server2, const char* server3) void configTzTime(const char* tz, const char* server1, const char* server2, const char* server3)
{ {

View File

@ -13,335 +13,227 @@
// limitations under the License. // limitations under the License.
#include "esp32-hal-timer.h" #include "esp32-hal-timer.h"
#include "freertos/FreeRTOS.h" #include "driver/timer.h"
#ifndef CONFIG_IDF_TARGET_ESP32C3 #include "soc/soc_caps.h"
#include "freertos/xtensa_api.h"
#include "soc/dport_reg.h"
#endif
#include "freertos/task.h"
#include "soc/timer_group_struct.h"
#include "esp_attr.h"
#include "driver/periph_ctrl.h"
#include "esp_system.h" typedef union {
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ struct {
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 uint32_t reserved0: 10;
#include "esp32/rom/ets_sys.h" uint32_t alarm_en: 1; /*When set alarm is enabled*/
#include "esp_intr_alloc.h" uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/
#elif CONFIG_IDF_TARGET_ESP32S2 uint32_t edge_int_en: 1; /*When set edge type interrupt will be generated during alarm*/
#include "esp32s2/rom/ets_sys.h" uint32_t divider: 16; /*Timer clock (T0/1_clk) pre-scale value.*/
#include "esp_intr_alloc.h" uint32_t autoreload: 1; /*When set timer 0/1 auto-reload at alarming is enabled*/
#include "soc/periph_defs.h" uint32_t increase: 1; /*When set timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/
#elif CONFIG_IDF_TARGET_ESP32C3 uint32_t enable: 1; /*When set timer 0/1 time-base counter is enabled*/
#include "esp32c3/rom/ets_sys.h" };
#include "esp_intr_alloc.h" uint32_t val;
#include "soc/periph_defs.h" } timer_cfg_t;
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#include "esp_intr.h"
#endif
#define HWTIMER_LOCK() portENTER_CRITICAL(timer->lock) #define NUM_OF_TIMERS SOC_TIMER_GROUP_TOTAL_TIMERS
#define HWTIMER_UNLOCK() portEXIT_CRITICAL(timer->lock)
typedef volatile struct { typedef struct {
union { int timer_group;
struct { int timer_idx;
uint32_t reserved0: 10; int alarm_interval;
uint32_t alarm_en: 1; /*When set alarm is enabled*/ bool auto_reload;
uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/ } timer_info_t;
uint32_t edge_int_en: 1; /*When set edge type interrupt will be generated during alarm*/
uint32_t divider: 16; /*Timer clock (T0/1_clk) pre-scale value.*/
uint32_t autoreload: 1; /*When set timer 0/1 auto-reload at alarming is enabled*/
uint32_t increase: 1; /*When set timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/
uint32_t enable: 1; /*When set timer 0/1 time-base counter is enabled*/
};
uint32_t val;
} config;
uint32_t cnt_low; /*Register to store timer 0/1 time-base counter current value lower 32 bits.*/
uint32_t cnt_high; /*Register to store timer 0 time-base counter current value higher 32 bits.*/
uint32_t update; /*Write any value will trigger a timer 0 time-base counter value update (timer 0 current value will be stored in registers above)*/
uint32_t alarm_low; /*Timer 0 time-base counter value lower 32 bits that will trigger the alarm*/
uint32_t alarm_high; /*Timer 0 time-base counter value higher 32 bits that will trigger the alarm*/
uint32_t load_low; /*Lower 32 bits of the value that will load into timer 0 time-base counter*/
uint32_t load_high; /*higher 32 bits of the value that will load into timer 0 time-base counter*/
uint32_t reload; /*Write any value will trigger timer 0 time-base counter reload*/
} hw_timer_reg_t;
typedef struct hw_timer_s { typedef struct hw_timer_s
hw_timer_reg_t * dev; {
uint8_t num; uint8_t group;
uint8_t group; uint8_t num;
uint8_t timer;
portMUX_TYPE lock;
} hw_timer_t; } hw_timer_t;
static hw_timer_t hw_timer[4] = { // Works for all chips
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE),0,0,0,portMUX_INITIALIZER_UNLOCKED}, static hw_timer_t timer_dev[4] = {
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x0024),1,0,1,portMUX_INITIALIZER_UNLOCKED}, {0,0}, {1,0}, {1,0}, {1,1}
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1000),2,1,0,portMUX_INITIALIZER_UNLOCKED},
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1024),3,1,1,portMUX_INITIALIZER_UNLOCKED}
}; };
typedef void (*voidFuncPtr)(void); // NOTE: (in IDF 5.0 there wont be need to know groups/numbers
static voidFuncPtr __timerInterruptHandlers[4] = {0,0,0,0}; // timer_init() will list thru all timers and return free timer handle)
void ARDUINO_ISR_ATTR __timerISR(void * arg){
uint32_t s0 = TIMERG0.int_st_timers.val;
uint32_t s1 = TIMERG1.int_st_timers.val;
TIMERG0.int_clr_timers.val = s0;
TIMERG1.int_clr_timers.val = s1;
uint8_t status = (s1 & 3) << 2 | (s0 & 3);
uint8_t i = 4;
//restart the timers that should autoreload
while(i--){
hw_timer_reg_t * dev = hw_timer[i].dev;
if((status & (1 << i)) && dev->config.autoreload){
dev->config.alarm_en = 1;
}
}
i = 4;
//call callbacks
while(i--){
if(__timerInterruptHandlers[i] && (status & (1 << i))){
__timerInterruptHandlers[i]();
}
}
}
uint64_t inline timerRead(hw_timer_t *timer){ uint64_t inline timerRead(hw_timer_t *timer){
timer->dev->update = 1;
while (timer->dev->update) {}; uint64_t value;
uint64_t h = timer->dev->cnt_high; timer_get_counter_value(timer->group, timer->num,&value);
uint64_t l = timer->dev->cnt_low; return value;
return (h << 32) | l;
} }
uint64_t timerAlarmRead(hw_timer_t *timer){ uint64_t timerAlarmRead(hw_timer_t *timer){
uint64_t h = timer->dev->alarm_high; uint64_t value;
uint64_t l = timer->dev->alarm_low; timer_get_alarm_value(timer->group, timer->num, &value);
return (h << 32) | l; return value;
} }
void timerWrite(hw_timer_t *timer, uint64_t val){ void timerWrite(hw_timer_t *timer, uint64_t val){
timer->dev->load_high = (uint32_t) (val >> 32); timer_set_counter_value(timer->group, timer->num, val);
timer->dev->load_low = (uint32_t) (val);
timer->dev->reload = 1;
} }
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){ void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){
timer->dev->alarm_high = (uint32_t) (alarm_value >> 32); timer_set_alarm_value(timer->group, timer->num, alarm_value);
timer->dev->alarm_low = (uint32_t) alarm_value; timerSetAutoReload(timer,autoreload);
timer->dev->config.autoreload = autoreload;
} }
void timerSetConfig(hw_timer_t *timer, uint32_t config){ void timerSetConfig(hw_timer_t *timer, uint32_t config){
timer->dev->config.val = config; timer_cfg_t cfg;
cfg.val = config;
timer_set_alarm(timer->group, timer->num, cfg.alarm_en);
timerSetDivider(timer,cfg.divider);
timerSetAutoReload(timer,cfg.autoreload);
timerSetCountUp(timer, cfg.increase);
if (cfg.enable) {
timerStart(timer);
}
else{
timerStop(timer);
}
return;
} }
uint32_t timerGetConfig(hw_timer_t *timer){ uint32_t timerGetConfig(hw_timer_t *timer){
return timer->dev->config.val; timer_config_t timer_cfg;
timer_get_config(timer->group, timer->num,&timer_cfg);
//Translate to default uint32_t
timer_cfg_t cfg;
cfg.alarm_en = timer_cfg.alarm_en;
cfg.autoreload = timer_cfg.auto_reload;
cfg.divider = timer_cfg.divider;
cfg.edge_int_en = timer_cfg.intr_type;
cfg.level_int_en = !timer_cfg.intr_type;
cfg.enable = timer_cfg.counter_en;
cfg.increase = timer_cfg.counter_dir;
return cfg.val;
} }
void timerSetCountUp(hw_timer_t *timer, bool countUp){ void timerSetCountUp(hw_timer_t *timer, bool countUp){
timer->dev->config.increase = countUp; timer_set_counter_mode(timer->group, timer->num,countUp);
} }
bool timerGetCountUp(hw_timer_t *timer){ bool timerGetCountUp(hw_timer_t *timer){
return timer->dev->config.increase; timer_cfg_t config;
config.val = timerGetConfig(timer);
return config.increase;
} }
void timerSetAutoReload(hw_timer_t *timer, bool autoreload){ void timerSetAutoReload(hw_timer_t *timer, bool autoreload){
timer->dev->config.autoreload = autoreload; timer_set_auto_reload(timer->group, timer->num,autoreload);
} }
bool timerGetAutoReload(hw_timer_t *timer){ bool timerGetAutoReload(hw_timer_t *timer){
return timer->dev->config.autoreload; timer_cfg_t config;
config.val= timerGetConfig(timer);
return config.autoreload;
} }
void timerSetDivider(hw_timer_t *timer, uint16_t divider){//2 to 65536 // Set divider from 2 to 65535
if(!divider){ void timerSetDivider(hw_timer_t *timer, uint16_t divider){
divider = 0xFFFF; if(divider < 2)
} else if(divider == 1){ {
divider = 2; log_e("Timer divider must be set in range of 2 to 65535");
return;
} }
int timer_en = timer->dev->config.enable; timer_set_divider(timer->group, timer->num,divider);
timer->dev->config.enable = 0;
timer->dev->config.divider = divider;
timer->dev->config.enable = timer_en;
} }
uint16_t timerGetDivider(hw_timer_t *timer){ uint16_t timerGetDivider(hw_timer_t *timer){
return timer->dev->config.divider; timer_cfg_t config;
config.val = timerGetConfig(timer);
return config.divider;
} }
void timerStart(hw_timer_t *timer){ void timerStart(hw_timer_t *timer){
timer->dev->config.enable = 1; timer_start(timer->group, timer->num);
} }
void timerStop(hw_timer_t *timer){ void timerStop(hw_timer_t *timer){
timer->dev->config.enable = 0; timer_pause(timer->group, timer->num);
} }
void timerRestart(hw_timer_t *timer){ void timerRestart(hw_timer_t *timer){
timer->dev->config.enable = 0; timerWrite(timer,0);
timer->dev->reload = 1;
timer->dev->config.enable = 1;
} }
bool timerStarted(hw_timer_t *timer){ bool timerStarted(hw_timer_t *timer){
return timer->dev->config.enable; timer_cfg_t config;
config.val = timerGetConfig(timer);
return config.enable;
} }
void timerAlarmEnable(hw_timer_t *timer){ void timerAlarmEnable(hw_timer_t *timer){
timer->dev->config.alarm_en = 1; timer_set_alarm(timer->group, timer->num,true);
} }
void timerAlarmDisable(hw_timer_t *timer){ void timerAlarmDisable(hw_timer_t *timer){
timer->dev->config.alarm_en = 0; timer_set_alarm(timer->group, timer->num,false);
} }
bool timerAlarmEnabled(hw_timer_t *timer){ bool timerAlarmEnabled(hw_timer_t *timer){
return timer->dev->config.alarm_en; timer_cfg_t config;
config.val = timerGetConfig(timer);
return config.alarm_en;
} }
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
hw_timer_t * timer = (hw_timer_t *)arg; hw_timer_t * timer = (hw_timer_t *)arg;
if(ev_type == APB_BEFORE_CHANGE){ if(ev_type == APB_BEFORE_CHANGE){
timer->dev->config.enable = 0; timerStop(timer);
} else { } else {
old_apb /= 1000000; old_apb /= 1000000;
new_apb /= 1000000; new_apb /= 1000000;
timer->dev->config.divider = (new_apb * timer->dev->config.divider) / old_apb; uint16_t divider = (new_apb * timerGetDivider(timer)) / old_apb;
timer->dev->config.enable = 1; timerSetDivider(timer,divider);
timerStart(timer);
} }
} }
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){ hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
if(num > 3){ if(num >= NUM_OF_TIMERS)
{
log_e("Timer dont have that timer number.");
return NULL; return NULL;
} }
hw_timer_t * timer = &hw_timer[num];
if(timer->group) { hw_timer_t * timer = &timer_dev[num]; //Get Timer group/num from 0-3 number
periph_module_enable(PERIPH_TIMG1_MODULE);
} else { timer_config_t config = {
periph_module_enable(PERIPH_TIMG0_MODULE); .divider = divider,
} .counter_dir = countUp,
timer->dev->config.enable = 0; .counter_en = TIMER_PAUSE,
if(timer->group) { .alarm_en = TIMER_ALARM_DIS,
#if CONFIG_IDF_TARGET_ESP32 .auto_reload = false,
TIMERG1.int_ena.val &= ~BIT(timer->timer); };
#else
TIMERG1.int_ena_timers.val &= ~BIT(timer->timer); timer_init(timer->group, timer->num, &config);
#endif timer_set_counter_value(timer->group, timer->num, 0);
TIMERG1.int_clr_timers.val |= BIT(timer->timer); timerStart(timer);
} else {
#if CONFIG_IDF_TARGET_ESP32
TIMERG0.int_ena.val &= ~BIT(timer->timer);
#else
TIMERG0.int_ena_timers.val &= ~BIT(timer->timer);
#endif
TIMERG0.int_clr_timers.val |= BIT(timer->timer);
}
#ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK
timer->dev->config.use_xtal = 0;
#endif
timerSetDivider(timer, divider);
timerSetCountUp(timer, countUp);
timerSetAutoReload(timer, false);
timerAttachInterrupt(timer, NULL, false);
timerWrite(timer, 0);
timer->dev->config.enable = 1;
addApbChangeCallback(timer, _on_apb_change); addApbChangeCallback(timer, _on_apb_change);
return timer; return timer;
} }
void timerEnd(hw_timer_t *timer){ void timerEnd(hw_timer_t *timer){
timer->dev->config.enable = 0;
timerAttachInterrupt(timer, NULL, false);
removeApbChangeCallback(timer, _on_apb_change); removeApbChangeCallback(timer, _on_apb_change);
timer_deinit(timer->group, timer->num);
} }
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){ void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
#if CONFIG_IDF_TARGET_ESP32
if(edge){ if(edge){
log_w("EDGE timer interrupt does not work properly on ESP32! Setting to LEVEL..."); log_w("EDGE timer interrupt is not supported! Setting to LEVEL...");
edge = false; edge = false;
} }
#endif timer_enable_intr(timer->group, timer->num);
static bool initialized = false;
static intr_handle_t intr_handle = NULL; timer_info_t *timer_info = calloc(1, sizeof(timer_info_t));
if(intr_handle){ timer_info->timer_group = timer->group;
esp_intr_disable(intr_handle); timer_info->timer_idx = timer->num;
} timer_info->auto_reload = timerGetAutoReload(timer);
if(fn == NULL){ timer_info->alarm_interval = timerAlarmRead(timer);
timer->dev->config.level_int_en = 0;
timer->dev->config.edge_int_en = 0; timer_isr_callback_add(timer->group, timer->num, (timer_isr_t)fn, timer_info, 0);
timer->dev->config.alarm_en = 0;
if(timer->num & 2){
#if CONFIG_IDF_TARGET_ESP32
TIMERG1.int_ena.val &= ~BIT(timer->timer);
#else
TIMERG1.int_ena_timers.val &= ~BIT(timer->timer);
#endif
TIMERG1.int_clr_timers.val |= BIT(timer->timer);
} else {
#if CONFIG_IDF_TARGET_ESP32
TIMERG0.int_ena.val &= ~BIT(timer->timer);
#else
TIMERG0.int_ena_timers.val &= ~BIT(timer->timer);
#endif
TIMERG0.int_clr_timers.val |= BIT(timer->timer);
}
__timerInterruptHandlers[timer->num] = NULL;
} else {
__timerInterruptHandlers[timer->num] = fn;
timer->dev->config.level_int_en = edge?0:1;//When set, an alarm will generate a level type interrupt.
timer->dev->config.edge_int_en = edge?1:0;//When set, an alarm will generate an edge type interrupt.
int intr_source = 0;
#ifndef CONFIG_IDF_TARGET_ESP32C3
if(!edge){
#endif
if(timer->group){
intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer->timer;
} else {
intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer->timer;
}
#ifndef CONFIG_IDF_TARGET_ESP32C3
} else {
if(timer->group){
intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer->timer;
} else {
intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer->timer;
}
}
#endif
if(!initialized){
initialized = true;
esp_intr_alloc(intr_source, (int)(ARDUINO_ISR_FLAG|ESP_INTR_FLAG_LOWMED), __timerISR, NULL, &intr_handle);
} else {
intr_matrix_set(esp_intr_get_cpu(intr_handle), intr_source, esp_intr_get_intno(intr_handle));
}
if(timer->group){
#if CONFIG_IDF_TARGET_ESP32
TIMERG1.int_ena.val |= BIT(timer->timer);
#else
TIMERG1.int_ena_timers.val |= BIT(timer->timer);
#endif
} else {
#if CONFIG_IDF_TARGET_ESP32
TIMERG0.int_ena.val |= BIT(timer->timer);
#else
TIMERG0.int_ena_timers.val |= BIT(timer->timer);
#endif
}
}
if(intr_handle){
esp_intr_enable(intr_handle);
}
} }
void timerDetachInterrupt(hw_timer_t *timer){ void timerDetachInterrupt(hw_timer_t *timer){
@ -354,6 +246,12 @@ uint64_t timerReadMicros(hw_timer_t *timer){
return timer_val * div / (getApbFrequency() / 1000000); return timer_val * div / (getApbFrequency() / 1000000);
} }
uint64_t timerReadMilis(hw_timer_t *timer){
uint64_t timer_val = timerRead(timer);
uint16_t div = timerGetDivider(timer);
return timer_val * div / (getApbFrequency() / 1000);
}
double timerReadSeconds(hw_timer_t *timer){ double timerReadSeconds(hw_timer_t *timer){
uint64_t timer_val = timerRead(timer); uint64_t timer_val = timerRead(timer);
uint16_t div = timerGetDivider(timer); uint16_t div = timerGetDivider(timer);
@ -366,6 +264,12 @@ uint64_t timerAlarmReadMicros(hw_timer_t *timer){
return timer_val * div / (getApbFrequency() / 1000000); return timer_val * div / (getApbFrequency() / 1000000);
} }
uint64_t timerAlarmReadMilis(hw_timer_t *timer){
uint64_t timer_val = timerAlarmRead(timer);
uint16_t div = timerGetDivider(timer);
return timer_val * div / (getApbFrequency() / 1000);
}
double timerAlarmReadSeconds(hw_timer_t *timer){ double timerAlarmReadSeconds(hw_timer_t *timer){
uint64_t timer_val = timerAlarmRead(timer); uint64_t timer_val = timerAlarmRead(timer);
uint16_t div = timerGetDivider(timer); uint16_t div = timerGetDivider(timer);

View File

@ -20,13 +20,13 @@
#ifndef MAIN_ESP32_HAL_TIMER_H_ #ifndef MAIN_ESP32_HAL_TIMER_H_
#define MAIN_ESP32_HAL_TIMER_H_ #define MAIN_ESP32_HAL_TIMER_H_
#include "esp32-hal.h"
#include "freertos/FreeRTOS.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "esp32-hal.h"
#include "freertos/FreeRTOS.h"
struct hw_timer_s; struct hw_timer_s;
typedef struct hw_timer_s hw_timer_t; typedef struct hw_timer_s hw_timer_t;
@ -50,6 +50,7 @@ void timerSetAutoReload(hw_timer_t *timer, bool autoreload);
bool timerStarted(hw_timer_t *timer); bool timerStarted(hw_timer_t *timer);
uint64_t timerRead(hw_timer_t *timer); uint64_t timerRead(hw_timer_t *timer);
uint64_t timerReadMicros(hw_timer_t *timer); uint64_t timerReadMicros(hw_timer_t *timer);
uint64_t timerReadMilis(hw_timer_t *timer);
double timerReadSeconds(hw_timer_t *timer); double timerReadSeconds(hw_timer_t *timer);
uint16_t timerGetDivider(hw_timer_t *timer); uint16_t timerGetDivider(hw_timer_t *timer);
bool timerGetCountUp(hw_timer_t *timer); bool timerGetCountUp(hw_timer_t *timer);
@ -57,7 +58,7 @@ bool timerGetAutoReload(hw_timer_t *timer);
void timerAlarmEnable(hw_timer_t *timer); void timerAlarmEnable(hw_timer_t *timer);
void timerAlarmDisable(hw_timer_t *timer); void timerAlarmDisable(hw_timer_t *timer);
void timerAlarmWrite(hw_timer_t *timer, uint64_t interruptAt, bool autoreload); void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload);
bool timerAlarmEnabled(hw_timer_t *timer); bool timerAlarmEnabled(hw_timer_t *timer);
uint64_t timerAlarmRead(hw_timer_t *timer); uint64_t timerAlarmRead(hw_timer_t *timer);

View File

@ -34,9 +34,16 @@
#include "esp32-hal.h" #include "esp32-hal.h"
#include "esp32-hal-tinyusb.h" #include "esp32-hal-tinyusb.h"
#if CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/usb/usb_persist.h" #include "esp32s2/rom/usb/usb_persist.h"
#include "esp32s2/rom/usb/usb_dc.h" #include "esp32s2/rom/usb/usb_dc.h"
#include "esp32s2/rom/usb/chip_usb_dw_wrapper.h" #include "esp32s2/rom/usb/chip_usb_dw_wrapper.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "hal/usb_serial_jtag_ll.h"
#include "esp32s3/rom/usb/usb_persist.h"
#include "esp32s3/rom/usb/usb_dc.h"
#include "esp32s3/rom/usb/chip_usb_dw_wrapper.h"
#endif
typedef enum{ typedef enum{
TINYUSB_USBDEV_0, TINYUSB_USBDEV_0,
@ -370,6 +377,120 @@ __attribute__ ((weak)) int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_
static bool usb_persist_enabled = false; static bool usb_persist_enabled = false;
static restart_type_t usb_persist_mode = RESTART_NO_PERSIST; static restart_type_t usb_persist_mode = RESTART_NO_PERSIST;
#if CONFIG_IDF_TARGET_ESP32S3
static void hw_cdc_reset_handler(void *arg) {
portBASE_TYPE xTaskWoken = 0;
uint32_t usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask();
usb_serial_jtag_ll_clr_intsts_mask(usbjtag_intr_status);
if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_BUS_RESET) {
xSemaphoreGiveFromISR((xSemaphoreHandle)arg, &xTaskWoken);
}
if (xTaskWoken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
static void usb_switch_to_cdc_jtag(){
// Disable USB-OTG
periph_module_reset(PERIPH_USB_MODULE);
//periph_module_enable(PERIPH_USB_MODULE);
periph_module_disable(PERIPH_USB_MODULE);
// Switch to hardware CDC+JTAG
CLEAR_PERI_REG_MASK(RTC_CNTL_USB_CONF_REG, (RTC_CNTL_SW_HW_USB_PHY_SEL|RTC_CNTL_SW_USB_PHY_SEL|RTC_CNTL_USB_PAD_ENABLE));
// Do not use external PHY
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PHY_SEL);
// Release GPIO pins from CDC+JTAG
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
// Force the host to re-enumerate (BUS_RESET)
pinMode(USBPHY_DM_NUM, OUTPUT_OPEN_DRAIN);
pinMode(USBPHY_DP_NUM, OUTPUT_OPEN_DRAIN);
digitalWrite(USBPHY_DM_NUM, LOW);
digitalWrite(USBPHY_DP_NUM, LOW);
// Initialize CDC+JTAG ISR to listen for BUS_RESET
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_BUS_RESET);
intr_handle_t intr_handle = NULL;
xSemaphoreHandle reset_sem = xSemaphoreCreateBinary();
if(reset_sem){
if(esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, 0, hw_cdc_reset_handler, reset_sem, &intr_handle) != ESP_OK){
vSemaphoreDelete(reset_sem);
reset_sem = NULL;
log_e("HW USB CDC failed to init interrupts");
}
} else {
log_e("reset_sem init failed");
}
// Connect GPIOs to integrated CDC+JTAG
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
// Wait for BUS_RESET to give us back the semaphore
if(reset_sem){
if(xSemaphoreTake(reset_sem, 1000 / portTICK_PERIOD_MS) != pdPASS){
log_e("reset_sem timeout");
}
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
esp_intr_free(intr_handle);
vSemaphoreDelete(reset_sem);
}
}
#endif
static void IRAM_ATTR usb_persist_shutdown_handler(void)
{
if(usb_persist_mode != RESTART_NO_PERSIST){
if (usb_persist_enabled) {
usb_dc_prepare_persist();
}
if (usb_persist_mode == RESTART_BOOTLOADER) {
//USB CDC Download
if (usb_persist_enabled) {
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
#if CONFIG_IDF_TARGET_ESP32S2
} else {
periph_module_reset(PERIPH_USB_MODULE);
periph_module_enable(PERIPH_USB_MODULE);
#endif
}
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
} else if (usb_persist_mode == RESTART_BOOTLOADER_DFU) {
//DFU Download
#if CONFIG_IDF_TARGET_ESP32S2
// Reset USB Core
USB0.grstctl |= USB_CSFTRST;
while ((USB0.grstctl & USB_CSFTRST) == USB_CSFTRST){}
#endif
chip_usb_set_persist_flags(USBDC_BOOT_DFU);
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
} else if (usb_persist_enabled) {
//USB Persist reboot
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
}
}
}
void usb_persist_restart(restart_type_t mode)
{
if (mode < RESTART_TYPE_MAX && esp_register_shutdown_handler(usb_persist_shutdown_handler) == ESP_OK) {
usb_persist_mode = mode;
#if CONFIG_IDF_TARGET_ESP32S3
if (mode == RESTART_BOOTLOADER) {
usb_switch_to_cdc_jtag();
}
#endif
esp_restart();
}
}
static bool tinyusb_reserve_in_endpoint(uint8_t endpoint){ static bool tinyusb_reserve_in_endpoint(uint8_t endpoint){
if(endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0){ if(endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0){
return false; return false;
@ -515,35 +636,6 @@ static void tinyusb_apply_device_config(tinyusb_device_config_t *config){
tinyusb_device_descriptor.bDeviceProtocol = config->usb_protocol; tinyusb_device_descriptor.bDeviceProtocol = config->usb_protocol;
} }
static void IRAM_ATTR usb_persist_shutdown_handler(void)
{
if(usb_persist_mode != RESTART_NO_PERSIST){
if (usb_persist_enabled) {
usb_dc_prepare_persist();
}
if (usb_persist_mode == RESTART_BOOTLOADER) {
//USB CDC Download
if (usb_persist_enabled) {
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
} else {
periph_module_reset(PERIPH_USB_MODULE);
periph_module_enable(PERIPH_USB_MODULE);
}
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
} else if (usb_persist_mode == RESTART_BOOTLOADER_DFU) {
//DFU Download
// Reset USB Core
USB0.grstctl |= USB_CSFTRST;
while ((USB0.grstctl & USB_CSFTRST) == USB_CSFTRST){}
chip_usb_set_persist_flags(USBDC_BOOT_DFU);
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
} else if (usb_persist_enabled) {
//USB Persist reboot
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
}
}
}
// USB Device Driver task // USB Device Driver task
// This top level thread processes all usb events and invokes callbacks // This top level thread processes all usb events and invokes callbacks
static void usb_device_task(void *param) { static void usb_device_task(void *param) {
@ -607,11 +699,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
periph_module_enable(PERIPH_USB_MODULE); periph_module_enable(PERIPH_USB_MODULE);
} }
if (esp_register_shutdown_handler(usb_persist_shutdown_handler) != ESP_OK) {
tinyusb_is_initialized = false;
return ESP_FAIL;
}
tinyusb_config_t tusb_cfg = { tinyusb_config_t tusb_cfg = {
.external_phy = false // In the most cases you need to use a `false` value .external_phy = false // In the most cases you need to use a `false` value
}; };
@ -624,14 +711,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
return err; return err;
} }
void usb_persist_restart(restart_type_t mode)
{
if (mode < RESTART_TYPE_MAX) {
usb_persist_mode = mode;
esp_restart();
}
}
uint8_t tinyusb_add_string_descriptor(const char * str){ uint8_t tinyusb_add_string_descriptor(const char * str){
if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){ if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){
return 0; return 0;

View File

@ -15,7 +15,6 @@
#include "esp32-hal.h" #include "esp32-hal.h"
#if CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_TINYUSB_ENABLED #if CONFIG_TINYUSB_ENABLED
#ifdef __cplusplus #ifdef __cplusplus
@ -105,4 +104,3 @@ uint8_t tinyusb_get_free_out_endpoint(void);
#endif #endif
#endif /* CONFIG_TINYUSB_ENABLED */ #endif /* CONFIG_TINYUSB_ENABLED */
#endif /* CONFIG_IDF_TARGET_ESP32S2 */

View File

@ -12,219 +12,268 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "esp32-hal-touch.h" #include "soc/soc_caps.h"
#ifndef CONFIG_IDF_TARGET_ESP32C3 #if SOC_TOUCH_SENSOR_NUM > 0
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_attr.h"
#include "soc/rtc_io_reg.h"
#include "soc/sens_reg.h"
#include "soc/sens_struct.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/touch_sensor.h" #include "driver/touch_sensor.h"
#include "esp32-hal-touch.h"
#include "esp_system.h" /*
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ Internal Private Touch Data Structure and Functions
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 */
#include "esp32/rom/ets_sys.h"
#include "esp_intr_alloc.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#include "esp_intr_alloc.h"
#include "soc/periph_defs.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#include "esp_intr.h"
#endif
#if SOC_TOUCH_VERSION_1 // ESP32
static uint16_t __touchSleepCycles = 0x1000; static uint16_t __touchSleepCycles = 0x1000;
static uint16_t __touchMeasureCycles = 0x1000; static uint16_t __touchMeasureCycles = 0x1000;
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
static uint16_t __touchSleepCycles = TOUCH_PAD_SLEEP_CYCLE_DEFAULT;
static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT;
#endif
typedef void (*voidFuncPtr)(void); typedef void (*voidFuncPtr)(void);
static voidFuncPtr __touchInterruptHandlers[10] = {0,}; typedef void (*voidArgFuncPtr)(void *);
static intr_handle_t touch_intr_handle = NULL;
void ARDUINO_ISR_ATTR __touchISR(void * arg) typedef struct {
voidFuncPtr fn;
bool callWithArgs;
void* arg;
#if SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
bool lastStatusIsPressed;
#endif
} TouchInterruptHandle_t;
static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = {0,};
static void ARDUINO_ISR_ATTR __touchISR(void * arg)
{ {
#if CONFIG_IDF_TARGET_ESP32 #if SOC_TOUCH_VERSION_1 // ESP32
uint32_t pad_intr = READ_PERI_REG(SENS_SAR_TOUCH_CTRL2_REG) & 0x3ff; uint32_t pad_intr = touch_pad_get_status();
uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG);
uint8_t i = 0;
//clear interrupt //clear interrupt
WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, rtc_intr); touch_pad_clear_status();
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR); // call Pad ISR User callback
for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
if (rtc_intr & RTC_CNTL_TOUCH_INT_ST) { if ((pad_intr >> i) & 0x01) {
for (i = 0; i < 10; ++i) { if(__touchInterruptHandlers[i].fn){
if ((pad_intr >> i) & 0x01) { // keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)"
if(__touchInterruptHandlers[i]){ if (__touchInterruptHandlers[i].callWithArgs) {
__touchInterruptHandlers[i](); ((voidArgFuncPtr)__touchInterruptHandlers[i].fn)(__touchInterruptHandlers[i].arg);
} else {
__touchInterruptHandlers[i].fn();
} }
} }
} }
} }
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
touch_pad_intr_mask_t evt = touch_pad_read_intr_status_mask();
uint8_t pad_num = touch_pad_get_current_meas_channel();
if (evt & TOUCH_PAD_INTR_MASK_ACTIVE) {
// touch has been pressed / touched
__touchInterruptHandlers[pad_num].lastStatusIsPressed = true;
}
if (evt & TOUCH_PAD_INTR_MASK_INACTIVE) {
// touch has been released / untouched
__touchInterruptHandlers[pad_num].lastStatusIsPressed = false;
}
if(__touchInterruptHandlers[pad_num].fn){
// keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)"
if (__touchInterruptHandlers[pad_num].callWithArgs) {
((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg);
} else {
__touchInterruptHandlers[pad_num].fn();
}
}
#endif #endif
} }
void __touchSetCycles(uint16_t measure, uint16_t sleep)
static void __touchSetCycles(uint16_t measure, uint16_t sleep)
{ {
__touchSleepCycles = sleep; __touchSleepCycles = sleep;
__touchMeasureCycles = measure; __touchMeasureCycles = measure;
#if CONFIG_IDF_TARGET_ESP32
//Touch pad SleepCycle Time
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_SLEEP_CYCLES, __touchSleepCycles, SENS_TOUCH_SLEEP_CYCLES_S);
//Touch Pad Measure Time
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_MEAS_DELAY, __touchMeasureCycles, SENS_TOUCH_MEAS_DELAY_S);
#else
touch_pad_set_meas_time(sleep, measure); touch_pad_set_meas_time(sleep, measure);
#endif
} }
void __touchInit()
static void __touchInit()
{ {
static bool initialized = false; static bool initialized = false;
if(initialized){ if(initialized){
return; return;
} }
initialized = true;
#if CONFIG_IDF_TARGET_ESP32 esp_err_t err = ESP_OK;
SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS, 1, RTC_IO_TOUCH_XPD_BIAS_S);
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR); #if SOC_TOUCH_VERSION_1 // ESP32
//clear touch enable err = touch_pad_init();
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, 0x0); if (err != ESP_OK) {
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_TOUCH_SLP_TIMER_EN); goto err;
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles); }
esp_intr_alloc(ETS_RTC_CORE_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, __touchISR, NULL, &touch_intr_handle); // the next two lines will drive the touch reading values -- both will return ESP_OK
#else touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V);
touch_pad_init(); touch_pad_set_meas_time(__touchMeasureCycles, __touchSleepCycles);
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V5); // Touch Sensor Timer initiated
touch_pad_set_idle_channel_connect(TOUCH_PAD_CONN_GND); touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles); err = touch_pad_filter_start(10);
if (err != ESP_OK) {
goto err;
}
// keep ISR activated - it can run all together (ISR + touchRead())
err = touch_pad_isr_register(__touchISR, NULL);
if (err != ESP_OK) {
goto err;
}
touch_pad_intr_enable(); // returns ESP_OK
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
err = touch_pad_init();
if (err != ESP_OK) {
goto err;
}
// the next lines will drive the touch reading values -- all os them return ESP_OK
touch_pad_set_meas_time(__touchSleepCycles, __touchMeasureCycles);
touch_pad_set_voltage(TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD);
touch_pad_set_idle_channel_connect(TOUCH_PAD_IDLE_CH_CONNECT_DEFAULT);
touch_pad_denoise_t denoise = { touch_pad_denoise_t denoise = {
.grade = TOUCH_PAD_DENOISE_BIT4, .grade = TOUCH_PAD_DENOISE_BIT4,
.cap_level = TOUCH_PAD_DENOISE_CAP_L4, .cap_level = TOUCH_PAD_DENOISE_CAP_L4,
}; };
touch_pad_denoise_set_config(&denoise); touch_pad_denoise_set_config(&denoise);
touch_pad_denoise_enable(); touch_pad_denoise_enable();
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // Touch Sensor Timer initiated
touch_pad_fsm_start(); touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK
touch_pad_fsm_start(); // returns ESP_OK
//ISR setup moved to __touchChannelInit
#endif #endif
initialized = true;
return;
err:
log_e(" Touch sensor initialization error.");
initialized = false;
return;
} }
uint16_t __touchRead(uint8_t pin) static void __touchChannelInit(int pad)
{
static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = { false };
if(channels_initialized[pad]){
return;
}
#if SOC_TOUCH_VERSION_1 // ESP32
// Initial no Threshold and setup
__touchInterruptHandlers[pad].fn = NULL;
touch_pad_config(pad, SOC_TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
// Initial no Threshold and setup
__touchInterruptHandlers[pad].fn = NULL;
touch_pad_config(pad); // returns ESP_OK
// keep ISR activated - it can run all together (ISR + touchRead())
esp_err_t err = touch_pad_isr_register(__touchISR, NULL, TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE);
if (err != ESP_OK) {
log_e(" Touch sensor initialization error.");
return;
}
touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); // returns ESP_OK
#endif
channels_initialized[pad] = true;
delay(20); //delay needed before reading from touch channel after config
}
static touch_value_t __touchRead(uint8_t pin)
{ {
int8_t pad = digitalPinToTouchChannel(pin); int8_t pad = digitalPinToTouchChannel(pin);
if(pad < 0){ if(pad < 0){
return 0; return 0;
} }
pinMode(pin, ANALOG);
__touchInit(); __touchInit();
__touchChannelInit(pad);
#if CONFIG_IDF_TARGET_ESP32 touch_value_t touch_value;
uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG); touch_pad_read_raw_data(pad, &touch_value);
//Disable Intr & enable touch pad
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG,
(v0 & ~((1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | (1 << (pad + SENS_TOUCH_PAD_OUTEN1_S))))
| (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
uint32_t rtc_tio_reg = RTC_IO_TOUCH_PAD0_REG + pad * 4;
WRITE_PERI_REG(rtc_tio_reg, (READ_PERI_REG(rtc_tio_reg)
& ~(RTC_IO_TOUCH_PAD0_DAC_M))
| (7 << RTC_IO_TOUCH_PAD0_DAC_S)//Touch Set Slope
| RTC_IO_TOUCH_PAD0_TIE_OPT_M //Enable Tie,Init Level
| RTC_IO_TOUCH_PAD0_START_M //Enable Touch Pad IO
| RTC_IO_TOUCH_PAD0_XPD_M); //Enable Touch Pad Power on
//force oneTime test start
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_XPD_WAIT, 10, SENS_TOUCH_XPD_WAIT_S);
while (GET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_DONE) == 0) {};
uint16_t touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (pad / 2) * 4) >> ((pad & 1) ? SENS_TOUCH_MEAS_OUT1_S : SENS_TOUCH_MEAS_OUT0_S);
//clear touch force ,select the Touch mode is Timer
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
//restore previous value
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0);
return touch_value; return touch_value;
#else
static uint32_t chan_mask = 0;
uint32_t value = 0;
if((chan_mask & (1 << pad)) == 0){
if(touch_pad_set_thresh((touch_pad_t)pad, TOUCH_PAD_THRESHOLD_MAX) != ESP_OK){
log_e("touch_pad_set_thresh failed");
} else if(touch_pad_config((touch_pad_t)pad) != ESP_OK){
log_e("touch_pad_config failed");
} else {
chan_mask |= (1 << pad);
}
}
if((chan_mask & (1 << pad)) != 0) {
if(touch_pad_read_raw_data((touch_pad_t)pad, &value) != ESP_OK){
log_e("touch_pad_read_raw_data failed");
}
}
return value;
#endif
} }
void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold) static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Args, touch_value_t threshold, bool callWithArgs)
{ {
int8_t pad = digitalPinToTouchChannel(pin); int8_t pad = digitalPinToTouchChannel(pin);
if(pad < 0){ if(pad < 0){
return; return;
} }
pinMode(pin, ANALOG); if (userFunc == NULL) {
// dettach ISR User Call
__touchInit(); __touchInterruptHandlers[pad].fn = NULL;
threshold = SOC_TOUCH_PAD_THRESHOLD_MAX; // deactivate the ISR with SOC_TOUCH_PAD_THRESHOLD_MAX
__touchInterruptHandlers[pad] = userFunc; } else {
// attach ISR User Call
#if CONFIG_IDF_TARGET_ESP32 __touchInit();
//clear touch force ,select the Touch mode is Timer #if SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M); __touchChannelInit(pad);
#endif
//interrupt when touch value < threshold __touchInterruptHandlers[pad].fn = userFunc;
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL); __touchInterruptHandlers[pad].callWithArgs = callWithArgs;
//Intr will give ,when SET0 < threshold __touchInterruptHandlers[pad].arg = Args;
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_1EN); }
//Enable Rtc Touch Module Intr,the Interrupt need Rtc out Enable
SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_TOUCH_INT_ENA);
//set threshold
uint8_t shift = (pad & 1) ? SENS_TOUCH_OUT_TH1_S : SENS_TOUCH_OUT_TH0_S;
SET_PERI_REG_BITS((SENS_SAR_TOUCH_THRES1_REG + (pad / 2) * 4), SENS_TOUCH_OUT_TH0, threshold, shift);
uint32_t rtc_tio_reg = RTC_IO_TOUCH_PAD0_REG + pad * 4;
WRITE_PERI_REG(rtc_tio_reg, (READ_PERI_REG(rtc_tio_reg)
& ~(RTC_IO_TOUCH_PAD0_DAC_M))
| (7 << RTC_IO_TOUCH_PAD0_DAC_S)//Touch Set Slope
| RTC_IO_TOUCH_PAD0_TIE_OPT_M //Enable Tie,Init Level
| RTC_IO_TOUCH_PAD0_START_M //Enable Touch Pad IO
| RTC_IO_TOUCH_PAD0_XPD_M); //Enable Touch Pad Power on
//Enable Digital rtc control :work mode and out mode
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG,
(1 << (pad + SENS_TOUCH_PAD_WORKEN_S)) | \
(1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | \
(1 << (pad + SENS_TOUCH_PAD_OUTEN1_S)));
#else
#if SOC_TOUCH_VERSION_1 // ESP32
touch_pad_config(pad, threshold);
#elif SOC_TOUCH_VERSION_2 // ESP32S2, ESP32S3
touch_pad_set_thresh(pad, threshold);
#endif #endif
} }
extern uint16_t touchRead(uint8_t pin) __attribute__ ((weak, alias("__touchRead"))); // it keeps backwards compatibility
extern void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold) __attribute__ ((weak, alias("__touchAttachInterrupt"))); static void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold)
extern void touchSetCycles(uint16_t measure, uint16_t sleep) __attribute__ ((weak, alias("__touchSetCycles"))); {
__touchConfigInterrupt(pin, userFunc, NULL, threshold, false);
}
// new additional version of the API with User Args
static void __touchAttachArgsInterrupt(uint8_t pin, void (*userFunc)(void), void *args, touch_value_t threshold)
{
__touchConfigInterrupt(pin, userFunc, args, threshold, true);
}
// new additional API to dettach touch ISR
static void __touchDettachInterrupt(uint8_t pin)
{
__touchConfigInterrupt(pin, NULL, NULL, 0, false); // userFunc as NULL acts as dettaching
}
/*
External Public Touch API Functions
*/
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
void touchInterruptSetThresholdDirection(bool mustbeLower) {
if (mustbeLower) {
touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW);
} else {
touch_pad_set_trigger_mode(TOUCH_TRIGGER_ABOVE);
}
}
#elif SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
// returns true if touch pad has been and continues pressed and false otherwise
bool touchInterruptGetLastStatus(uint8_t pin) {
int8_t pad = digitalPinToTouchChannel(pin);
if(pad < 0){
return false;
}
return __touchInterruptHandlers[pad].lastStatusIsPressed;
}
#endif #endif
extern touch_value_t touchRead(uint8_t) __attribute__ ((weak, alias("__touchRead")));
extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribute__ ((weak, alias("__touchAttachInterrupt")));
extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__ ((weak, alias("__touchAttachArgsInterrupt")));
extern void touchDetachInterrupt(uint8_t) __attribute__ ((weak, alias("__touchDettachInterrupt")));
extern void touchSetCycles(uint16_t, uint16_t) __attribute__ ((weak, alias("__touchSetCycles")));
#endif // #if SOC_TOUCH_SENSOR_NUM > 0

View File

@ -24,8 +24,21 @@
extern "C" { extern "C" {
#endif #endif
#include "soc/soc_caps.h"
#include "esp32-hal.h" #include "esp32-hal.h"
#if SOC_TOUCH_SENSOR_NUM > 0
#if !defined(SOC_TOUCH_VERSION_1) && !defined(SOC_TOUCH_VERSION_2)
#error Touch IDF driver Not supported!
#endif
#if SOC_TOUCH_VERSION_1 // ESP32
typedef uint16_t touch_value_t;
#elif SOC_TOUCH_VERSION_2 // ESP32S2 ESP32S3
typedef uint32_t touch_value_t;
#endif
/* /*
* Set cycles that measurement operation takes * Set cycles that measurement operation takes
* The result from touchRead, threshold and detection * The result from touchRead, threshold and detection
@ -40,17 +53,44 @@ void touchSetCycles(uint16_t measure, uint16_t sleep);
* You can use this method to chose a good threshold value * You can use this method to chose a good threshold value
* to use as value for touchAttachInterrupt * to use as value for touchAttachInterrupt
* */ * */
uint16_t touchRead(uint8_t pin); touch_value_t touchRead(uint8_t pin);
/* /*
* Set function to be called if touch pad value falls * Set function to be called if touch pad value falls (ESP32)
* below the given threshold. Use touchRead to determine * below the given threshold / rises (ESP32-S2/S3) by given increment (threshold).
* a proper threshold between touched and untouched state * Use touchRead to determine a proper threshold between touched and untouched state
* */ * */
void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold); void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold);
void touchAttachInterruptArg(uint8_t pin, void (*userFunc)(void*), void *arg, touch_value_t threshold);
void touchDetachInterrupt(uint8_t pin);
/*
* Specific functions to ESP32
* Tells the driver if it shall activate the ISR if the sensor is Lower or Higher than the Threshold
* Default if Lower.
**/
#if SOC_TOUCH_VERSION_1 // Only for ESP32 SoC
void touchInterruptSetThresholdDirection(bool mustbeLower);
#endif
/*
* Specific functions to ESP32-S2 and ESP32-S3
* Returns true when the latest ISR status for the Touchpad is that it is touched (Active)
* and false when the Touchpad is untoouched (Inactive)
* This function can be used in conjunction with ISR User callback in order to take action
* as soon as the touchpad is touched and/or released
**/
#if SOC_TOUCH_VERSION_2 // Only for ESP32S2 and ESP32S3
// returns true if touch pad has been and continues pressed and false otherwise
bool touchInterruptGetLastStatus(uint8_t pin);
#endif
#endif // SOC_TOUCH_SENSOR_NUM > 0
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */ #endif /* MAIN_ESP32_HAL_TOUCH_H_ */

View File

@ -34,7 +34,7 @@ struct uart_struct_t {
uint8_t num; uint8_t num;
bool has_peek; bool has_peek;
uint8_t peek_byte; uint8_t peek_byte;
QueueHandle_t uart_event_queue; // export it by some uartGetEventQueue() function
}; };
#if CONFIG_DISABLE_HAL_LOCKS #if CONFIG_DISABLE_HAL_LOCKS
@ -43,12 +43,12 @@ struct uart_struct_t {
#define UART_MUTEX_UNLOCK() #define UART_MUTEX_UNLOCK()
static uart_t _uart_bus_array[] = { static uart_t _uart_bus_array[] = {
{0, false, 0}, {0, false, 0, NULL},
#if SOC_UART_NUM > 1 #if SOC_UART_NUM > 1
{1, false, 0}, {1, false, 0, NULL},
#endif #endif
#if SOC_UART_NUM > 2 #if SOC_UART_NUM > 2
{2, false, 0}, {2, false, 0, NULL},
#endif #endif
}; };
@ -58,21 +58,46 @@ static uart_t _uart_bus_array[] = {
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock) #define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
static uart_t _uart_bus_array[] = { static uart_t _uart_bus_array[] = {
{NULL, 0, false, 0}, {NULL, 0, false, 0, NULL},
#if SOC_UART_NUM > 1 #if SOC_UART_NUM > 1
{NULL, 1, false, 0}, {NULL, 1, false, 0, NULL},
#endif #endif
#if SOC_UART_NUM > 2 #if SOC_UART_NUM > 2
{NULL, 2, false, 0}, {NULL, 2, false, 0, NULL},
#endif #endif
}; };
#endif #endif
// solves issue https://github.com/espressif/arduino-esp32/issues/6032
// baudrate must be multiplied when CPU Frequency is lower than APB 80MHz
uint32_t _get_effective_baudrate(uint32_t baudrate)
{
uint32_t Freq = getApbFrequency()/1000000;
if (Freq < 80) {
return 80 / Freq * baudrate;
}
else {
return baudrate;
}
}
// Routines that take care of UART events will be in the HardwareSerial Class code
void uartGetEventQueue(uart_t* uart, QueueHandle_t *q)
{
// passing back NULL for the Queue pointer when UART is not initialized yet
*q = NULL;
if(uart == NULL) {
return;
}
*q = uart->uart_event_queue;
return;
}
bool uartIsDriverInstalled(uart_t* uart) bool uartIsDriverInstalled(uart_t* uart)
{ {
if(uart == NULL) { if(uart == NULL) {
return 0; return false;
} }
if (uart_is_driver_installed(uart->num)) { if (uart_is_driver_installed(uart->num)) {
@ -81,28 +106,36 @@ bool uartIsDriverInstalled(uart_t* uart)
return false; return false;
} }
void uartSetPins(uart_t* uart, uint8_t rxPin, uint8_t txPin) // Valid pin UART_PIN_NO_CHANGE is defined to (-1)
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
void uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
{ {
if(uart == NULL || rxPin >= SOC_GPIO_PIN_COUNT || txPin >= SOC_GPIO_PIN_COUNT) { if(uart == NULL) {
return; return;
} }
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
ESP_ERROR_CHECK(uart_set_pin(uart->num, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); // IDF uart_set_pin() will issue necessary Error Message and take care of all GPIO Number validation.
UART_MUTEX_UNLOCK(); uart_set_pin(uart->num, txPin, rxPin, ctsPin, rtsPin);
UART_MUTEX_UNLOCK();
}
//
void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold) {
if(uart == NULL) {
return;
}
// IDF will issue corresponding error message when mode or threshold are wrong and prevent crashing
// IDF will check (mode > HW_FLOWCTRL_CTS_RTS || threshold >= SOC_UART_FIFO_LEN)
uart_set_hw_flow_ctrl(uart->num, (uart_hw_flowcontrol_t) mode, threshold);
} }
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted, uint8_t rxfifo_full_thrhd) uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t rx_buffer_size, uint16_t tx_buffer_size, bool inverted, uint8_t rxfifo_full_thrhd)
{ {
if(uart_nr >= SOC_UART_NUM) { if(uart_nr >= SOC_UART_NUM) {
return NULL; return NULL;
} }
if(rxPin == -1 && txPin == -1) {
return NULL;
}
uart_t* uart = &_uart_bus_array[uart_nr]; uart_t* uart = &_uart_bus_array[uart_nr];
if (uart_is_driver_installed(uart_nr)) { if (uart_is_driver_installed(uart_nr)) {
@ -121,7 +154,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
uart_config_t uart_config; uart_config_t uart_config;
uart_config.baud_rate = baudrate; uart_config.baud_rate = _get_effective_baudrate(baudrate);
uart_config.data_bits = (config & 0xc) >> 2; uart_config.data_bits = (config & 0xc) >> 2;
uart_config.parity = (config & 0x3); uart_config.parity = (config & 0x3);
uart_config.stop_bits = (config & 0x30) >> 4; uart_config.stop_bits = (config & 0x30) >> 4;
@ -130,7 +163,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
uart_config.source_clk = UART_SCLK_APB; uart_config.source_clk = UART_SCLK_APB;
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 0, NULL, 0)); ESP_ERROR_CHECK(uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0));
ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config)); ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
@ -290,7 +323,7 @@ void uartFlushTxOnly(uart_t* uart, bool txOnly)
} }
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
ESP_ERROR_CHECK(uart_wait_tx_done(uart->num, portMAX_DELAY)); while(!uart_ll_is_tx_idle(UART_LL_GET_HW(uart->num)));
if ( !txOnly ) { if ( !txOnly ) {
ESP_ERROR_CHECK(uart_flush_input(uart->num)); ESP_ERROR_CHECK(uart_flush_input(uart->num));
@ -304,7 +337,7 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
return; return;
} }
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), baud_rate); uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate));
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
} }
@ -388,11 +421,12 @@ int log_printf(const char *format, ...)
va_list copy; va_list copy;
va_start(arg, format); va_start(arg, format);
va_copy(copy, arg); va_copy(copy, arg);
len = vsnprintf(NULL, 0, format, arg); len = vsnprintf(NULL, 0, format, copy);
va_end(copy); va_end(copy);
if(len >= sizeof(loc_buf)){ if(len >= sizeof(loc_buf)){
temp = (char*)malloc(len+1); temp = (char*)malloc(len+1);
if(temp == NULL) { if(temp == NULL) {
va_end(arg);
return 0; return 0;
} }
} }
@ -454,6 +488,7 @@ void log_print_buf(const uint8_t *b, size_t len){
*/ */
unsigned long uartBaudrateDetect(uart_t *uart, bool flg) unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
{ {
#ifndef CONFIG_IDF_TARGET_ESP32S3
if(uart == NULL) { if(uart == NULL) {
return 0; return 0;
} }
@ -471,6 +506,9 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
return ret; return ret;
#else
return 0;
#endif
} }
@ -515,7 +553,7 @@ void uartStartDetectBaudrate(uart_t *uart) {
//hw->rx_filt.glitch_filt_en = 1; //hw->rx_filt.glitch_filt_en = 1;
//hw->conf0.autobaud_en = 0; //hw->conf0.autobaud_en = 0;
//hw->conf0.autobaud_en = 1; //hw->conf0.autobaud_en = 1;
#elif CONFIG_IDF_TARGET_ESP32S3
#else #else
hw->auto_baud.glitch_filt = 0x08; hw->auto_baud.glitch_filt = 0x08;
hw->auto_baud.en = 0; hw->auto_baud.en = 0;
@ -552,6 +590,7 @@ uartDetectBaudrate(uart_t *uart)
#ifdef CONFIG_IDF_TARGET_ESP32C3 #ifdef CONFIG_IDF_TARGET_ESP32C3
//hw->conf0.autobaud_en = 0; //hw->conf0.autobaud_en = 0;
#elif CONFIG_IDF_TARGET_ESP32S3
#else #else
hw->auto_baud.en = 0; hw->auto_baud.en = 0;
#endif #endif

View File

@ -22,6 +22,8 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#define SERIAL_5N1 0x8000010 #define SERIAL_5N1 0x8000010
#define SERIAL_6N1 0x8000014 #define SERIAL_6N1 0x8000014
@ -48,12 +50,23 @@ extern "C" {
#define SERIAL_7O2 0x800003b #define SERIAL_7O2 0x800003b
#define SERIAL_8O2 0x800003f #define SERIAL_8O2 0x800003f
// These are Hardware Flow Contol possible usage
// equivalent to UDF enum uart_hw_flowcontrol_t from
// https://github.com/espressif/esp-idf/blob/master/components/hal/include/hal/uart_types.h#L75-L81
#define HW_FLOWCTRL_DISABLE 0x0 // disable HW Flow Control
#define HW_FLOWCTRL_RTS 0x1 // use only RTS PIN for HW Flow Control
#define HW_FLOWCTRL_CTS 0x2 // use only CTS PIN for HW Flow Control
#define HW_FLOWCTRL_CTS_RTS 0x3 // use both CTS and RTS PIN for HW Flow Control
struct uart_struct_t; struct uart_struct_t;
typedef struct uart_struct_t uart_t; typedef struct uart_struct_t uart_t;
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted, uint8_t rxfifo_full_thrhd); uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t rx_buffer_size, uint16_t tx_buffer_size, bool inverted, uint8_t rxfifo_full_thrhd);
void uartEnd(uart_t* uart); void uartEnd(uart_t* uart);
// This is used to retrieve the Event Queue pointer from a UART IDF Driver in order to allow user to deal with its events
void uartGetEventQueue(uart_t* uart, QueueHandle_t *q);
uint32_t uartAvailable(uart_t* uart); uint32_t uartAvailable(uart_t* uart);
uint32_t uartAvailableForWrite(uart_t* uart); uint32_t uartAvailableForWrite(uart_t* uart);
uint8_t uartRead(uart_t* uart); uint8_t uartRead(uart_t* uart);
@ -74,7 +87,12 @@ void uartSetDebug(uart_t* uart);
int uartGetDebug(); int uartGetDebug();
bool uartIsDriverInstalled(uart_t* uart); bool uartIsDriverInstalled(uart_t* uart);
void uartSetPins(uart_t* uart, uint8_t rxPin, uint8_t txPin);
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
void uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin);
// Enables or disables HW Flow Control function -- needs also to set CTS and/or RTS pins
void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold);
void uartStartDetectBaudrate(uart_t *uart); void uartStartDetectBaudrate(uart_t *uart);
unsigned long uartDetectBaudrate(uart_t *uart); unsigned long uartDetectBaudrate(uart_t *uart);

View File

@ -95,6 +95,9 @@ void analogWrite(uint8_t pin, int value);
//returns chip temperature in Celsius //returns chip temperature in Celsius
float temperatureRead(); float temperatureRead();
//allows user to bypass SPI RAM test routine
bool testSPIRAM(void);
#if CONFIG_AUTOSTART_ARDUINO #if CONFIG_AUTOSTART_ARDUINO
//enable/disable WDT for Arduino's setup and loop functions //enable/disable WDT for Arduino's setup and loop functions
void enableLoopWDT(); void enableLoopWDT();

View File

@ -23,7 +23,7 @@ extern "C" {
/** Minor version number (x.X.x) */ /** Minor version number (x.X.x) */
#define ESP_ARDUINO_VERSION_MINOR 0 #define ESP_ARDUINO_VERSION_MINOR 0
/** Patch version number (x.x.X) */ /** Patch version number (x.x.X) */
#define ESP_ARDUINO_VERSION_PATCH 0 #define ESP_ARDUINO_VERSION_PATCH 3
/** /**
* Macro to convert ARDUINO version number into an integer * Macro to convert ARDUINO version number into an integer

0
cores/esp32/libb64/AUTHORS Executable file → Normal file
View File

0
cores/esp32/libb64/LICENSE Executable file → Normal file
View File

0
cores/esp32/libb64/cdecode.c Executable file → Normal file
View File

0
cores/esp32/libb64/cdecode.h Executable file → Normal file
View File

0
cores/esp32/libb64/cencode.c Executable file → Normal file
View File

0
cores/esp32/libb64/cencode.h Executable file → Normal file
View File

View File

@ -2,7 +2,7 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_task_wdt.h" #include "esp_task_wdt.h"
#include "Arduino.h" #include "Arduino.h"
#if (ARDUINO_USB_CDC_ON_BOOT|ARDUINO_USB_MSC_ON_BOOT|ARDUINO_USB_DFU_ON_BOOT) #if (ARDUINO_USB_CDC_ON_BOOT|ARDUINO_USB_MSC_ON_BOOT|ARDUINO_USB_DFU_ON_BOOT) && !ARDUINO_USB_MODE
#include "USB.h" #include "USB.h"
#if ARDUINO_USB_MSC_ON_BOOT #if ARDUINO_USB_MSC_ON_BOOT
#include "FirmwareMSC.h" #include "FirmwareMSC.h"
@ -33,6 +33,10 @@ void yieldIfNecessary(void){
bool loopTaskWDTEnabled; bool loopTaskWDTEnabled;
__attribute__((weak)) size_t getArduinoLoopTaskStackSize(void) {
return ARDUINO_LOOP_STACK_SIZE;
}
void loopTask(void *pvParameters) void loopTask(void *pvParameters)
{ {
setup(); setup();
@ -50,21 +54,21 @@ void loopTask(void *pvParameters)
extern "C" void app_main() extern "C" void app_main()
{ {
#if ARDUINO_USB_CDC_ON_BOOT #if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE
Serial.begin(); Serial.begin();
#endif #endif
#if ARDUINO_USB_MSC_ON_BOOT #if ARDUINO_USB_MSC_ON_BOOT && !ARDUINO_USB_MODE
MSC_Update.begin(); MSC_Update.begin();
#endif #endif
#if ARDUINO_USB_DFU_ON_BOOT #if ARDUINO_USB_DFU_ON_BOOT && !ARDUINO_USB_MODE
USB.enableDFU(); USB.enableDFU();
#endif #endif
#if ARDUINO_USB_ON_BOOT #if ARDUINO_USB_ON_BOOT && !ARDUINO_USB_MODE
USB.begin(); USB.begin();
#endif #endif
loopTaskWDTEnabled = false; loopTaskWDTEnabled = false;
initArduino(); initArduino();
xTaskCreateUniversal(loopTask, "loopTask", ARDUINO_LOOP_STACK_SIZE, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE); xTaskCreateUniversal(loopTask, "loopTask", getArduinoLoopTaskStackSize(), NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
} }
#endif #endif

View File

@ -88,7 +88,7 @@ char* ultoa(unsigned long value, char* result, int base) {
return result; return result;
} }
char * dtostrf(double number, signed char width, unsigned char prec, char *s) { char * dtostrf(double number, signed int width, unsigned int prec, char *s) {
bool negative = false; bool negative = false;
if (isnan(number)) { if (isnan(number)) {
@ -117,7 +117,7 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) {
// Round correctly so that print(1.999, 2) prints as "2.00" // Round correctly so that print(1.999, 2) prints as "2.00"
// I optimized out most of the divisions // I optimized out most of the divisions
double rounding = 2.0; double rounding = 2.0;
for (uint8_t i = 0; i < prec; ++i) for (uint32_t i = 0; i < prec; ++i)
rounding *= 10.0; rounding *= 10.0;
rounding = 1.0 / rounding; rounding = 1.0 / rounding;

View File

@ -39,7 +39,7 @@ char* utoa (unsigned int val, char *s, int radix);
char* ultoa (unsigned long val, char *s, int radix); char* ultoa (unsigned long val, char *s, int radix);
char* dtostrf (double val, signed char width, unsigned char prec, char *s); char* dtostrf (double val, signed int width, unsigned int prec, char *s);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View File

@ -1,47 +0,0 @@
Make your question, not a Statement, inclusive. Include all pertinent information:
What you are trying to do
Describe your system (Hardware, computer, O/S, core version, environment)
Describe what is failing
Show the shortest possible code that will duplicate the error
Show the EXACT error message (it doesn't work is not enough)
Then if someone is interested and knowledgeable you might get a answer. All of this work on your part shows us that you have worked to solve YOUR problem. The more complete your issue posting is, the more likely someone will volunteer their time to help you.
If you have a Guru Meditation Error or Backtrace, ***please decode it***:
[ExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder)
----------------------------- Remove above -----------------------------
### Hardware:
|||||||
|:---|---|---|---|---|---|
|<B>Board</B>|ESP32 Dev Module|node32|ttgo_lora|ESP32-S2-Saola|Custom w/ ESP32-S2-WROVER 16MB|
|<B>Version/Date</B>|1.0.4|2.0.0|0badbeef|11/jul/2017|today's master|
|<B>IDE name</B>|Arduino IDE|Atom + Platform.io|IDF component|VSCode|
|<B>Flash Frequency</B>|40Mhz|80Mhz|
|<B>PSRAM enabled</B>|yes|no|
|<B>Upload Speed</B>|115200|
|<B>Computer OS</B>|Windows 10|Mac OSX|Ubuntu|
### Description:
Describe your problem here
### Sketch: (leave the backquotes for [code formatting](https://help.github.com/articles/creating-and-highlighting-code-blocks/))
```cpp
//Change the code below by your sketch
#include <Arduino.h>
void setup() {
}
void loop() {
}
```
### Debug Messages:
```
Enable Core debug level: Debug on tools menu of Arduino IDE, then put the serial output here
```

View File

@ -3,3 +3,4 @@
# #
# matplotlib is currently required only by the script generate_chart.py # matplotlib is currently required only by the script generate_chart.py
sphinx-copybutton==0.3.0 sphinx-copybutton==0.3.0
sphinx-tabs==3.2.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

208
docs/source/api/adc.rst Normal file
View File

@ -0,0 +1,208 @@
###
ADC
###
About
-----
ADC (analog to digital converter) is a very common peripheral used to convert an analog signal such as voltage
to a digital form so that it can be read and processed by a microcontroller.
ADCs are very useful in control and monitoring applications since most sensors
(e.g., temperature, pressure, force) produce analogue output voltages.
.. note:: Each SoC or module has a different number of ADC's with a different number of channels and pins availible. Refer to datasheet of each board for more info.
Arduino-ESP32 ADC API
---------------------
ADC common API
**************
analogRead
^^^^^^^^^^
This function is used to get the ADC raw value for a given pin/ADC channel.
.. code-block:: arduino
uint16_t analogRead(uint8_t pin);
* ``pin`` GPIO pin to read analog value
This function will return analog raw value.
analogReadMillivolts
^^^^^^^^^^^^^^^^^^^^
This function is used to get ADC value for a given pin/ADC channel in millivolts.
.. code-block:: arduino
uint32_t analogReadMilliVolts(uint8_t pin);
* ``pin`` GPIO pin to read analog value
This function will return analog value in millivolts.
analogReadResolution
^^^^^^^^^^^^^^^^^^^^
This function is used to set the resolution of ``analogRead`` return value. Default is 12 bits (range from 0 to 4096)
for all chips except ESP32S3 where default is 13 bits (range from 0 to 8192).
When different resolution is set, the values read will be shifted to match the given resolution.
Range is 1 - 16 .The default value will be used, if this function is not used.
.. note:: For the ESP32, the resolution is between 9 to12 and it will change the ADC hardware resolution. Else value will be shifted.
.. code-block:: arduino
void analogReadResolution(uint8_t bits);
* ``bits`` sets analog read resolution
analogSetClockDiv
^^^^^^^^^^^^^^^^^
This function is used to set the divider for the ADC clock.
Range is 1 - 255. Default value is 1.
.. code-block:: arduino
void analogSetClockDiv(uint8_t clockDiv);
* ``clockDiv`` sets the divider for ADC clock.
analogSetAttenuation
^^^^^^^^^^^^^^^^^^^^
This function is used to set the attenuation for all channels.
Input voltages can be attenuated before being input to the ADCs.
There are 4 available attenuation options, the higher the attenuation is, the higher the measurable input voltage could be.
The measurable input voltage differs for each chip, see table below for detailed information.
.. tabs::
.. tab:: ESP32
===================== ===========================================
Attenuation Measurable input voltage range
===================== ===========================================
``ADC_ATTEN_DB_0`` 100 mV ~ 950 mV
``ADC_ATTEN_DB_2_5`` 100 mV ~ 1250 mV
``ADC_ATTEN_DB_6`` 150 mV ~ 1750 mV
``ADC_ATTEN_DB_11`` 150 mV ~ 2450 mV
===================== ===========================================
.. tab:: ESP32-S2
===================== ===========================================
Attenuation Measurable input voltage range
===================== ===========================================
``ADC_ATTEN_DB_0`` 0 mV ~ 750 mV
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1050 mV
``ADC_ATTEN_DB_6`` 0 mV ~ 1300 mV
``ADC_ATTEN_DB_11`` 0 mV ~ 2500 mV
===================== ===========================================
.. tab:: ESP32-C3
===================== ===========================================
Attenuation Measurable input voltage range
===================== ===========================================
``ADC_ATTEN_DB_0`` 0 mV ~ 750 mV
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1050 mV
``ADC_ATTEN_DB_6`` 0 mV ~ 1300 mV
``ADC_ATTEN_DB_11`` 0 mV ~ 2500 mV
===================== ===========================================
.. tab:: ESP32-S3
===================== ===========================================
Attenuation Measurable input voltage range
===================== ===========================================
``ADC_ATTEN_DB_0`` 0 mV ~ 950 mV
``ADC_ATTEN_DB_2_5`` 0 mV ~ 1250 mV
``ADC_ATTEN_DB_6`` 0 mV ~ 1750 mV
``ADC_ATTEN_DB_11`` 0 mV ~ 3100 mV
===================== ===========================================
.. code-block:: arduino
void analogSetAttenuation(adc_attenuation_t attenuation);
* ``attenuation`` sets the attenuation.
analogSetPinAttenuation
^^^^^^^^^^^^^^^^^^^^^^^
This function is used to set the attenuation for a specific pin/ADC channel. For more information refer to `analogSetAttenuation`_.
.. code-block:: arduino
void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation);
* ``pin`` selects specific pin for attenuation settings.
* ``attenuation`` sets the attenuation.
adcAttachPin
^^^^^^^^^^^^
This function is used to attach the pin to ADC (it will also clear any other analog mode that could be on)
.. code-block:: arduino
bool adcAttachPin(uint8_t pin);
This function will return ``true`` if configuration is successful. Else returns ``false``.
ADC API specific for ESP32 chip
*******************************
analogSetWidth
^^^^^^^^^^^^^^
This function is used to set the hardware sample bits and read resolution.
Default is 12bit (0 - 4095).
Range is 9 - 12.
.. code-block:: arduino
void analogSetWidth(uint8_t bits);
analogSetVRefPin
^^^^^^^^^^^^^^^^
This function is used to set pin to use for ADC calibration if the esp is not already calibrated (pins 25, 26 or 27).
.. code-block:: arduino
void analogSetVRefPin(uint8_t pin);
* ``pin`` GPIO pin to set VRefPin for ADC calibration
hallRead
^^^^^^^^
This function is used to get the ADC value of the HALL sensor conneted to pins 36(SVP) and 39(SVN).
.. code-block:: arduino
int hallRead();
This function will return the hall sensor value.
Example Applications
********************
Here is an example of how to use the ADC.
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogRead/AnalogRead.ino
:language: arduino
Or you can run Arduino example 01.Basics -> AnalogReadSerial.

Some files were not shown because too many files have changed in this diff Show More