Compare commits

...

120 Commits

Author SHA1 Message Date
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
4100 changed files with 701629 additions and 26378 deletions

View File

@ -52,3 +52,11 @@ body:
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

View File

@ -40,6 +40,7 @@ body:
description: What version of Arduino ESP32 are you running? If possible, consider updating to the latest version.
options:
- latest master
- v2.0.2
- v2.0.1
- v2.0.0
- v1.0.6

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

58
.github/scripts/tests_build.sh vendored Executable file
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

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

@ -0,0 +1,35 @@
#!/bin/bash
if [ ! $# -eq 3 ]; then
echo "Bad number of arguments: $#" >&2
echo "usage: $0 <major> <minor> <patch>" >&2
exit 1
fi
re='^[0-9]+$'
if [[ ! $1 =~ $re ]] || [[ ! $2 =~ $re ]] || [[ ! $3 =~ $re ]] ; then
echo "error: Not a valid version: $1.$2.$3" >&2
echo "usage: $0 <major> <minor> <patch>" >&2
exit 1
fi
ESP_ARDUINO_VERSION_MAJOR="$1"
ESP_ARDUINO_VERSION_MINOR="$2"
ESP_ARDUINO_VERSION_PATCH="$3"
ESP_ARDUINO_VERSION="$ESP_ARDUINO_VERSION_MAJOR.$ESP_ARDUINO_VERSION_MINOR.$ESP_ARDUINO_VERSION_PATCH"
echo "New Arduino Version: $ESP_ARDUINO_VERSION"
echo "Updating platform.txt..."
cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > __platform.txt && mv __platform.txt platform.txt
echo "Updating package.json..."
cat package.json | sed "s/.*\"version\":.*/ \"version\": \"$ESP_ARDUINO_VERSION\",/g" > __package.json && mv __package.json package.json
echo "Updating cores/esp32/esp_arduino_version.h..."
cat cores/esp32/esp_arduino_version.h | \
sed "s/#define ESP_ARDUINO_VERSION_MAJOR.*/#define ESP_ARDUINO_VERSION_MAJOR $ESP_ARDUINO_VERSION_MAJOR/g" | \
sed "s/#define ESP_ARDUINO_VERSION_MINOR.*/#define ESP_ARDUINO_VERSION_MINOR $ESP_ARDUINO_VERSION_MINOR/g" | \
sed "s/#define ESP_ARDUINO_VERSION_PATCH.*/#define ESP_ARDUINO_VERSION_PATCH $ESP_ARDUINO_VERSION_PATCH/g" > __esp_arduino_version.h && mv __esp_arduino_version.h cores/esp32/esp_arduino_version.h
exit 0

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
strategy:
fail-fast: false
matrix:
chip: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
chunks: ${{fromJson(needs.gen_chunks.outputs.chunks)}}
container:
image: python:3.10.1-bullseye
options: --privileged
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Download ${{matrix.chip}}-${{matrix.chunks}} artifacts
uses: actions/download-artifact@v2
with:
name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
path: tests/
- name: Check Artifacts
run: |
ls -R tests
cat tests/*/build/build.options.json
- name: Install dependencies
run: |
pip install -U pip
pip install -r tests/requirements.txt
- name: Run Tests
run: |
bash .github/scripts/tests_run.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
- name: Upload test result artifacts
uses: actions/upload-artifact@v2
if: always()
with:
name: test_results-${{matrix.chip}}-${{matrix.chunks}}
path: tests/*/*.xml
event_file:
name: "Event File"
if: ${{ always() }}
needs: Test
runs-on: ubuntu-latest
steps:
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Event File
path: ${{github.event_path}}

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

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

View File

@ -1,14 +1,26 @@
name: ESP32 Arduino CI
on:
workflow_dispatch:
push:
branches:
- master
- release/*
pull_request:
concurrency:
group: build-${{github.event.pull_request.number || github.ref}}
cancel-in-progress: true
jobs:
cmake-check:
name: Check cmake file
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: bash ./.github/scripts/check-cmakelists.sh
# Ubuntu
build-arduino-linux:
name: Arduino ${{ matrix.chunk }} on ubuntu-latest
@ -16,12 +28,22 @@ jobs:
strategy:
matrix:
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache tools
id: cache-linux
uses: actions/cache@v2
with:
path: |
./tools/dist
~/arduino_ide
key: ${{ runner.os }}-${{ hashFiles('package/package_esp32_index.template.json',
'tools/get.py',
'.github/scripts/install-arduino-ide.sh') }}
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} 15
@ -32,7 +54,7 @@ jobs:
strategy:
matrix:
os: [windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
@ -48,7 +70,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2

View File

@ -1,28 +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
if: github.repository == 'espressif/arduino-esp32'
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-esp32s2-elf
tools/xtensa-esp32s3-elf
tools/riscv32-esp-elf
tools/dist
tools/esptool
@ -22,3 +23,6 @@ boards.sloeber.txt
# Ignore docs build (Sphinx)
docs/build
docs/source/_build
# Test log files
*.log

View File

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

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,4 +1,4 @@
# Arduino core for the ESP32, ESP32-S2 and ESP32-C3
# Arduino core for the ESP32, ESP32-S2, ESP32-S3 and ESP32-C3
![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)

2937
boards.txt Normal file → Executable file

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

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) {
const long dividend = out_max - out_min;
const long divisor = in_max - in_min;
const long delta = x - in_min;
if(divisor == 0){
log_e("Invalid map input range, min == max");
return -1; //AVR returns -1, SAM returns 0
const long run = in_max - in_min;
if(run == 0){
log_e("map(): Invalid input range, min == max");
return -1; // AVR returns -1, SAM returns 0
}
return (delta * dividend + (divisor / 2)) / divisor + out_min;
const long rise = out_max - out_min;
const long delta = x - in_min;
return (delta * rise) / run + out_min;
}
uint16_t makeWord(uint16_t w)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -68,22 +68,11 @@ extern "C" {
#define ONLOW_WE 0x0C
#define ONHIGH_WE 0x0D
typedef struct {
uint8_t reg; /*!< GPIO register offset from DR_REG_IO_MUX_BASE */
int8_t rtc; /*!< RTC GPIO number (-1 if not RTC GPIO pin) */
int8_t adc; /*!< ADC Channel number (-1 if not ADC pin) */
int8_t touch; /*!< Touch Channel number (-1 if not Touch pin) */
} esp32_gpioMux_t;
#define digitalPinIsValid(pin) GPIO_IS_VALID_GPIO(pin)
#define digitalPinCanOutput(pin) GPIO_IS_VALID_OUTPUT_GPIO(pin)
extern const esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT];
extern const int8_t esp32_adc2gpio[20];
#define digitalPinIsValid(pin) ((pin) < SOC_GPIO_PIN_COUNT && esp32_gpioMux[(pin)].reg)
#define digitalPinCanOutput(pin) ((pin) < NUM_OUPUT_PINS && esp32_gpioMux[(pin)].reg)
#define digitalPinToRtcPin(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].rtc:-1)
#define digitalPinToAnalogChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].adc:-1)
#define digitalPinToTouchChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].touch:-1)
#define digitalPinToDacChannel(pin) (((pin) == PIN_DAC1)?0:((pin) == PIN_DAC2)?1:-1)
#define digitalPinToRtcPin(pin) ((RTC_GPIO_IS_VALID_GPIO(pin))?rtc_io_number_get(pin):-1)
#define digitalPinToDacChannel(pin) (((pin) == DAC_CHANNEL_1_GPIO_NUM)?0:((pin) == DAC_CHANNEL_2_GPIO_NUM)?1:-1)
void pinMode(uint8_t pin, uint8_t mode);
void digitalWrite(uint8_t pin, uint8_t val);
@ -93,6 +82,10 @@ void attachInterrupt(uint8_t pin, void (*)(void), int mode);
void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode);
void detachInterrupt(uint8_t pin);
int8_t digitalPinToTouchChannel(uint8_t pin);
int8_t digitalPinToAnalogChannel(uint8_t pin);
int8_t analogChannelToDigitalPin(uint8_t channel);
#ifdef __cplusplus
}
#endif

View File

@ -127,7 +127,7 @@ typedef enum {
static inline i2c_stretch_cause_t i2c_ll_stretch_cause(i2c_dev_t *hw)
{
#if CONFIG_IDF_TARGET_ESP32C3
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
return hw->sr.stretch_cause;
#elif CONFIG_IDF_TARGET_ESP32S2
return hw->status_reg.stretch_cause;
@ -164,7 +164,7 @@ static inline void i2c_ll_stretch_clr(i2c_dev_t *hw)
static inline bool i2c_ll_slave_addressed(i2c_dev_t *hw)
{
#if CONFIG_IDF_TARGET_ESP32C3
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
return hw->sr.slave_addressed;
#else
return hw->status_reg.slave_addressed;
@ -173,7 +173,7 @@ static inline bool i2c_ll_slave_addressed(i2c_dev_t *hw)
static inline bool i2c_ll_slave_rw(i2c_dev_t *hw)//not exposed by hal_ll
{
#if CONFIG_IDF_TARGET_ESP32C3
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
return hw->sr.slave_rw;
#else
return hw->status_reg.slave_rw;
@ -360,10 +360,12 @@ esp_err_t i2cSlaveDeinit(uint8_t num){
}
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
#if !CONFIG_DISABLE_HAL_LOCKS
if(!i2c->lock){
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
return ESP_ERR_NO_MEM;
}
#endif
I2C_SLAVE_MUTEX_LOCK();
i2c_slave_free_resources(i2c);
I2C_SLAVE_MUTEX_UNLOCK();
@ -377,10 +379,12 @@ size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t tim
}
size_t to_queue = 0, to_fifo = 0;
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
#if !CONFIG_DISABLE_HAL_LOCKS
if(!i2c->lock){
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
return ESP_ERR_NO_MEM;
}
#endif
if(!i2c->tx_queue){
return 0;
}

View File

@ -56,10 +56,11 @@ uint8_t channels_resolution[LEDC_CHANNELS] = {0};
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
{
if(chan >= LEDC_CHANNELS){
log_e("No more LEDC channels available! You can have maximum %u", LEDC_CHANNELS);
if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
return 0;
}
uint8_t group=(chan/8), timer=((chan/2)%4);
ledc_timer_config_t ledc_timer = {
@ -69,9 +70,12 @@ double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
.freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK
};
ledc_timer_config(&ledc_timer);
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);
}
@ -95,7 +99,7 @@ void ledcWrite(uint8_t chan, uint32_t duty)
uint32_t ledcRead(uint8_t chan)
{
if(chan >= LEDC_CHANNELS){
if(chan >= LEDC_CHANNELS){
return 0;
}
uint8_t group=(chan/8), channel=(chan%8);
@ -130,7 +134,12 @@ double ledcWriteTone(uint8_t chan, double freq)
.freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK
};
ledc_timer_config(&ledc_timer);
if(ledc_timer_config(&ledc_timer) != ESP_OK)
{
log_e("ledcSetup failed!");
return 0;
}
channels_resolution[chan] = 10;
double res_freq = ledc_get_freq(group,timer);
@ -153,7 +162,7 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
void ledcAttachPin(uint8_t pin, uint8_t chan)
{
if(chan >= LEDC_CHANNELS){
if(chan >= LEDC_CHANNELS){
return;
}
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
@ -177,7 +186,8 @@ void ledcDetachPin(uint8_t pin)
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
{
if(chan >= LEDC_CHANNELS){
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;
}
uint8_t group=(chan/8), timer=((chan/2)%4);
@ -189,9 +199,13 @@ double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
.freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK
};
ledc_timer_config(&ledc_timer);
channels_resolution[chan] = bit_num;
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);
}

View File

@ -38,9 +38,11 @@ extern "C"
#else
#define ARDUHAL_LOG_LEVEL CORE_DEBUG_LEVEL
#ifdef USE_ESP_IDF_LOG
#ifndef LOG_LOCAL_LEVEL
#define LOG_LOCAL_LEVEL CORE_DEBUG_LEVEL
#endif
#endif
#endif
#ifndef CONFIG_ARDUHAL_LOG_COLORS
#define CONFIG_ARDUHAL_LOG_COLORS 0
@ -158,7 +160,7 @@ void log_print_buf(const uint8_t *b, size_t len);
#define isr_log_e(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
#define log_buf_e(b,l) do{ARDUHAL_LOG_COLOR_PRINT(E);log_print_buf(b,l);ARDUHAL_LOG_COLOR_PRINT_END;}while(0)
#else
#define log_e(format, ...) do {log_to_esp(TAG, ESP_LOG_ERROR, format, ##__VA_ARGS__);}while(0)
#define log_e(format, ...) do {ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, TAG, format, ##__VA_ARGS__);}while(0)
#define isr_log_e(format, ...) do {ets_printf(LOG_FORMAT(E, format), esp_log_timestamp(), TAG, ##__VA_ARGS__);}while(0)
#define log_buf_e(b,l) do {ESP_LOG_BUFFER_HEXDUMP(TAG, b, l, ESP_LOG_ERROR);}while(0)
#endif
@ -187,9 +189,9 @@ void log_print_buf(const uint8_t *b, size_t len);
#include "esp_log.h"
#ifdef USE_ESP_IDF_LOG
#ifndef TAG
#define TAG "ARDUINO"
#endif
//#ifndef TAG
//#define TAG "ARDUINO"
//#endif
//#define log_n(format, ...) myLog(ESP_LOG_NONE, format, ##__VA_ARGS__)
#else
#ifdef CONFIG_ARDUHAL_ESP_LOG

View File

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

View File

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

View File

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

View File

@ -96,6 +96,7 @@ struct rmt_obj_s
void * arg;
TaskHandle_t rxTaskHandle;
bool rx_completed;
bool tx_not_rx;
};
/**
@ -109,15 +110,15 @@ static xSemaphoreHandle g_rmt_objlocks[MAX_CHANNELS] = {
};
static rmt_obj_t g_rmt_objects[MAX_CHANNELS] = {
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
#if MAX_CHANNELS > 4
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
{ false, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, true, true},
#endif
};
@ -248,6 +249,26 @@ static bool _rmtCreateRxTask(rmt_obj_t* rmt)
return true;
}
// Helper function to test if an RMT channel is correctly assigned to TX or RX, issuing an error message if necessary
// Also test RMT pointer for NULL and returns false in case it is NULL
// return true when it is correctly assigned, false otherwise
static bool _rmtCheckTXnotRX(rmt_obj_t* rmt, bool tx_not_rx)
{
if (!rmt) { // also returns false on NULL
return false;
}
if (rmt->tx_not_rx == tx_not_rx) { // matches expected RX/TX channel
return true;
}
if (tx_not_rx) { // expected TX channel
log_e("Can't write on a RX RMT Channel");
} else{ // expected RX channel
log_e("Can't read on a TX RMT Channel");
}
return false; // missmatched
}
/**
* Public method definitions
@ -255,7 +276,7 @@ static bool _rmtCreateRxTask(rmt_obj_t* rmt)
bool rmtSetCarrier(rmt_obj_t* rmt, bool carrier_en, bool carrier_level, uint32_t low, uint32_t high)
{
if (!rmt || low > 0xFFFF || high > 0xFFFF) {
if (!_rmtCheckTXnotRX(rmt, RMT_TX_MODE) || low > 0xFFFF || high > 0xFFFF) {
return false;
}
size_t channel = rmt->channel;
@ -268,7 +289,7 @@ bool rmtSetCarrier(rmt_obj_t* rmt, bool carrier_en, bool carrier_level, uint32_t
bool rmtSetFilter(rmt_obj_t* rmt, bool filter_en, uint32_t filter_level)
{
if (!rmt || filter_level > 0xFF) {
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE) || filter_level > 0xFF) {
return false;
}
size_t channel = rmt->channel;
@ -281,7 +302,7 @@ bool rmtSetFilter(rmt_obj_t* rmt, bool filter_en, uint32_t filter_level)
bool rmtSetRxThreshold(rmt_obj_t* rmt, uint32_t value)
{
if (!rmt || value > 0xFFFF) {
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE) || value > 0xFFFF) {
return false;
}
size_t channel = rmt->channel;
@ -306,14 +327,17 @@ bool rmtDeinit(rmt_obj_t *rmt)
RMT_MUTEX_LOCK(rmt->channel);
// force stopping rmt processing
rmt_rx_stop(rmt->channel);
rmt_tx_stop(rmt->channel);
if (rmt->tx_not_rx) {
rmt_tx_stop(rmt->channel);
} else {
rmt_rx_stop(rmt->channel);
if(rmt->rxTaskHandle){
vTaskDelete(rmt->rxTaskHandle);
rmt->rxTaskHandle = NULL;
}
}
if(rmt->rxTaskHandle){
vTaskDelete(rmt->rxTaskHandle);
rmt->rxTaskHandle = NULL;
}
rmt_driver_uninstall(rmt->channel);
rmt_driver_uninstall(rmt->channel);
size_t from = rmt->channel;
size_t to = rmt->buffers + rmt->channel;
@ -330,6 +354,7 @@ bool rmtDeinit(rmt_obj_t *rmt)
#if !CONFIG_DISABLE_HAL_LOCKS
if(g_rmt_objlocks[from] != NULL) {
vSemaphoreDelete(g_rmt_objlocks[from]);
g_rmt_objlocks[from] = NULL;
}
#endif
@ -338,10 +363,9 @@ bool rmtDeinit(rmt_obj_t *rmt)
bool rmtLoop(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
{
if (!rmt) {
if (!_rmtCheckTXnotRX(rmt, RMT_TX_MODE)) {
return false;
}
int channel = rmt->channel;
RMT_MUTEX_LOCK(channel);
rmt_tx_stop(channel);
@ -353,10 +377,9 @@ bool rmtLoop(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
{
if (!rmt) {
if (!_rmtCheckTXnotRX(rmt, RMT_TX_MODE)) {
return false;
}
int channel = rmt->channel;
RMT_MUTEX_LOCK(channel);
rmt_tx_stop(channel);
@ -368,10 +391,9 @@ bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
bool rmtWriteBlocking(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
{
if (!rmt) {
if (!_rmtCheckTXnotRX(rmt, RMT_TX_MODE)) {
return false;
}
int channel = rmt->channel;
RMT_MUTEX_LOCK(channel);
rmt_tx_stop(channel);
@ -383,10 +405,9 @@ bool rmtWriteBlocking(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
bool rmtReadData(rmt_obj_t* rmt, uint32_t* data, size_t size)
{
if (!rmt) {
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE)) {
return false;
}
rmtReadAsync(rmt, (rmt_data_t*) data, size, NULL, false, 0);
return true;
}
@ -394,7 +415,7 @@ bool rmtReadData(rmt_obj_t* rmt, uint32_t* data, size_t size)
bool rmtBeginReceive(rmt_obj_t* rmt)
{
if (!rmt) {
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE)) {
return false;
}
int channel = rmt->channel;
@ -418,7 +439,7 @@ bool rmtReceiveCompleted(rmt_obj_t* rmt)
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb, void * arg)
{
if (!rmt || !cb) {
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE)) {
return false;
}
int channel = rmt->channel;
@ -449,15 +470,19 @@ bool rmtEnd(rmt_obj_t* rmt)
int channel = rmt->channel;
RMT_MUTEX_LOCK(channel);
rmt_rx_stop(channel);
rmt->rx_completed = true;
if (rmt->tx_not_rx) {
rmt_tx_stop(channel);
} else {
rmt_rx_stop(channel);
rmt->rx_completed = true;
}
RMT_MUTEX_UNLOCK(channel);
return true;
}
bool rmtReadAsync(rmt_obj_t* rmt, rmt_data_t* data, size_t size, void* eventFlag, bool waitForData, uint32_t timeout)
{
if (!rmt) {
if (!_rmtCheckTXnotRX(rmt, RMT_RX_MODE)) {
return false;
}
int channel = rmt->channel;
@ -568,6 +593,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
rmt->data_size = 0;
rmt->rx_completed = false;
rmt->events = NULL;
rmt->tx_not_rx = tx_not_rx;
#if !CONFIG_DISABLE_HAL_LOCKS
if(g_rmt_objlocks[channel] == NULL) {

View File

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

View File

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

View File

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

View File

@ -58,7 +58,7 @@ bool timerGetAutoReload(hw_timer_t *timer);
void timerAlarmEnable(hw_timer_t *timer);
void timerAlarmDisable(hw_timer_t *timer);
void timerAlarmWrite(hw_timer_t *timer, uint64_t interruptAt, bool autoreload);
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload);
bool timerAlarmEnabled(hw_timer_t *timer);
uint64_t timerAlarmRead(hw_timer_t *timer);

View File

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

View File

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

View File

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

View File

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

View File

@ -34,7 +34,7 @@ struct uart_struct_t {
uint8_t num;
bool has_peek;
uint8_t peek_byte;
QueueHandle_t uart_event_queue; // export it by some uartGetEventQueue() function
};
#if CONFIG_DISABLE_HAL_LOCKS
@ -43,12 +43,12 @@ struct uart_struct_t {
#define UART_MUTEX_UNLOCK()
static uart_t _uart_bus_array[] = {
{0, false, 0},
{0, false, 0, NULL},
#if SOC_UART_NUM > 1
{1, false, 0},
{1, false, 0, NULL},
#endif
#if SOC_UART_NUM > 2
{2, false, 0},
{2, false, 0, NULL},
#endif
};
@ -58,12 +58,12 @@ static uart_t _uart_bus_array[] = {
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
static uart_t _uart_bus_array[] = {
{NULL, 0, false, 0},
{NULL, 0, false, 0, NULL},
#if SOC_UART_NUM > 1
{NULL, 1, false, 0},
{NULL, 1, false, 0, NULL},
#endif
#if SOC_UART_NUM > 2
{NULL, 2, false, 0},
{NULL, 2, false, 0, NULL},
#endif
};
@ -82,10 +82,22 @@ uint32_t _get_effective_baudrate(uint32_t baudrate)
}
}
// Routines that take care of UART events will be in the HardwareSerial Class code
void uartGetEventQueue(uart_t* uart, QueueHandle_t *q)
{
// passing back NULL for the Queue pointer when UART is not initialized yet
*q = NULL;
if(uart == NULL) {
return;
}
*q = uart->uart_event_queue;
return;
}
bool uartIsDriverInstalled(uart_t* uart)
{
if(uart == NULL) {
return 0;
return false;
}
if (uart_is_driver_installed(uart->num)) {
@ -94,28 +106,36 @@ bool uartIsDriverInstalled(uart_t* uart)
return false;
}
void uartSetPins(uart_t* uart, uint8_t rxPin, uint8_t txPin)
// Valid pin UART_PIN_NO_CHANGE is defined to (-1)
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
void uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
{
if(uart == NULL || rxPin >= SOC_GPIO_PIN_COUNT || txPin >= SOC_GPIO_PIN_COUNT) {
if(uart == NULL) {
return;
}
UART_MUTEX_LOCK();
ESP_ERROR_CHECK(uart_set_pin(uart->num, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
UART_MUTEX_UNLOCK();
// IDF uart_set_pin() will issue necessary Error Message and take care of all GPIO Number validation.
uart_set_pin(uart->num, txPin, rxPin, ctsPin, rtsPin);
UART_MUTEX_UNLOCK();
}
//
void uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold) {
if(uart == NULL) {
return;
}
// IDF will issue corresponding error message when mode or threshold are wrong and prevent crashing
// IDF will check (mode > HW_FLOWCTRL_CTS_RTS || threshold >= SOC_UART_FIFO_LEN)
uart_set_hw_flow_ctrl(uart->num, (uart_hw_flowcontrol_t) mode, threshold);
}
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted, uint8_t rxfifo_full_thrhd)
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t rx_buffer_size, uint16_t tx_buffer_size, bool inverted, uint8_t rxfifo_full_thrhd)
{
if(uart_nr >= SOC_UART_NUM) {
return NULL;
}
if(rxPin == -1 && txPin == -1) {
return NULL;
}
uart_t* uart = &_uart_bus_array[uart_nr];
if (uart_is_driver_installed(uart_nr)) {
@ -143,7 +163,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
uart_config.source_clk = UART_SCLK_APB;
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 0, NULL, 0));
ESP_ERROR_CHECK(uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0));
ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
@ -153,9 +173,6 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
ESP_ERROR_CHECK(uart_set_line_inverse(uart_nr, UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV));
}
// Set RS485 half duplex mode on UART. This shall force flush to wait up to sending all bits out
ESP_ERROR_CHECK(uart_set_mode(uart_nr, UART_MODE_RS485_HALF_DUPLEX));
UART_MUTEX_UNLOCK();
uartFlush(uart);
@ -306,7 +323,7 @@ void uartFlushTxOnly(uart_t* uart, bool txOnly)
}
UART_MUTEX_LOCK();
ESP_ERROR_CHECK(uart_wait_tx_done(uart->num, portMAX_DELAY));
while(!uart_ll_is_tx_idle(UART_LL_GET_HW(uart->num)));
if ( !txOnly ) {
ESP_ERROR_CHECK(uart_flush_input(uart->num));
@ -404,11 +421,12 @@ int log_printf(const char *format, ...)
va_list copy;
va_start(arg, format);
va_copy(copy, arg);
len = vsnprintf(NULL, 0, format, arg);
len = vsnprintf(NULL, 0, format, copy);
va_end(copy);
if(len >= sizeof(loc_buf)){
temp = (char*)malloc(len+1);
if(temp == NULL) {
va_end(arg);
return 0;
}
}
@ -470,6 +488,7 @@ void log_print_buf(const uint8_t *b, size_t len){
*/
unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
{
#ifndef CONFIG_IDF_TARGET_ESP32S3
if(uart == NULL) {
return 0;
}
@ -487,6 +506,9 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
UART_MUTEX_UNLOCK();
return ret;
#else
return 0;
#endif
}
@ -531,7 +553,7 @@ void uartStartDetectBaudrate(uart_t *uart) {
//hw->rx_filt.glitch_filt_en = 1;
//hw->conf0.autobaud_en = 0;
//hw->conf0.autobaud_en = 1;
#elif CONFIG_IDF_TARGET_ESP32S3
#else
hw->auto_baud.glitch_filt = 0x08;
hw->auto_baud.en = 0;
@ -568,6 +590,7 @@ uartDetectBaudrate(uart_t *uart)
#ifdef CONFIG_IDF_TARGET_ESP32C3
//hw->conf0.autobaud_en = 0;
#elif CONFIG_IDF_TARGET_ESP32S3
#else
hw->auto_baud.en = 0;
#endif

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
#include "freertos/task.h"
#include "esp_task_wdt.h"
#include "Arduino.h"
#if (ARDUINO_USB_CDC_ON_BOOT|ARDUINO_USB_MSC_ON_BOOT|ARDUINO_USB_DFU_ON_BOOT)
#if (ARDUINO_USB_CDC_ON_BOOT|ARDUINO_USB_MSC_ON_BOOT|ARDUINO_USB_DFU_ON_BOOT) && !ARDUINO_USB_MODE
#include "USB.h"
#if ARDUINO_USB_MSC_ON_BOOT
#include "FirmwareMSC.h"
@ -54,16 +54,16 @@ void loopTask(void *pvParameters)
extern "C" void app_main()
{
#if ARDUINO_USB_CDC_ON_BOOT
#if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE
Serial.begin();
#endif
#if ARDUINO_USB_MSC_ON_BOOT
#if ARDUINO_USB_MSC_ON_BOOT && !ARDUINO_USB_MODE
MSC_Update.begin();
#endif
#if ARDUINO_USB_DFU_ON_BOOT
#if ARDUINO_USB_DFU_ON_BOOT && !ARDUINO_USB_MODE
USB.enableDFU();
#endif
#if ARDUINO_USB_ON_BOOT
#if ARDUINO_USB_ON_BOOT && !ARDUINO_USB_MODE
USB.begin();
#endif
loopTaskWDTEnabled = false;

View File

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

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* dtostrf (double val, signed char width, unsigned char prec, char *s);
char* dtostrf (double val, signed int width, unsigned int prec, char *s);
#ifdef __cplusplus
} // extern "C"

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
sphinx-copybutton==0.3.0
sphinx-tabs==3.2.0

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.

47
docs/source/api/dac.rst Normal file
View File

@ -0,0 +1,47 @@
###
DAC
###
About
-----
DAC (digital to analog converter) is a very common peripheral used to convert a digital signal to an
analog form.
ESP32 and ESP32-S2 have two 8-bit DAC channels. The DAC driver allows these channels to be set to arbitrary voltages.
DACs can be used for generating a specific (and dynamic) reference voltage for external sensors,
controlling transistors, etc.
========= ========= =========
ESP32 SoC DAC_1 pin DAC_2 pin
========= ========= =========
ESP32 GPIO 25 GPIO 26
ESP32-S2 GPIO 17 GPIO 18
========= ========= =========
Arduino-ESP32 DAC API
---------------------
dacWrite
********
This function is used to set the DAC value for a given pin/DAC channel.
.. code-block:: arduino
void dacWrite(uint8_t pin, uint8_t value);
* ``pin`` GPIO pin.
* ``value`` to be set. Range is 0 - 255 (equals 0V - 3.3V).
dacDisable
**********
This function is used to disable DAC output on a given pin/DAC channel.
.. code-block:: arduino
void dacDisable(uint8_t pin);
* ``pin`` GPIO pin.

View File

@ -381,4 +381,4 @@ Here is an example of how to use the I2C in Slave Mode.
.. literalinclude:: ../../../libraries/Wire/examples/WireSlave/WireSlave.ino
:language: arduino
.. _Arduino Wire Library: https://www.arduino.cc/en/reference/wire
.. _Arduino Wire Library: https://www.arduino.cc/en/reference/wire

566
docs/source/api/i2s.rst Normal file
View File

@ -0,0 +1,566 @@
###
I2S
###
About
-----
I2S - Inter-IC Sound, correctly written I²S pronounced "eye-squared-ess", alternative notation is IIS. I²S is an electrical serial bus interface standard used for connecting digital audio devices together.
It is used to communicate PCM (Pulse-Code Modulation) audio data between integrated circuits in an electronic device. The I²S bus separates clock and serial data signals, resulting in simpler receivers than those required for asynchronous communications systems that need to recover the clock from the data stream.
Despite the similar name, I²S is unrelated and incompatible with the bidirectional I²C (IIC) bus.
The I²S bus consists of at least three lines:
.. note:: All lines can be attached to almost any pin and this change can occur even during operation.
* **Bit clock line**
* Officially "continuous serial clock (SCK)". Typically written "bit clock (BCLK)".
* In this library function parameter ``sckPin`` or constant ``PIN_I2S_SCK``.
* **Word clock line**
* Officially "word select (WS)". Typically called "left-right clock (LRCLK)" or "frame sync (FS)".
* 0 = Left channel, 1 = Right channel
* In this library function parameter ``fsPin`` or constant ``PIN_I2S_FS``.
* **Data line**
* Officially "serial data (SD)", but can be called SDATA, SDIN, SDOUT, DACDAT, ADCDAT, etc.
* Unlike Arduino I2S with single data pin switching between input and output, in ESP core driver use separate data line for input and output.
* For backward compatibility, the shared data pin is ``sdPin`` or constant ``PIN_I2S_SD`` when using simplex mode.
* When using in duplex mode, there are two data lines:
* Output data line is called ``outSdPin`` for function parameter, or constant ``PIN_I2S_SD_OUT``
* Input data line is called ``inSdPin`` for function parameter, or constant ``PIN_I2S_SD_IN``
I2S Modes
---------
The I2S can be set up in three groups of modes:
* Master (default) or Slave.
* Simplex (default) or Duplex.
* Operation modes (Philips standard, ADC/DAC, PDM)
* Most of them are dual-channel, some can be single channel
.. note:: Officially supported operation mode is only ``I2S_PHILIPS_MODE``. Other modes are implemented, but we cannot guarantee flawless execution and behavior.
Master / Slave Mode
*******************
In **Master mode** (default) the device is generating clock signal ``sckPin`` and word select signal on ``fsPin``.
In **Slave mode** the device listens on attached pins for the clock signal and word select - i.e. unless externally driven the pins will remain LOW.
How to enter either mode is described in the function section.
Operation Modes
***************
Setting the operation mode is done with function ``begin`` (see API section)
* ``I2S_PHILIPS_MODE``
* Currently the only official* ``PIN_I2S_SCK``
* ``PIN_I2S_FS``
* ``PIN_I2S_SD``
* ``PIN_I2S_SD_OUT`` only need to send one channel data but the data will be copied for another channel automatically, then both channels will transmit same data.
* ``ADC_DAC_MODE``
The output will be an analog signal on pins ``25`` (L or R?) and ``26`` (L or R?).
Input will be received on pin ``_inSdPin``.
The data are sampled in 12 bits and stored in a 16 bits, with the 4 most significant bits set to zero.
* ``PDM_STEREO_MODE``
Pulse-density-modulation is similar to PWM, but instead, the pulses have constant width. The signal is modulated with the number of ones or zeroes in sequence.
* ``PDM_MONO_MODE``
Single-channel version of PDM mode described above.
Simplex / Duplex Mode
*********************
The **Simplex** mode is the default after driver initialization. Simplex mode uses the shared data pin ``sdPin`` or constant ``PIN_I2S_SD`` for both output and input, but can only read or write. This is the same behavior as in original Arduino library.
The **Duplex** mode uses two separate data pins:
* Output pin ``outSdPin`` for function parameter, or constant ``PIN_I2S_SD_OUT``
* Input pin ``inSdPin`` for function parameter, or constant ``PIN_I2S_SD_IN``
In this mode, the driver is able to read and write simultaneously on each line and is suitable for applications like walkie-talkie or phone.
Switching between these modes is performed simply by calling setDuplex() or setSimplex() (see APi section for details and more functions).
Arduino-ESP32 I2S API
---------------------
The ESP32 I2S library is based on the Arduino I2S Library and implements a few more APIs, described in this `documentation <https://www.arduino.cc/en/Reference/I2S>`_.
Initialization and deinitialization
***********************************
Before initialization, choose which pins you want to use. In DAC mode you can use only pins `25` and `26` for the output.
begin (Master Mode)
^^^^^^^^^^^^^^^^^^^
Before usage choose which pins you want to use. In DAC mode you can use only pins 25 and 26 as output.
.. code-block:: arduino
int begin(int mode, int sampleRate, int bitsPerSample)
Parameters:
* [in] ``mode`` one of above mentioned operation mode, for example ``I2S_PHILIPS_MODE``.
* [in] ``sampleRate`` is the sampling rate in Hz. Currently officially supported value is only 16000 - other than this value will print warning, but continue to operate, however the resulting audio quality may suffer and the app may crash.
* [in] ``bitsPerSample`` is the number of bits in a channel sample.
Currently, the supported value is only 16 - other than this value will print a warning, but continues to operate, however, the resulting audio quality may suffer and the application may crash.
For ``ADC_DAC_MODE`` the only possible value will remain 16.
This function will return ``true`` on success or ``fail`` in case of failure.
When failed, an error message will be printed if subscribed.
begin (Slave Mode)
^^^^^^^^^^^^^^^^^^
Performs initialization before use - creates buffers, task handling underlying driver messages, configuring and starting the driver operation.
This version initializes I2S in SLAVE mode (see previous entry for MASTER mode).
.. code-block:: arduino
int begin(int mode, int bitsPerSample)
Parameters:
* [in] ``mode`` one of above mentioned modes for example ``I2S_PHILIPS_MODE``.
* [in] ``bitsPerSample`` is the umber of bits in a channel sample. Currently, the only supported value is only 16 - other than this value will print warning, but continue to operate, however the resulting audio quality may suffer and the app may crash.
For ``ADC_DAC_MODE`` the only possible value will remain 16.
This function will return ``true`` on success or ``fail`` in case of failure.
When failed, an error message will be printed if subscribed.
end
^^^
Performs safe deinitialization - free buffers, destroy task, end driver operation, etc.
.. code-block:: arduino
void end()
Pin setup
*********
Pins can be changed in two ways- 1st constants, 2nd functions.
.. note:: Shared data pin can be equal to any other data pin, but must not be equal to clock pin nor frame sync pin! Input and Output pins must not be equal, but one of them can be equal to shared data pin!
.. code-block:: arduino
sckPin != fsPin != outSdPin != inSdPin
.. code-block:: arduino
sckPin != fsPin != sdPin
By default, the pin numbers are defined in constants in the header file. You can redefine any of those constants before including ``I2S.h``. This way the driver will use these new default values and you will not need to specify pins in your code. The constants and their default values are:
* ``PIN_I2S_SCK`` 14
* ``PIN_I2S_FS`` 25
* ``PIN_I2S_SD`` 26
* ``PIN_I2S_SD_OUT`` 26
* ``PIN_I2S_SD_IN`` 35
The second option to change pins is using the following functions. These functions can be called on either on initialized or uninitialized object.
If called on the initialized object (after calling ``begin``) the pins will change during operation.
If called on the uninitialized object (before calling ``begin``, or after calling ``end``) the new pin setup will be used on next initialization.
setSckPin
^^^^^^^^^
Set and apply clock pin.
.. code-block:: arduino
int setSckPin(int sckPin)
This function will return ``true`` on success or ``fail`` in case of failure.
setFsPin
^^^^^^^^
Set and apply frame sync pin.
.. code-block:: arduino
int setFsPin(int fsPin)
This function will return ``true`` on success or ``fail`` in case of failure.
setDataPin
^^^^^^^^^^
Set and apply shared data pin used in simplex mode.
.. code-block:: arduino
int setDataPin(int sdPin)
This function will return ``true`` on success or ``fail`` in case of failure.
setDataInPin
^^^^^^^^^^^^
Set and apply data input pin.
.. code-block:: arduino
int setDataInPin(int inSdPin)
This function will return ``true`` on success or ``fail`` in case of failure.
setDataOutPin
^^^^^^^^^^^^^
Set and apply data output pin.
.. code-block:: arduino
int setDataOutPin(int outSdPin)
This function will return ``true`` on success or ``fail`` in case of failure.
setAllPins
^^^^^^^^^^
Set all pins using given values in parameters. This is simply a wrapper of four functions mentioned above.
.. code-block:: arduino
int setAllPins(int sckPin, int fsPin, int sdPin, int outSdPin, int inSdPin)
Set all pins to default i.e. take values from constants mentioned above. This simply calls the the function with the following constants.
* ``PIN_I2S_SCK`` 14
* ``PIN_I2S_FS`` 25
* ``PIN_I2S_SD`` 26
* ``PIN_I2S_SD_OUT`` 26
* ``PIN_I2S_SD_IN`` 35
.. code-block:: arduino
int setAllPins()
getSckPin
^^^^^^^^^
Get the current value of the clock pin.
.. code-block:: arduino
int getSckPin()
getFsPin
^^^^^^^^
Get the current value of frame sync pin.
.. code-block:: arduino
int getFsPin()
getDataPin
^^^^^^^^^^
Get the current value of shared data pin.
.. code-block:: arduino
int getDataPin()
getDataInPin
^^^^^^^^^^^^
Get the current value of data input pin.
.. code-block:: arduino
int getDataInPin()
getDataOutPin
^^^^^^^^^^^^^
Get the current value of data output pin.
.. code-block:: arduino
int getDataOutPin()
onTransmit
^^^^^^^^^^
Register the function to be called on each successful transmit event.
.. code-block:: arduino
void onTransmit(void(*)(void))
onReceive
^^^^^^^^^
Register the function to be called on each successful receives event.
.. code-block:: arduino
void onReceive(void(*)(void))
setBufferSize
^^^^^^^^^^^^^
Set the size of buffer.
.. code-block:: arduino
int setBufferSize(int bufferSize)
This function can be called on both the initialized or uninitialized driver.
If called on initialized, it will change internal values for buffer size and re-initialize driver with new value.
If called on uninitialized, it will only change the internal values which will be used for next initialization.
Parameter ``bufferSize`` must be in range from 8 to 1024 and the unit is sample words. The default value is 128.
Example: 16 bit sample, dual channel, buffer size for input:
``128 = 2B sample * 2 channels * 128 buffer size * buffer count (default 2) = 1024B``
And more ```1024B`` for output buffer in total of ``2kB`` used.
This function always assumes dual-channel, keeping the same size even for MONO modes.
This function will return ``true`` on success or ``fail`` in case of failure.
When failed, an error message will be printed.
getBufferSize
^^^^^^^^^^^^^
Get current buffer sizes in sample words (see description for ``setBufferSize``).
.. code-block:: arduino
int getBufferSize()
Duplex vs Simplex
*****************
Original Arduino I2S library supports only *simplex* mode (only transmit or only receive at a time). For compatibility, we kept this behavior, but ESP natively supports *duplex* mode (receive and transmit simultaneously on separate pins).
By default this library is initialized in simplex mode as it would in Arduino, switching input and output on ``sdPin`` (constant ``PIN_I2S_SD`` default pin 26).
setDuplex
^^^^^^^^^
Switch to duplex mode and use separate pins:
.. code-block:: arduino
int setDuplex()
input: inSdPin (constant PIN_I2S_SD_IN, default 35)
output: outSdPin (constant PIN_I2S_SD, default 26)
setSimplex
^^^^^^^^^^
(Default mode)
Switch to simplex mode using shared data pin sdPin (constant PIN_I2S_SD, default 26).
.. code-block:: arduino
int setSimplex()
isDuplex
^^^^^^^^
Returns 1 if current mode is duplex, 0 if current mode is simplex (default).
.. code-block:: arduino
int isDuplex()
Data stream
***********
available
^^^^^^^^^
Returns number of **bytes** ready to read.
.. code-block:: arduino
int available()
read
^^^^
Read ``size`` bytes from internal buffer if possible.
.. code-block:: arduino
int read(void* buffer, size_t size)
This function is non-blocking, i.e. if the requested number of bytes is not available, it will return as much as possible without waiting.
Hint: use ``available()`` before calling this function.
Parameters:
[out] ``void* buffer`` buffer into which will be copied data read from internal buffer. WARNING: this buffer must be allocated before use!
[in] ``size_t size`` number of bytes required to be read.
Returns number of successfully bytes read. Returns ``false``` in case of reading error.
Read one sample.
.. code-block:: arduino
int read()
peek
^^^^
Read one sample from the internal buffer and returns it.
.. code-block:: arduino
int peek()
Repeated peeks will be returned in the same sample until ``read`` is called.
flush
^^^^^
Force write internal buffer to driver.
.. code-block:: arduino
void flush()
write
^^^^^
Write a single byte.
.. code-block:: arduino
size_t write(uint8_t)
Single-sample writes are blocking - waiting until there is free space in the internal buffer to be written into.
Returns number of successfully written bytes, in this case, 1. Returns 0 on error.
Write single sample.
.. code-block:: arduino
size_t write(int32_t)
Single-sample writes are blocking - waiting until there is free space in the internal buffer to be written into.
Returns number of successfully written bytes. Returns 0 on error.
Expected return number is ``bitsPerSample/8``.
Write buffer of supplied size;
.. code-block:: arduino
size_t write(const void *buffer, size_t size)
Parameters:
[in] ``const void *buffer`` buffer to be written
[in] ``size_t size`` size of buffer in bytes
Returns number of successfully written bytes. Returns 0 in case of error.
The expected return number is equal to ``size``.
write
^^^^^
This is a wrapper of the previous function performing typecast from `uint8_t*`` to ``void*``.
.. code-block:: arduino
size_t write(const uint8_t *buffer, size_t size)
availableForWrite
^^^^^^^^^^^^^^^^^
Returns number of bytes available for write.
.. code-block:: arduino
int availableForWrite()
write_blocking
^^^^^^^^^^^^^^
Core function implementing blocking write, i.e. waits until all requested data are written.
.. code-block:: arduino
size_t write_blocking(const void *buffer, size_t size)
WARNING: If too many bytes are requested, this can cause WatchDog Trigger Reset!
Returns number of successfully written bytes. Returns 0 on error.
write_nonblocking
^^^^^^^^^^^^^^^^^
Core function implementing non-blocking write, i.e. writes as much as possible and exits.
.. code-block:: arduino
size_t write_nonblocking(const void *buffer, size_t size)
Returns number of successfully written bytes. Returns 0 on error.
Sample code
-----------
.. code-block:: c
#include <I2S.h>
const int buff_size = 128;
int available, read;
uint8_t buffer[buff_size];
I2S.begin(I2S_PHILIPS_MODE, 16000, 16);
I2S.read(); // Switch the driver in simplex mode to receive
available = I2S.available();
if(available < buff_size){
read = I2S.read(buffer, available);
}else{
read = I2S.read(buffer, buff_size);
}
I2S.write(buffer, read);
I2S.end();

183
docs/source/api/ledc.rst Normal file
View File

@ -0,0 +1,183 @@
##################
LED Control (LEDC)
##################
About
-----
The LED control (LEDC) peripheral is primarly designed to control the intensity of LEDs,
although it can also be used to generate PWM signals for other purposes.
ESP32 SoCs has from 6 to 16 channels (variates on socs, see table below) which can generate independent waveforms, that can be used for example to drive RGB LED devices.
========= =======================
ESP32 SoC Number of LEDC channels
========= =======================
ESP32 16
ESP32-S2 8
ESP32-C3 6
ESP32-S3 8
========= =======================
Arduino-ESP32 LEDC API
----------------------
ledcSetup
*********
This function is used to setup the LEDC channel frequency and resolution.
.. code-block:: arduino
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits);
* ``channel`` select LEDC channel to config.
* ``freq`` select frequency of pwm.
* ``resolution_bits`` select resolution for ledc channel.
* range is 1-14 bits (1-20 bits for ESP32).
This function will return ``frequency`` configured for LEDC channel.
If ``0`` is returned, error occurs and ledc channel was not configured.
ledcWrite
*********
This function is used to set duty for the LEDC channel.
.. code-block:: arduino
void ledcWrite(uint8_t chan, uint32_t duty);
* ``chan`` select the LEDC channel for writing duty.
* ``duty`` select duty to be set for selected channel.
ledcRead
********
This function is used to get configured duty for the LEDC channel.
.. code-block:: arduino
uint32_t ledcRead(uint8_t chan);
* ``chan`` select LEDC channel to read the configured duty.
This function will return ``duty`` set for selected LEDC channel.
ledcReadFreq
************
This function is used to get configured frequency for the LEDC channel.
.. code-block:: arduino
double ledcReadFreq(uint8_t chan);
* ``chan`` select the LEDC channel to read the configured frequency.
This function will return ``frequency`` configured for selected LEDC channel.
ledcWriteTone
*************
This function is used to setup the LEDC channel to 50 % PWM tone on selected frequency.
.. code-block:: arduino
double ledcWriteTone(uint8_t chan, double freq);
* ``chan`` select LEDC channel.
* ``freq`` select frequency of pwm signal.
This function will return ``frequency`` set for channel.
If ``0`` is returned, error occurs and ledc cahnnel was not configured.
ledcWriteNote
*************
This function is used to setup the LEDC channel to specific note.
.. code-block:: arduino
double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave);
* ``chan`` select LEDC channel.
* ``note`` select note to be set.
======= ======= ======= ======= ======= ======
NOTE_C NOTE_Cs NOTE_D NOTE_Eb NOTE_E NOTE_F
NOTE_Fs NOTE_G NOTE_Gs NOTE_A NOTE_Bb NOTE_B
======= ======= ======= ======= ======= ======
* ``octave`` select octave for note.
This function will return ``frequency`` configured for the LEDC channel according to note and octave inputs.
If ``0`` is returned, error occurs and the LEDC channel was not configured.
ledcAttachPin
*************
This function is used to attach the pin to the LEDC channel.
.. code-block:: arduino
void ledcAttachPin(uint8_t pin, uint8_t chan);
* ``pin`` select GPIO pin.
* ``chan`` select LEDC channel.
ledcDetachPin
*************
This function is used to detach the pin from LEDC.
.. code-block:: arduino
void ledcDetachPin(uint8_t pin);
* ``pin`` select GPIO pin.
ledcChangeFrequency
*******************
This function is used to set frequency for the LEDC channel.
.. code-block:: arduino
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num);
* ``channel`` select LEDC channel.
* ``freq`` select frequency of pwm.
* ``bit_num`` select resolution for LEDC channel.
* range is 1-14 bits (1-20 bits for ESP32).
This function will return ``frequency`` configured for the LEDC channel.
If ``0`` is returned, error occurs and the LEDC channel frequency was not set.
analogWrite
***********
This function is used to write an analog value (PWM wave) on the pin.
It is compatible with Arduinos analogWrite function.
.. code-block:: arduino
void analogWrite(uint8_t pin, int value);
* ``pin`` select the GPIO pin.
* ``value`` select the duty cycle of pwm.
* range is from 0 (always off) to 255 (always on).
Example Applications
********************
LEDC software fade example:
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogOut/LEDCSoftwareFade/LEDCSoftwareFade.ino
:language: arduino
LEDC Write RGB example:
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogOut/ledcWrite_RGB/ledcWrite_RGB.ino
:language: arduino

View File

@ -0,0 +1,701 @@
###########
Preferences
###########
About
-----
The Preferences library is unique to arduino-esp32. It should be considered as the replacement for the Arduino EEPROM library.
It uses a portion of the on-board non-volatile memory (NVS) of the ESP32 to store data. This data is retained across restarts and loss of power events to the system.
Preferences works best for storing many small values, rather than a few large values. If large amounts of data are to be stored, consider using a file system library such as LitteFS.
The Preferences library is usable by all ESP32 variants.
Header File
-----------
.. code-block:: arduino
#include <Preferences.h>
..
Overview
--------
Library methods are provided to:
- create a namespace;
- open and close a namespace;
- store and retrieve data within a namespace for supported data types;
- determine if a key value has been initialized;
- delete a ``key-value`` pair;
- delete all ``key-value`` pairs in a namespace;
- determine data types stored against a key;
- determine the number of key entries in the namespace.
Preferences directly supports the following data types:
.. table:: **Table 1 — Preferences Data Types**
:align: center
+-------------------+-------------------+---------------+
| Preferences Type | Data Type | Size (bytes) |
+===================+===================+===============+
| Bool | bool | 1 |
+-------------------+-------------------+---------------+
| Char | int8_t | 1 |
+-------------------+-------------------+---------------+
| UChar | uint8_t | 1 |
+-------------------+-------------------+---------------+
| Short | int16_t | 2 |
+-------------------+-------------------+---------------+
| UShort | uint16_t | 2 |
+-------------------+-------------------+---------------+
| Int | int32_t | 4 |
+-------------------+-------------------+---------------+
| UInt | uint32_t | 4 |
+-------------------+-------------------+---------------+
| Long | int32_t | 4 |
+-------------------+-------------------+---------------+
| ULong | uint32_t | 4 |
+-------------------+-------------------+---------------+
| Long64 | int64_t | 8 |
+-------------------+-------------------+---------------+
| ULong64 | uint64_t | 8 |
+-------------------+-------------------+---------------+
| Float | float_t | 8 |
+-------------------+-------------------+---------------+
| Double | double_t | 8 |
+-------------------+-------------------+---------------+
| | const char* | variable |
| String +-------------------+ |
| | String | |
+-------------------+-------------------+---------------+
| Bytes | uint8_t | variable |
+-------------------+-------------------+---------------+
String values can be stored and retrieved either as an Arduino String or as a null terminated ``char`` array (c-string).
Bytes type is used for storing and retrieving an arbitrary number of bytes in a namespace.
Arduino-esp32 Preferences API
-----------------------------
``begin``
**********
Open non-volatile storage with a given namespace name from an NVS partition.
.. code-block:: arduino
bool begin(const char * name, bool readOnly=false, const char* partition_label=NULL)
..
**Parameters**
* ``name`` (Required)
- Namespace name. Maximum length is 15 characters.
* ``readOnly`` (Optional)
- ``false`` will open the namespace in read-write mode.
- ``true`` will open the namespace in read-only mode.
- if omitted, the namespace is opened in read-write mode.
* ``partition_label`` (Optional)
- name of the NVS partition in which to open the namespace.
- if omitted, the namespace is opened in the "``nvs``" partition.
**Returns**
* ``true`` if the namespace was opened successfully; ``false`` otherwise.
**Notes**
* If the namespace does not exist within the partition, it is first created.
* Attempting to write a key value to a namespace open in read-only mode will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``end``
*********
Close the currently opened namespace.
.. code-block:: arduino
void end()
..
**Parameters**
* None
**Returns**
* Nothing
**Note**
* After closing a namespace, methods used to access it will fail.
``clear``
**********
Delete all keys and values from the currently opened namespace.
.. code-block:: arduino
bool clear()
..
**Parameters**
* None
**Returns**
* ``true`` if all keys and values were deleted; ``false`` otherwise.
**Note**
* the namespace name still exists afterward.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``remove``
*************
Delete a key-value pair from the currently open namespace.
.. code-block:: arduino
bool remove(const char * key)
..
**Parameters**
* ``key`` (Required)
- the name of the key to be deleted.
**Returns**
* ``true`` if key-value pair was deleted; ``false`` otherwise.
**Note**
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``putChar, putUChar``
**********************
Store a value against a given key in the currently open namespace.
.. code-block:: arduino
size_t putChar(const char* key, int8_t value)
size_t putUChar(const char* key, uint8_t value)
..
**Parameters**
* ``key`` (Required)
- if the key does not exist in the currently opened namespace it is first created.
* ``value`` (Required)
- must match the data type of the method.
**Returns**
* ``1`` (the number of bytes stored for these data types) if the call is successful; ``0`` otherwise.
**Notes**
* Attempting to store a value without a namespace being open in read-write mode will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``putShort, putUShort``
************************
Store a value against a given key in the currently open namespace.
.. code-block:: arduino
size_t putShort(const char* key, int16_t value)
size_t putUShort(const char* key, uint16_t value)
..
**Parameters**
* ``key`` (Required)
- if the key does not exist in the currently opened namespace it is first created.
* ``value`` (Required)
- must match the data type of the method.
**Returns**
* ``2`` (the number of bytes stored for these data types) if the call is successful; ``0`` otherwise.
**Notes**
* Attempting to store a value without a namespace being open in read-write mode will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``putInt, putUInt``
********************
``putLong, putULong``
**********************
Store a value against a given key in the currently open namespace.
.. code-block:: arduino
size_t putInt(const char* key, int32_t value)
size_t putUInt(const char* key, uint32_t value)
size_t putLong(const char* key, int32_t value)
size_t putULong(const char* key, uint32_t value)
..
**Parameters**
* ``key`` (Required)
- if the key does not exist in the currently opened namespace it is first created.
* ``value`` (Required)
- must match the data type of the method.
**Returns**
* ``4`` (the number of bytes stored for these data types) if the call is successful; ``0`` otherwise.
**Notes**
* Attempting to store a value without a namespace being open in read-write mode will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``putLong64, putULong64``
*************************
``putFloat, putDouble``
***********************
Store a value against a given key in the currently open namespace.
.. code-block:: arduino
size_t putLong64(const char* key, int64_t value)
size_t putULong64(const char* key, uint64_t value)
size_t putFloat(const char* key, float_t value)
size_t putDouble(const char* key, double_t value)
..
**Parameters**
* ``key`` (Required)
- if the key does not exist in the currently opened namespace it is first created.
* ``value`` (Required)
- must match the data type of the method.
**Returns**
* ``8`` (the number of bytes stored for these data types) if the call is successful; ``0`` otherwise.
**Notes**
* Attempting to store a value without a namespace being open in read-write mode will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``putBool``
***********
Store a value against a given key in the currently open namespace.
.. code-block:: arduino
size_t putBool(const char* key, bool value)
..
**Parameters**
* ``key`` (Required)
- if the key does not exist in the currently opened namespace it is first created.
* ``value`` (Required)
- must match the data type of the method.
**Returns**
* ``true`` if successful; ``false`` otherwise.
**Notes**
* Attempting to store a value without a namespace being open in read-write mode will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``putString``
**************
Store a variable length value against a given key in the currently open namespace.
.. code-block:: arduino
size_t putString(const char* key, const char* value);
size_t putString(const char* key, String value);
..
**Parameters**
* ``key`` (Required)
- if the key does not exist in the currently opened namespace it is first created.
* ``value`` (Required)
- if ``const char*``, a null-terminated (c-string) character array.
- if ``String``, a valid Arduino String type.
**Returns**
* if successful: the number of bytes stored; ``0`` otherwise.
**Notes**
* Attempting to store a value without a namespace being open in read-write mode will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``putBytes``
************
Store a variable number of bytes against a given key in the currently open namespace.
.. code-block:: arduino
size_t putBytes(const char* key, const void* value, size_t len);
..
**Parameters**
* ``key`` (Required)
- if the key does not exist in the currently opened namespace it is first created.
* ``value`` (Required)
- pointer to an array or buffer containing the bytes to be stored.
* ``len`` (Required)
- the number of bytes from ``value`` to be stored.
**Returns**
* if successful: the number of bytes stored; ``0`` otherwise.
**Notes**
* Attempting to store a value without a namespace being open in read-write mode will fail.
* This method operates on the bytes used by the underlying data type, not the number of elements of a given data type. The data type of ``value`` is not retained by the Preferences library afterward.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``getChar, getUChar``
*********************
Retrieve a value stored against a given key in the currently open namespace.
.. code-block:: arduino
int8_t getChar(const char* key, int8_t defaultValue = 0)
uint8_t getUChar(const char* key, uint8_t defaultValue = 0)
..
**Parameters**
* ``key`` (Required)
* ``defaultValue`` (Optional)
- must match the data type of the method if provided.
**Returns**
* the value stored against ``key`` if the call is successful.
* ``defaultValue``, if it is provided; ``0`` otherwise.
**Notes**
* Attempting to retrieve a key without a namespace being available will fail.
* Attempting to retrieve value from a non existant key will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``getShort, getUShort``
****************************
Retrieve a value stored against a given key in the currently open namespace.
.. code-block:: arduino
int16_t getShort(const char* key, int16_t defaultValue = 0)
uint16_t getUShort(const char* key, uint16_t defaultValue = 0)
..
Except for the data type returned, behaves exactly like ``getChar``.
``getInt, getUInt``
*******************
Retrieve a value stored against a given key in the currently open namespace.
.. code-block:: arduino
int32_t getInt(const char* key, int32_t defaultValue = 0)
uint32_t getUInt(const char* key, uint32_t defaultValue = 0)
..
Except for the data type returned, behaves exactly like ``getChar``.
``getLong, getULong``
*********************
Retrieve a value stored against a given key in the currently open namespace.
.. code-block:: arduino
int32_t getLong(const char* key, int32_t defaultValue = 0)
uint32_t getULong(const char* key, uint32_t defaultValue = 0)
..
Except for the data type returned, behaves exactly like ``getChar``.
``getLong64, getULong64``
*************************
Retrieve a value stored against a given key in the currently open namespace.
.. code-block:: arduino
int64_t getLong64(const char* key, int64_t defaultValue = 0)
uint64_t getULong64(const char* key, uint64_t defaultValue = 0)
..
Except for the data type returned, behaves exactly like ``getChar``.
``getFloat``
*************
Retrieve a value stored against a given key in the currently open namespace.
.. code-block:: arduino
float_t getFloat(const char* key, float_t defaultValue = NAN)
..
Except for the data type returned and the value of ``defaultValue``, behaves exactly like ``getChar``.
``getDouble``
*************
Retrieve a value stored against a given key in the currently open namespace.
.. code-block:: arduino
double_t getDouble(const char* key, double_t defaultValue = NAN)
..
Except for the data type returned and the value of ``defaultValue``, behaves exactly like ``getChar``.
``getBool``
************
Retrieve a value stored against a given key in the currently open namespace.
.. code-block:: arduino
uint8_t getUChar(const char* key, uint8_t defaultValue = 0);
..
Except for the data type returned, behaves exactly like ``getChar``.
``getString``
*************
Copy a string of ``char`` stored against a given key in the currently open namespace to a buffer.
.. code-block:: arduino
size_t getString(const char* key, char* value, size_t len);
..
**Parameters**
* ``key`` (Required)
* ``value`` (Required)
- a buffer of a size large enough to hold ``len`` bytes
* ``len`` (Required)
- the number of type ``char``` to be written to the buffer pointed to by ``value``
**Returns**
* if successful; the number of bytes equal to ``len`` is written to the buffer pointed to by ``value``, and the method returns ``1``.
* if the method fails, nothing is written to the buffer pointed to by ``value`` and the method returns ``0``.
**Notes**
* ``len`` must equal the number of bytes stored against the key or the call will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``getString``
*************
Retrieve an Arduino String value stored against a given key in the currently open namespace.
.. code-block:: arduino
String getString(const char* key, String defaultValue = String());
..
**Parameters**
* ``key`` (Required)
* ``defaultValue`` (Optional)
**Returns**
* the value stored against ``key`` if the call if successful
* if the method fails: it returns ``defaultValue``, if provided; ``""`` (an empty String) otherwise.
**Notes**
* ``defaultValue`` must be of type ``String``.
``getBytes``
*************
Copy a series of bytes stored against a given key in the currently open namespace to a buffer.
.. code-block:: arduino
size_t getBytes(const char* key, void * buf, size_t len);
..
**Parameters**
* ``key`` (Required)
* ``buf`` (Required)
- a buffer of a size large enough to hold ``len`` bytes.
* ``len`` (Required)
- the number of bytes to be written to the buffer pointed to by ``buf``
**Returns**
* if successful, the number of bytes equal to ``len`` is written to buffer ``buf``, and the method returns ``1``.
* if the method fails, nothing is written to the buffer and the method returns ``0``.
**Notes**
* ``len`` must equal the number of bytes stored against the key or the call will fail.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``getBytesLength``
******************
Get the number of bytes stored in the value against a key of type ``Bytes`` in the currently open namespace.
.. code-block:: arduino
size_t getBytesLength(const char* key)
..
**Parameters**
* ``key`` (Required)
**Returns**
* if successful: the number of bytes in the value stored against ``key``; ``0`` otherwise.
**Notes**
* This method will fail if ``key`` is not of type ``Bytes``.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
``getType``
***********
Get the Preferences data type of a given key within the currently open namespace.
.. code-block:: arduino
PreferenceType getType(const char* key)
..
**Parameters**
* ``key`` (Required)
**Returns**
* an ``int`` value as per Table 2 below.
* a value of ``10`` (PT_INVALID) if the call fails.
**Notes**
* The return values are enumerated in ``Preferences.h``. Table 2 includes the enumerated values for information.
* A return value can map to more than one Prefs Type.
* The method will fail if: the namespace is not open; the key does not exist; the provided key exceeds 15 characters.
.. table:: **Table 2 — getType Return Values**
:align: center
+---------------+---------------+-------------------+-----------------------+
| Return value | Prefs Type | Data Type | Enumerated Value |
+===============+===============+===================+=======================+
| 0 | Char | int8_t | PT_I8 |
+---------------+---------------+-------------------+-----------------------+
| 1 | UChar | uint8_t | PT_U8 |
| +---------------+-------------------+ |
| | Bool | bool | |
+---------------+---------------+-------------------+-----------------------+
| 2 | Short | int16_t | PT_I16 |
+---------------+---------------+-------------------+-----------------------+
| 3 | UShort | uint16_t | PT_U16 |
+---------------+---------------+-------------------+-----------------------+
| 4 | Int | int32_t | PT_I32 |
| +---------------+ | |
| | Long | | |
+---------------+---------------+-------------------+-----------------------+
| 5 | UInt | uint32_t | PT_U32 |
| +---------------+ | |
| | ULong | | |
+---------------+---------------+-------------------+-----------------------+
| 6 | Long64 | int64_t | PT_I64 |
+---------------+---------------+-------------------+-----------------------+
| 7 | ULong64 | uint64_t | PT_U64 |
+---------------+---------------+-------------------+-----------------------+
| 8 | String | String | PT_STR |
| | +-------------------+ |
| | | \*char | |
+---------------+---------------+-------------------+-----------------------+
| 9 | Double | double_t | PT_BLOB |
| +---------------+-------------------+ |
| | Float | float_t | |
| +---------------+-------------------+ |
| | Bytes | uint8_t | |
+---------------+---------------+-------------------+-----------------------+
| 10 | \- | \- | PT_INVALID |
+---------------+---------------+-------------------+-----------------------+
``freeEntries``
***************
Get the number of free entries available in the key table of the currently open namespace.
.. code-block:: arduino
size_t freeEntries()
..
**Parameters**
* none
**Returns**
* if successful: the number of free entries available in the key table of the currently open namespace; ``0`` otherwise.
**Notes**
* keys storing values of type ``Bool``, ``Char``, ``UChar``, ``Short``, ``UShort``, ``Int``, ``UInt``, ``Long``, ``ULong``, ``Long64``, ``ULong64`` use one entry in the key table.
* keys storing values of type ``Float`` and ``Double`` use three entries in the key table.
* Arduino or c-string ``String`` types use a minimum of two key table entries with the number of entries increasing with the length of the string.
* keys storing values of type ``Bytes`` use a minimum of three key table entries with the number of entries increasing with the number of bytes stored.
* A message providing the reason for a failed call is sent to the arduino-esp32 ``log_e`` facility.
.. --- EOF ----

View File

@ -0,0 +1,84 @@
##########
SigmaDelta
##########
About
-----
ESP32 provides a second-order sigma delta modulation module and 8 (4 for ESP32-C3)
independent modulation channels. The channels are capable to output 1-bit
signals (output index: 100 ~ 107) with sigma delta modulation.
========= =============================
ESP32 SoC Number of SigmaDelta channels
========= =============================
ESP32 8
ESP32-S2 8
ESP32-C3 4
ESP32-S3 8
========= =============================
Arduino-ESP32 SigmaDelta API
----------------------------
sigmaDeltaSetup
***************
This function is used to setup the SigmaDelta channel frequency and resolution.
.. code-block:: arduino
double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits);
* ``pin`` select GPIO pin.
* ``channel`` select SigmaDelta channel.
* ``freq`` select frequency.
* range is 1-14 bits (1-20 bits for ESP32).
This function will return ``frequency`` configured for the SigmaDelta channel.
If ``0`` is returned, error occurs and the SigmaDelta channel was not configured.
sigmaDeltaWrite
***************
This function is used to set duty for the SigmaDelta channel.
.. code-block:: arduino
void sigmaDeltaWrite(uint8_t channel, uint8_t duty);
* ``channel`` select SigmaDelta channel.
* ``duty`` select duty to be set for selected channel.
sigmaDeltaRead
**************
This function is used to get configured duty for the SigmaDelta channel.
.. code-block:: arduino
uint8_t sigmaDeltaRead(uint8_t channel)
* ``channnel`` select SigmaDelta channel.
This function will return ``duty`` configured for the selected SigmaDelta channel.
sigmaDeltaDetachPin
*******************
This function is used to detach pin from SigmaDelta.
.. code-block:: arduino
void sigmaDeltaDetachPin(uint8_t pin);
* ``pin`` select GPIO pin.
Example Applications
********************
Here is example use of SigmaDelta:
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogOut/SigmaDelta/SigmaDelta.ino
:language: arduino

377
docs/source/api/timer.rst Normal file
View File

@ -0,0 +1,377 @@
##########
Timer
##########
About
-----
The ESP32 SoCs contains from 2 to 4 hardware timers.
They are all 64-bit (54-bit for ESP32-C3) generic timers based on 16-bit pre-scalers and 64-bit (54-bit for ESP32-C3)
up / down counters which are capable of being auto-reloaded.
========= ================
ESP32 SoC Number of timers
========= ================
ESP32 4
ESP32-S2 4
ESP32-C3 2
ESP32-S3 4
========= ================
Arduino-ESP32 Timer API
----------------------------
timerBegin
**********
This function is used to configure the timer. After successful setup the timer will automatically start.
.. code-block:: arduino
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp);
* ``num`` select timer number.
* ``divider`` select timer divider.
* ``resolution`` select timer resolution.
* range is 1-14 bits (1-20 bits for ESP32).
This function will return ``timer`` structure if configuration is successful.
If ``NULL`` is returned, error occurs and the timer was not configured.
timerEnd
********
This function is used to end timer.
.. code-block:: arduino
void timerEnd(hw_timer_t *timer);
* ``timer`` timer struct.
timerSetConfig
**************
This function is used to configure initialized timer (timerBegin() called).
.. code-block:: arduino
uint32_t timerGetConfig(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``configuration`` as uint32_t number.
This can be translated by inserting it to struct ``timer_cfg_t.val``.
timerAttachInterrupt
********************
This function is used to attach interrupt to timer.
.. code-block:: arduino
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge);
* ``timer`` timer struct.
* ``fn`` funtion to be called when interrupt is triggered.
* ``edge`` select edge to trigger interrupt (only LEVEL trigger is currently supported).
timerDetachInterrupt
********************
This function is used to detach interrupt from timer.
.. code-block:: arduino
void timerDetachInterrupt(hw_timer_t *timer);
* ``timer`` timer struct.
timerStart
**********
This function is used to start counter of the timer.
.. code-block:: arduino
void timerStart(hw_timer_t *timer);
* ``timer`` timer struct.
timerStop
*********
This function is used to stop counter of the timer.
.. code-block:: arduino
void timerStop(hw_timer_t *timer);
* ``timer`` timer struct.
timerRestart
************
This function is used to restart counter of the timer.
.. code-block:: arduino
void timerRestart(hw_timer_t *timer);
* ``timer`` timer struct.
timerWrite
**********
This function is used to set counter value of the timer.
.. code-block:: arduino
void timerWrite(hw_timer_t *timer, uint64_t val);
* ``timer`` timer struct.
* ``val`` counter value to be set.
timerSetDivider
***************
This function is used to set the divider of the timer.
.. code-block:: arduino
void timerSetDivider(hw_timer_t *timer, uint16_t divider);
* ``timer`` timer struct.
* ``divider`` divider to be set.
timerSetCountUp
***************
This function is used to configure counting direction of the timer.
.. code-block:: arduino
void timerSetCountUp(hw_timer_t *timer, bool countUp);
* ``timer`` timer struct.
* ``countUp`` select counting direction (``true`` = increment).
timerSetAutoReload
******************
This function is used to set counter value of the timer.
.. code-block:: arduino
void timerSetAutoReload(hw_timer_t *timer, bool autoreload);
* ``timer`` timer struct.
* ``autoreload`` select autoreload (``true`` = enabled).
timerStarted
************
This function is used to get if the timer is running.
.. code-block:: arduino
bool timerStarted(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``true`` if the timer is running. If ``false`` is returned, timer is stopped.
timerRead
*********
This function is used to read counter value of the timer.
.. code-block:: arduino
uint64_t timerRead(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``counter value`` of the timer.
timerReadMicros
***************
This function is used to read counter value in microseconds of the timer.
.. code-block:: arduino
uint64_t timerReadMicros(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``counter value`` of the timer in microseconds.
timerReadMilis
**************
This function is used to read counter value in miliseconds of the timer.
.. code-block:: arduino
uint64_t timerReadMilis(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``counter value`` of the timer in miliseconds.
timerReadSeconds
****************
This function is used to read counter value in seconds of the timer.
.. code-block:: arduino
double timerReadSeconds(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``counter value`` of the timer in seconds.
timerGetDivider
***************
This function is used to get divider of the timer.
.. code-block:: arduino
uint16_t timerGetDivider(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``divider`` of the timer.
timerGetCountUp
***************
This function is used get counting direction of the timer.
.. code-block:: arduino
bool timerGetCountUp(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``true`` if the timer counting direction is UP (incrementing).
If ``false`` returned, the timer counting direction is DOWN (decrementing).
timerGetAutoReload
******************
This function is used to get configuration of auto reload of the timer.
.. code-block:: arduino
bool timerGetAutoReload(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``true`` if the timer auto reload is enabled.
If ``false`` returned, the timer auto reload is disabled.
timerAlarmEnable
****************
This function is used to enable generation of timer alarm events.
.. code-block:: arduino
void timerAlarmEnable(hw_timer_t *timer);
* ``timer`` timer struct.
timerAlarmDisable
*****************
This function is used to disable generation of timer alarm events.
.. code-block:: arduino
void timerAlarmDisable(hw_timer_t *timer);
* ``timer`` timer struct.
timerAlarmWrite
***************
This function is used to configure alarm value and autoreload of the timer.
.. code-block:: arduino
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload);
* ``timer`` timer struct.
* ``alarm_value`` alarm value to generate event.
* ``autoreload`` enabled/disabled autorealod.
timerAlarmEnabled
*****************
This function is used to get status of timer alarm.
.. code-block:: arduino
bool timerAlarmEnabled(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``true`` if the timer alarm is enabled.
If ``false`` returned, the timer alarm is disabled.
timerAlarmRead
**************
This function is used to read alarm value of the timer.
.. code-block:: arduino
uint64_t timerAlarmRead(hw_timer_t *timer);
* ``timer`` timer struct.
timerAlarmReadMicros
********************
This function is used to read alarm value of the timer in microseconds.
.. code-block:: arduino
uint64_t timerAlarmReadMicros(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``alarm value`` of the timer in microseconds.
timerAlarmReadSeconds
*********************
This function is used to read alarm value of the timer in seconds.
.. code-block:: arduino
double timerAlarmReadSeconds(hw_timer_t *timer);
* ``timer`` timer struct.
This function will return ``alarm value`` of the timer in seconds.
Example Applications
********************
There are 2 examples uses of Timer:
Repeat timer example:
.. literalinclude:: ../../../libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino
:language: arduino
Watchdog timer example:
.. literalinclude:: ../../../libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino
:language: arduino

View File

@ -34,6 +34,7 @@ Where ``event`` can be:
* ARDUINO_USB_CDC_LINE_CODING_EVENT
* ARDUINO_USB_CDC_RX_EVENT
* ARDUINO_USB_CDC_TX_EVENT
* ARDUINO_USB_CDC_RX_OVERFLOW_EVENT
* ARDUINO_USB_CDC_MAX_EVENT
setRxBufferSize

View File

@ -67,6 +67,35 @@ Use static allocation if you want to have more performance and if your applicati
By default, the memory allocation will be set to **dynamic** if this function is not being used.
setDualAntennaConfig
********************
Configures the Dual antenna functionallity. This function should be used only on the **ESP32-WROOM-DA** module or any other ESP32 with RF switch.
.. code-block:: arduino
bool setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2, wifi_rx_ant_t rx_mode, wifi_tx_ant_t tx_mode);
* ``gpio_ant1`` Configure the GPIO number for the antenna 1 connected to the RF switch (default ``GPIO2`` on ESP32-WROOM-DA)
* ``gpio_ant2`` Configure the GPIO number for the antenna 2 connected to the RF switch (default ``GPIO25`` on ESP32-WROOM-DA)
* ``rx_mode`` Set the RX antenna mode. See wifi_rx_ant_t for the options.
* ``tx_mode`` Set the TX antenna mode. See wifi_tx_ant_t for the options.
Return ``true`` if the configuration was successful.
For the ``rx_mode`` you can use the following configuration:
* ``WIFI_RX_ANT0`` Selects the antenna 1 for all RX activity.
* ``WIFI_RX_ANT1`` Selects the antenna 2 for all RX activity.
* ``WIFI_RX_ANT_AUTO`` Selects the antenna for RX automatically.
For the ``tx_mode`` you can use the following configuration:
* ``WIFI_TX_ANT0`` Selects the antenna 1 for all TX activity.
* ``WIFI_TX_ANT1`` Selects the antenna 2 for all TX activity.
* ``WIFI_TX_ANT_AUTO`` Selects the antenna for TX automatically.
WiFiAP
------

View File

@ -98,18 +98,13 @@ Generic Vendor
.. note::
Create one file per board or one file with multiple boards. Do not add board information/description on this file.
.. include:: ../common/datasheet.inc
Resources
---------
* `ESP32 Datasheet`_ (Datasheet)
* `ESP32-S2 Datasheet`_ (Datasheet)
* `ESP32-C3 Datasheet`_ (Datasheet)
.. _Espressif Systems: https://www.espressif.com
.. _Espressif Product Selector: https://products.espressif.com/
.. _ESP32 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
.. _ESP32-S2 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
.. |board_lolin_d32| raw:: html

View File

@ -26,9 +26,4 @@ Pin Layout
Add here the pin layout image (not required).
Resources
---------
* `ESP32`_ (Datasheet)
.. _ESP32: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
.. include:: ../common/datasheet.inc

View File

@ -0,0 +1,13 @@
Datasheet
---------
* `ESP32`_ (Datasheet)
* `ESP32-S2`_ (Datasheet)
* `ESP32-C3`_ (Datasheet)
* `ESP32-S3`_ (Datasheet)
.. _Espressif Product Selector: https://products.espressif.com/
.. _ESP32: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
.. _ESP32-S2: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
.. _ESP32-C3: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
.. _ESP32-S3: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf

View File

@ -18,11 +18,11 @@ import sys
# -- Project information -----------------------------------------------------
project = 'Arduino-ESP32'
copyright = '2021, Espressif'
copyright = '2022, Espressif'
author = 'Espressif'
# The full version, including alpha/beta/rc tags
release = '2.0.0'
release = '2.0.2'
# -- General configuration ---------------------------------------------------
@ -30,7 +30,8 @@ release = '2.0.0'
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx_copybutton'
'sphinx_copybutton',
'sphinx_tabs.tabs'
]
# Add any paths that contain templates here, relative to this directory.

View File

@ -1,20 +1,31 @@
##############################
Arduino as a ESP-IDF component
##############################
###############################
Arduino as an ESP-IDF component
###############################
This method is recommended for advanced users. To use this method, you will need to have the ESP-IDF toolchain installed.
For a simplified method, see `Installing using Boards Manager <https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html#installing-using-boards-manager>`_.
ESP32 Arduino lib-builder
-------------------------
For a simplified method, see `lib-builder <https://github.com/espressif/esp32-arduino-lib-builder>`_.
If you don't need any modifications in the default Arduino ESP32 core, we recommend you to install using the Boards Manager.
Arduino Lib Builder is the tool that integrates ESP-IDF into Arduino. It allows you to customize the default settings used by Espressif and try them in Arduino IDE.
For more information see `Arduino lib builder <https://github.com/espressif/esp32-arduino-lib-builder>`_
Installation
------------
.. note:: Latest Arduino Core ESP32 version is now compatible with `ESP-IDF v4.4 <https://github.com/espressif/esp-idf/tree/release/v4.4>`_. Please consider this compability when using Arduino as component in ESP-IDF.
.. note:: Latest Arduino Core ESP32 version is now compatible with `ESP-IDF v4.4 <https://github.com/espressif/esp-idf/tree/release/v4.4>`_. Please consider this compatibility when using Arduino as a component in ESP-IDF.
- Download and install `ESP-IDF <https://github.com/espressif/esp-idf>`_.
- Create blank ESP-IDF project (use sample_project from /examples/get-started) or choose one of the examples.
- In the project folder, create a new folder called `components` and clone this repository inside the new created folder.
#. Download and install `ESP-IDF <https://github.com/espressif/esp-idf>`_.
* For more information see `Get Started <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html#installation-step-by-step>`_.
#. Create a blank ESP-IDF project (use sample_project from /examples/get-started) or choose one of the examples.
#. In the project folder, create a new folder called ``components`` and clone this repository inside the newly created folder.
.. code-block:: bash
@ -26,19 +37,33 @@ Installation
cd ../.. && \
idf.py menuconfig
Configuration
-------------
Depending on one of the two following options, in the menuconfig set the appropriate settings.
Go to the section ``Arduino Configuration --->``
1. For usage of ``app_main()`` function - Turn off ``Autostart Arduino setup and loop on boot``
2. For usage of ``setup()`` and ``loop()`` functions - Turn on ``Autostart Arduino setup and loop on boot``
Experienced users can explore other options in the Arduino section.
After the setup you can save and exit:
- Save [S]
- Confirm default filename [Enter]
- Close confirmation window [Enter] or [Space] or [Esc]
- Quit [Q]
Option 1. Using Arduino setup() and loop()
******************************************
- The `idf.py menuconfig` has some Arduino options.
- Turn on `Autostart Arduino setup and loop on boot`.
- In main folder rename file `main.c` to `main.cpp`.
- In main folder open file `CMakeList.txt` and change `main.c` to `main.cpp` as described below.
- In main folder rename file `main.c` to `main.cpp`.
.. code-block:: bash
- In main folder open file `CMakeList.txt` and change `main.c` to `main.cpp` as described below.
idf_component_register(SRCS "main.cpp" INCLUDE_DIRS ".")
- Your main.cpp should be formated like any other sketch.
- Your main.cpp should be formatted like any other sketch.
.. code-block:: c
@ -46,7 +71,10 @@ Option 1. Using Arduino setup() and loop()
#include "Arduino.h"
void setup(){
Serial.begin(115200);
Serial.begin(115200);
while(!Serial){
; // wait for serial port to connect
}
}
void loop(){
@ -57,10 +85,10 @@ Option 1. Using Arduino setup() and loop()
Option 2. Using ESP-IDF appmain()
*********************************
- You need to implement ``app_main()`` and call ``initArduino();`` in it.
In main.c or main.cpp you need to implement ``app_main()`` and call ``initArduino();`` in it.
Keep in mind that setup() and loop() will not be called in this case.
If you plan to base your code on examples provided in `examples <https://github.com/espressif/esp-idf/tree/master/examples>`_, please make sure to move the app_main() function in main.cpp from the files in the example.
Furthermore the ``app_main()`` is single execution as a normal function so if you need an infinite loop as in Arduino place it there.
.. code-block:: cpp
@ -69,28 +97,39 @@ If you plan to base your code on examples provided in `examples <https://github.
extern "C" void app_main()
{
initArduino();
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
//do your own thing
}
initArduino();
- "Disable mutex locks for HAL"
- If enabled, there will be no protection on the drivers from concurently accessing them from another thread/interrupt/core
- "Autoconnect WiFi on boot"
- If enabled, WiFi will start with the last known configuration
- Otherwise it will wait for WiFi.begin
// Arduino-like setup()
Serial.begin(115200);
while(!Serial){
; // wait for serial port to connect
}
// Arduino-like loop()
while(true){
Serial.println("loop");
}
// WARNING: if program reaches end of function app_main() the MCU will restart.
}
Build, flash and monitor
************************
- For both options use command ``idf.py -p <your-board-serial-port> flash monitor``
- It will build, upload and open serial monitor to your board.
- The project will build, upload and open the serial monitor to your board
- Some boards require button combo press on the board: press-and-hold Boot button + press-and-release RST button, release Boot button
- After a successful flash, you may need to press the RST button again
- To terminate the serial monitor press [Ctrl] + [ ] ]
Logging To Serial
-----------------
If you are writing code that does not require Arduino to compile and you want your `ESP_LOGx` macros to work in Arduino IDE, you can enable the compatibility by adding the following lines after:
If you are writing code that does not require Arduino to compile and you want your `ESP_LOGx` macros to work in Arduino IDE, you can enable the compatibility by adding the following lines:
.. code-block:: c
@ -107,4 +146,4 @@ To fix that behavior, you need to set FreeRTOS tick rate to 1000Hz in `make menu
Compilation Errors
------------------
As commits are made to esp-idf and submodules, the codebases can develop incompatibilities which cause compilation errors. If you have problems compiling, follow the instructions in `Issue #1142 <https://github.com/espressif/arduino-esp32/issues/1142>`_ to roll esp-idf back to a different version.
As commits are made to esp-idf and submodules, the codebases can develop incompatibilities that cause compilation errors. If you have problems compiling, follow the instructions in `Issue #1142 <https://github.com/espressif/arduino-esp32/issues/1142>`_ to roll esp-idf back to a different version.

View File

@ -26,6 +26,9 @@ power consumption.
The ESP32 series is available as a chip or module.
.. _supported_socs:
Supported SoC's
---------------
@ -34,10 +37,10 @@ Here are the ESP32 series supported by the Arduino-ESP32 project:
======== ====== =========== ===================================
SoC Stable Development Datasheet
======== ====== =========== ===================================
ESP32 Yes Yes `ESP32 Datasheet`_
ESP32-S2 Yes Yes `ESP32-S2 Datasheet`_
ESP32-C3 Yes Yes `ESP32-C3 Datasheet`_
ESP32-S3 No No `ESP32-S3 Datasheet`_
ESP32 Yes Yes `ESP32`_
ESP32-S2 Yes Yes `ESP32-S2`_
ESP32-C3 Yes Yes `ESP32-C3`_
ESP32-S3 No Yes `ESP32-S3`_
======== ====== =========== ===================================
See `Boards <boards/boards.html>`_ for more details about ESP32 development boards.
@ -63,6 +66,20 @@ Supported Operating Systems
.. |linux-logo| image:: _static/logo_linux.png
.. |macos-logo| image:: _static/logo_macos.png
Supported IDEs
---------------------------
Here is the list of supported IDE for Arduino ESP32 support integration.
+-------------------+-------------------+
| |arduino-logo| | |pio-logo| |
+-------------------+-------------------+
| Arduino IDE | PlatformIO |
+-------------------+-------------------+
.. |arduino-logo| image:: _static/logo_arduino.png
.. |pio-logo| image:: _static/logo_pio.png
See `Installing Guides <installing.html>`_ for more details on how to install the Arduino ESP32 support.
Support
@ -91,7 +108,9 @@ Before opening a new issue, please read this:
Be sure to search for a similar reported issue. This avoids duplicating or creating noise in the GitHub Issues reporting.
We also have the troubleshooting guide to save your time on the most common issues reported by users.
For more details, see the `Issue Template <https://github.com/espressif/arduino-esp32/blob/master/docs/ISSUE_TEMPLATE.md>`_.
For more details about creating new Issue, see the `Issue Template <https://github.com/espressif/arduino-esp32/blob/master/.github/ISSUE_TEMPLATE/Issue-report.yml>`_.
If you have any new idea, see the `Feature request Template <https://github.com/espressif/arduino-esp32/blob/master/.github/ISSUE_TEMPLATE/Feature-request.yml>`_.
First Steps
-----------
@ -114,15 +133,14 @@ in the examples menu or inside each library folder.
https://github.com/espressif/arduino-esp32/tree/master/libraries
.. include:: common/datasheet.inc
Resources
---------
.. _Espressif Systems: https://www.espressif.com
.. _Espressif Product Selector: https://products.espressif.com/
.. _ESP32 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
.. _ESP32-S2 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
.. _ESP32-C3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
.. _ESP32-S3 Datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf
.. _Arduino.cc: https://www.arduino.cc/en/Main/Software
.. _Arduino Reference: https://www.arduino.cc/reference/en/
.. _ESP32 Forum: https://esp32.com

View File

@ -0,0 +1,334 @@
#####################################
Documentation Contribution Guidelines
#####################################
Introduction
------------
This is a guideline for the Arduino ESP32 project documentation. The idea for this guideline is to show how to start collaborating on the project.
The guideline works to give you the directions and to keep the documentation more concise, helping users to better understand the structure.
About Documentation
-------------------
We all know how important documentation is. This project is no different.
This documentation was created in a collaborative and open way, letting everyone contribute, from a small typo fix to a new chapter writing. We try to motivate our community by giving all the support needed through this guide.
The documentation is in **English only**. Future translations can be added when we finish the essential content in English first.
How to Collaborate
------------------
Everyone with some knowledge to share is welcome to collaborate.
One thing you need to consider is the fact that your contribution must be concise and assertive since it will be used by people developing projects. The information is very important for everyone, be sure you are not making the developer's life harder!
Documentation Guide
-------------------
This documentation is based on the `Sphinx`_ with `reStructuredText`_ and hosted by `ReadTheDocs`_.
If you want to get started with `Sphinx`_, see the official documentation:
* `Documentation Index <https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html>`_
* `Basics <https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`_
* `Directives <https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html>`_
First Steps
***********
Before starting your collaboration, you need to get the documentation source code from the Arduino-ESP32 project.
* **Step 1** - Fork the `Arduino-ESP32`_ to your GitHub account.
* **Step 2** - Check out the recently created fork.
* **Step 3** - Create a new branch for the changes/addition to the docs.
* **Step 4** - Write!
Requirements
************
To properly work with the documentation, you need to install some packages in your system.
.. code-block::
pip install -U Sphinx
pip install -r requirements.txt
The requirements file is under the ``docs`` folder.
Using Visual Studio Code
************************
If you are using the Visual Studio Code, you can install some extensions to help you while writing documentation.
`reStructuredText Pack <https://marketplace.visualstudio.com/items?itemName=lextudio.restructuredtext-pack>`_
We also recommend you install to grammar check extension to help you to review English grammar.
`Grammarly <https://marketplace.visualstudio.com/items?itemName=znck.grammarly>`_
Building
********
To build the documentation and generate the HTLM files, you can use the following command inside the ``docs`` folder. After a successful build, you can check the files inside the `build/html` folder.
.. code-block::
make html
This step is essential to ensure that there are no syntax errors and also to see the final result.
If everything is ok, you will see some output logs similar to this one:
.. code-block::
Running Sphinx v2.3.1
loading pickled environment... done
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 35 source files that are out of date
updating environment: [extensions changed ('sphinx_tabs.tabs')] 41 added, 3 changed, 0 removed
reading sources... [100%] tutorials/tutorials
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
writing output... [100%] tutorials/tutorials
generating indices... genindexdone
writing additional pages... searchdone
copying images... [100%] tutorials/../_static/tutorials/peripherals/tutorial_peripheral_diagram.png
copying static files... ... done
copying extra files... done
dumping search index in English (code: en)... done
dumping object inventory... done
build succeeded.
The HTML pages are in build/html.
Sections
--------
The Arduino ESP32 is structured in some sections to make it easier to maintain. Here is a brief description of this structure.
API
***
In this section, you will include all the documentation about drivers, libraries, and any other related to the core.
In this section, we do not add general information. For more general information, we have sections for other related parts, like the FAQ, library builder, troubleshooting, etc.
Boards
******
Here is the place to add any special guide on the development boards, pin layout, schematics, and any other relevant content.
Common
******
In this folder, you can add all common information used in several different places. This helps to make documentation easily maintainable.
Guides
******
This is the place to add the guides for common applications, IDEs configuration, and any other information that can be used as a guideline.
Tutorials
*********
If you want to add a specific tutorial related to the Arduino core for ESP32, this is the place. The intention is not to create a blog or a demo area, but this can be used to add some complex description or to add some more information about APIs.
Images and Assets
*****************
All the files used on the documentation must be stored in the ``_static`` folder. Be sure that the content used is not with any copyright restriction.
Documentation Rules
-------------------
Here are some guidelines to help you. We also recommend copying a sample file from the same category you are creating.
This will help you to follow the structure as well as to get inspired.
Basic Structure
***************
To help you create a new section from scratch, we recommend you include this structure in your content if it applies.
* **About** - Brief description of the document.
* Description of the peripheral, driver, protocol, including all different modes and configurations.
* **API** - Description of each public function, macros, and structs.
* **Basic Usage**
* **Example Application**
About Section
^^^^^^^^^^^^^
In this section, you need to add a brief description of the API. If you are describing a peripheral API, you should explain a little bit about the peripheral and the working modes, if it's applicable.
API Functions
^^^^^^^^^^^^^
To add a new function description, you must know that the users only have access to the public functions.
Here is an example of how to add the function description from `I2C API <https://docs.espressif.com/projects/arduino-esp32/en/latest/api/i2c.html>`_:
.. code-block::
setPins
^^^^^^^
This function is used to define the ``SDA`` and ``SCL`` pins.
.. note:: Call this function before ``begin`` to change the pins from the default ones.
.. code-block:: arduino
bool setPins(int sdaPin, int sclPin);
* ``sdaPin`` sets the GPIO to be used as the I2C peripheral data line.
* ``sclPin`` sets the GPIO to be used as the I2C peripheral clock line.
The default pins may vary from board to board. On the *Generic ESP32* the default I2C pins are:
* ``sdaPin`` **GPIO21**
* ``sclPin`` **GPIO22**
This function will return ``true`` if the peripheral was configured correctly.
Be sure to include a very comprehensive description, add all the parameters in and out, and describe the desired output.
If the function uses a specific structure, you can also describe the structure in the same function block or add a specific section if the structure is shared with other functions.
Basic Usage
^^^^^^^^^^^
Some APIs are more complex to use or require more steps in order to configure or initialize. If the API is not straightforward in terms of usability, please consider adding a how-to-use section describing all the steps to get the API configured.
Here is an example:
.. code-block::
Basic Usage
^^^^^^^^^^^
To start using I2C as slave mode on the Arduino, the first step is to include the ``Wire.h`` header to the sketch.
.. code-block:: arduino
#include "Wire.h"
Before calling ``begin``, you must create two callback functions to handle the communication with the master device.
.. code-block:: arduino
Wire.onReceive(onReceive);
and
.. code-block:: arduino
Wire.onRequest(onRequest);
The ``onReceive`` will handle the request from the ``master`` device upon a slave read request and the ``onRequest`` will handle the answer to the master.
Now, we can start the peripheral configuration by calling ``begin`` function with the device address.
.. code-block:: arduino
Wire.begin((uint8_t)I2C_DEV_ADDR);
By using ``begin`` without any arguments, all the settings will be done by using the default values. To set the values on your own, see the function description. This function is described here: `i2c begin`_
Example Application
^^^^^^^^^^^^^^^^^^^
It is very important to include at least one application example or a code snippet to help people using the API.
If the API does not have any application example, you can embed the code directly. However, if the example is available, you must include it as a literal block.
.. code-block::
.. literalinclude:: ../../../libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino
:language: arduino
Sphinx Basics
-------------
Heading Levels
**************
The heading levels used on this documentation are:
* **H1**: - (Dash)
* **H2**: * (Asterisk)
* **H3**: ^ (Circumflex)
* **H4**: # (Sharp)
Code Block
**********
To add a code block, you can use the following structure:
.. code-block::
.. code-block:: arduino
bool begin(); //Code example
Links
*****
To include links to external content, you can use two ways.
* First option:
.. code-block::
`Arduino Wire Library`_
_Arduino Wire Library: https://www.arduino.cc/en/reference/wire
* Second option:
.. code-block::
`Arduino Wire Library <https://www.arduino.cc/en/reference/wire>`_
Images
******
To include images in the docs, first, add all the files into the ``_static`` folder with a filename that makes sense for the topic.
After that, you can use the following structure to include the image in the docs.
.. code-block::
.. figure:: ../_static/arduino_i2c_master.png
:align: center
:width: 720
:figclass: align-center
You can adjust the ``width`` according to the image size.
Be sure the file size does not exceed 600kB.
Support
*******
If you need support on the documentation, you can ask a question in the discussion `here <https://github.com/espressif/arduino-esp32/discussions>`_.
Additional Guidelines
---------------------
If you want to contribute with code on the Arduino ESP32 core, be sure to follow the `ESP-IDF Documenting Code <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/contribute/documenting-code.html>`_ as a reference.
.. _Arduino-ESP32: https://github.com/espressif/arduino-esp32
.. _Sphinx: https://www.sphinx-doc.org/en/master/
.. _ReadTheDocs: https://readthedocs.org/
.. _reStructuredText: https://docutils.sourceforge.io/rst.html

View File

@ -0,0 +1,10 @@
######
Guides
######
.. toctree::
:caption: Guides:
:maxdepth: 1
:glob:
*

View File

@ -0,0 +1,248 @@
######################
Arduino IDE Tools Menu
######################
Introduction
------------
This guide is a walkthrough of the Arduino IDE configuration menu for the ESP32 System on Chip (SoC's). In this guide, you will see the most relevant configuration
to get your project optimized and working.
Since some boards and SoC's may vary in terms of hardware configuration, be sure you know all the board characteristics that you are using, like flash memory size, SoC variant (ESP32 family), PSRAM, etc.
.. note:: To help you identify the characteristics, you can see the `Espressif Product Selector`_.
Arduino IDE
-----------
The Arduino IDE is widely used for ESP32 on Arduino development and offers a wide variety of configurations.
Tools Menu
----------
To properly configure your project build and flash, some settings must be done in order to get it compiled and flashed without any issues.
Some boards are natively supported and almost no configuration is required. However, if your is not yet supported or you have a custom board, you need to configure the environment by yourself.
For more details or to add a new board, see the `boards.txt`_ file.
Generic Options
---------------
Most of the options are available for every ESP32 family. Some options will be available only for specific targets, like the USB configuration.
Board
*****
This option is the target board and must be selected in order to get all the default configuration settings. Once you select the correct board, you will see that some configurations will be automatically selected, but be aware that some boards can have multiple versions (i.e different flash sizes).
To select the board, go to ``Tools -> Board -> ESP32 Arduino`` and select the target board.
If your board is not present on this list, you can select the generic ``ESP32-XX Dev Module``.
Currently, we have one generic development module for each of the supported targets.
If the board selected belongs to another SoC family, you will see the following information at the build output:
``A fatal error occurred: This chip is ESP32 not ESP32-S2. Wrong --chip argument?``
Upload Speed
************
To select the flashing speed, change the ``Tools -> Upload Speed``. This value will be used for flashing the code to the device.
.. note:: If you have issues while flashing the device at high speed, try to decrease this value. This could be due to the external serial-to-USB chip limitations.
CPU Frequency
*************
On this option, you can select the CPU clock frequency. This option is critical and must be selected according to the high-frequency crystal present on the board and the radio usage (Wi-Fi and Bluetooth).
In some applications, reducing the CPU clock frequency is recommended in order to reduce power consumption.
If you don't know why you should change this frequency, leave the default option.
Flash Frequency
***************
Use this function to select the flash memory frequency. The frequency will be dependent on the memory model.
* **40MHz**
* **80MHz**
If you don't know if your memory supports **80Mhz**, you can try to upload the sketch using the **80MHz** option and watch the log output via the serial monitor.
.. note:: In some boards/SoC, the flash frequency is automatically selected according to the flash mode. In some cases (i.e ESP32-S3), the flash frequency is up to 120MHz.
Flash Mode
**********
This option is used to select the SPI communication mode with the flash memory.
Depending on the application, this mode can be changed in order to increase the flash communication speed.
* **QIO** - Quad I/O Fast Read
* Four SPI pins are used to write to the flash and to read from the flash.
* **DIO** - Dual I/O Fast Read
* Two SPI pins are used to write to the flash and to read from the flash.
* **QOUT** - Quad Output Fast Read
* Four SPI pins are used to read the flash data.
* **DOUT** - Dual Output Fast Read
* Two SPI pins are used to read flash data.
* **OPI** - Octal I/O
* Eight SPI pins are used to write and to read from the flash.
If you don't know how the board flash is physically connected or the flash memory model, try the **QIO** at **80MHz** first.
Flash Size
**********
This option is used to select the flash size. The flash size should be selected according to the flash model used on your board.
* **2MB** (16Mb)
* **4MB** (32Mb)
* **8MB** (64Mb)
* **16MB** (128Mb)
If you choose the wrong size, you may have issues when selecting the partition scheme.
Embedded Flash
^^^^^^^^^^^^^^
Some SoC has embedded flash. The ESP32-S3 is a good example.
.. note:: Check the manufacturer part number of your SoC/module to see the right version.
Example: **ESP32-S3FH4R2**
This particular ESP32-S3 variant comes with 4MB Flash and 2MB PSRAM.
**Options for Embedded Flash**
* **Fx4** 4MB Flash (*QIO*)
* **Fx8** 8MB Flash (*QIO*)
* **V** 1.8V SPI
The **x** stands for the temperature range specification.
* **H** High Temperature (*-40 to 85ºC*)
* **N** Low Temeprature (*-40 to 65ºC*)
For more details, please see the corresponding datasheet at `Espressif Product Selector`_.
Partition Scheme
****************
This option is used to select the partition model according to the flash size and the resources needed, like storage area and OTA (Over The Air updates).
.. note:: Be careful selecting the right partition according to the flash size. If you select the wrong partition, the system will crash.
Core Debug Level
****************
This option is used to select the Arduino core debugging level to be printed to the serial debug.
* **None** - Prints nothing.
* **Error** - Only at error level.
* **Warning** - Only at warning level and above.
* **Info** - Only at info level and above.
* **Debug** - Only at debug level and above.
* **Verbose** - Prints everything.
PSRAM
*****
The PSRAM is an internal or external extended RAM present on some boards, modules or SoC.
This option can be used to ``Enable`` or ``Disable`` PSRAM. In some SoCs, you can select the PSRAM mode as the following.
* **QSPI PSRAM** - Quad PSRAM
* **OPI PSRAM** - Octal PSRAM
Embedded PSRAM
^^^^^^^^^^^^^^
Some SoC has embedded PSRAM. The ESP32-S3 is a good example.
Example: **ESP32-S3FH4R2**
This particular ESP32-S3 comes with 4MB Flash and 2MB PSRAM.
**Options for Embedded Flash and PSRAM**
* **R2** 2MB PSRAM (*QSPI*)
* **R8** 8MB PSRAM (*OPI*)
* **V** 1.8V SPI
The **x** stands for the temperature range specification.
* **H** High Temperature (*-40 to 85ºC*)
* **N** Low Temeprature (*-40 to 65ºC*)
For more details, please see the corresponding datasheet at `Espressif Product Selector`_.
Arduino Runs On
***************
This function is used to select the core that runs the Arduino core. This is only valid if the target SoC has 2 cores.
When you have some heavy task running, you might want to run this task on a different core than the Arduino tasks. For this reason, you have this configuration to select the right core.
Events Run On
*************
This function is also used to select the core that runs the Arduino events. This is only valid if the target SoC has 2 cores.
Port
****
This option is used to select the serial port to be used on the flashing and monitor.
USB Options
-----------
Some ESP32 families have a USB peripheral. This peripheral can be used for flashing and debugging.
To see the supported list for each SoC, see this section: `Libraries <../libraries.html>`_.
The USB option will be available only if the correct target is selected.
USB CDC On Boot
***************
The USB Communications Device Class, or USB CDC, is a class used for basic communication to be used as a regular serial controller (like RS-232).
This class is used for flashing the device without any other external device attached to the SoC.
This option can be used to ``Enable`` or ``Disable`` this function at the boot. If this option is ``Enabled``, once the device is connected via USB, one new serial port will appear in the list of the serial ports.
Use this new serial port for flashing the device.
This option can be used as well for debugging via the ``Serial Monitor`` using **CDC** instead of the **UART0**.
To use the UART as serial output, you can use ``Serial0.print("Hello World!");`` instead of ``Serial.print("Hello World!");`` which will be printed using USB CDC.
USB Firmware MSC On Boot
************************
The USB Mass Storage Class, or USB MSC, is a class used for storage devices, like a USB flash drive.
This option can be used to ``Enable`` or ``Disable`` this function at the boot. If this option is ``Enabled``, once the device is connected via USB, one new storage device will appear in the system as a storage drive.
Use this new storage drive to write and read files or to drop a new firmware binary to flash the device.
.. figure:: ../_static/usb_msc_drive.png
:align: center
:width: 720
:figclass: align-center
USB DFU On Boot
***************
The USB Device Firmware Upgrade is a class used for flashing the device through USB.
This option can be used to ``Enable`` or ``Disable`` this function at the boot. If this option is ``Enabled``, once the device is connected via USB, the device will appear as a USB DFU capable device.
.. _Espressif Product Selector: https://products.espressif.com/
.. _boards.txt: https://github.com/espressif/arduino-esp32/blob/master/boards.txt

View File

@ -8,11 +8,12 @@ Here you will find all the relevant information about the project.
This is a work in progress documentation and we will appreciate your help! We are looking for contributors!
.. toctree::
:maxdepth: 2
:maxdepth: 1
:caption: Contents:
Getting Started <getting_started>
Libraries <libraries>
Guides <guides/guides>
Tutorials <tutorials/tutorials>
Advanced Utilities <advanced_utils>
FAQ <faq>

View File

@ -7,16 +7,21 @@ This guide will show how to install the Arduino-ESP32 support.
Before Installing
-----------------
We recommend you install the support using the Boards Manager, but other options are available depending on your operating system.
We recommend you install the support using your favorite IDE, but other options are available depending on your operating system.
To install Arduino-ESP32 support, you can use one of the following options.
Installing using Boards Manager
-------------------------------
Installing using Arduino IDE
----------------------------
This is the preferred and easiest way to install Arduino-ESP32.
.. figure:: _static/logo_arduino.png
:align: center
:width: 200
:figclass: align-center
This is the way to install Arduino-ESP32 directly from the Arduino IDE.
.. note::
Currently, the support for new chips (ESP32-S2 and ESP32-C3) is in the development release. Consider installing the development release if you need to test the new supported SoC in beta.
For overview of SoC's support, take a look on `Supported Soc's table <https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html#supported-soc-s>`_ where you can find if the particular chip is under stable or development release.
- Stable release link::
@ -58,8 +63,70 @@ To start the installation process using the Boards Managaer, follow these steps:
- Restart Arduino IDE.
Windows
-------
Installing using PlatformIO
---------------------------
.. figure:: _static/logo_pio.png
:align: center
:width: 200
:figclass: align-center
PlatformIO is one of most popular embedded development tool. Currently, it supports Arduino ESP32 and ESP-IDF from Espressif (other platforms are also supported).
To install PIO, you can follow this Getting Started, provided by PIO at `docs.platformio.org`_.
To test the latest Arduino ESP32, you need to change your project *platform.ini* accordingly.
- Start a new project and select one of the available board. You can change after by changing the *platform.ini* file.
- For ESP32
.. code-block:: bash
[env:arduino-esp32]
platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream
board = esp32dev
framework = arduino
platform_packages =
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#master
- For ESP32-S2 (ESP32-S2-Saola-1 board)
.. code-block:: bash
[env:arduino-esp32s2]
platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream
board = esp32-s2-saola-1
framework = arduino
platform_packages =
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#master
- For ESP32-C3 (ESP32-S3-DevKitM-1 board)
.. code-block:: bash
[env:arduino-esp32c3]
platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream
board = esp32-c3-devkitm-1
framework = arduino
platform_packages =
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#master
Now you're able to use the latest Arduino ESP32 support directly from Espressif GitHub repository.
To get more information about PlatformIO, see the following links:
- `PlatformIO Core (CLI) <https://docs.platformio.org/en/latest/core/index.html>`_
- `PlatformIO Home <https://docs.platformio.org/en/latest/home/index.html>`_
- `Tutorials and Examples <https://docs.platformio.org/en/latest/tutorials/index.html>`_
- `Library Management <https://docs.platformio.org/en/latest/librarymanager/index.html>`_
Windows (manual installation)
-----------------------------
.. warning:: Arduino ESP32 core v2.x.x cannot be used on Windows 8.x x86 (32 bits), Windows 7 or earlier. The Windows 32 bits OS is no longer supported by this toolchain.
@ -150,6 +217,11 @@ How to update to the latest code
Linux
-----
.. figure:: _static/logo_linux.png
:align: center
:width: 200
:figclass: align-center
Debian/Ubuntu
*************
@ -263,20 +335,5 @@ Where ``~/Documents/Arduino`` represents your sketch book location as per "Ardui
- Restart Arduino IDE.
PlatformIO
----------
- `What is PlatformIO? <https://docs.platformio.org/en/latest/what-is-platformio.html?utm_source=github&utm_medium=arduino-esp32>`_
- `PlatformIO IDE <https://platformio.org/platformio-ide?utm_source=github&utm_medium=arduino-esp32>`_
- `PlatformIO Core <https://docs.platformio.org/en/latest/core.html?utm_source=github&utm_medium=arduino-esp32>`_
- `Advanced usage <https://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32>`_: Custom settings, uploading to SPIFFS, Over-the-Air (OTA), staging version
- `Integration with Cloud and Standalone IDEs <https://docs.platformio.org/en/latest/ide.html?utm_source=github&utm_medium=arduino-esp32>`_: Cloud9, Codeanywhere, Eclipse Che (Codenvy), Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, VIM, Visual Studio, and VSCode
- `Project Examples <https://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32#examples>`_
.. _Arduino.cc: https://www.arduino.cc/en/Main/Software
.. _docs.platformio.org: https://docs.platformio.org/en/latest/integration/ide/pioide.html

View File

@ -2,37 +2,178 @@
Library Builder
###############
How to Use Library Builder
--------------------------
About
-----
Espressif has provided a `tool <https://github.com/espressif/esp32-arduino-lib-builder>`_ to simplify building your own compiled libraries for use in Arduino IDE (or your favorite IDE).
To generate custom libraries, follow these steps:
Espressif provides a `tool <https://github.com/espressif/esp32-arduino-lib-builder>`_ to simplify building your own compiled libraries for use in Arduino IDE (or your favorite IDE).
This tool can be used to change the project or a specific configuration according to your needs.
- Step 1 - Clone the ESP32 Arduino lib builder::
Installing
----------
To install the Library Builder into your environment, please, follow the instructions below.
- Clone the ESP32 Arduino lib builder:
.. code-block:: bash
git clone https://github.com/espressif/esp32-arduino-lib-builder
- Step 2 - Go to the ``esp32-arduino-lib-builder`` folder::
- Go to the ``esp32-arduino-lib-builder`` folder:
.. code-block:: bash
cd esp32-arduino-lib-builder
- Step 3 - Run the ``update-components`` script::
- Build:
./tools/update-components.sh`
.. code-block:: bash
- Step 4 - Run ``install-esp-idf`` installation script (if you already have an ``$IDF_PATH`` defined, it will use your local copy of the repository)::
./build.sh
./tools/install-esp-idf.sh
If everything works, you may see the following message: ``Successfully created esp32 image.``
- Step 5 - Copy the configuration (recommended) or directly edit sdkconfig using ``idf.py menuconfig``::
Dependencies
************
cp sdkconfig.esp32s2 sdkconfig
To build the library you will need to install some dependencies. Maybe you already have installed it, but it is a good idea to check before building.
- Step 6 - Build::
- Install all dependencies (**Ubuntu**):
idf.py build
.. code-block:: bash
The script automates the process of building `Arduino as an ESP-IDF component <https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md>`_.
Once it is complete, you can cherry pick the needed libraries from ``out/tools/sdk/lib``, or run ``tools/copy-to-arduino.sh`` to copy the entire built system.
``tools/config.sh`` contains a number of variables that control the process, particularly the ``$IDF_BRANCH`` variable. You can adjust this to try building against newer versions, but there are absolutely no guarantees that any components will work or even successfully compile against a newer IDF.
sudo apt-get install git wget curl libssl-dev libncurses-dev flex bison gperf cmake ninja-build ccache jq
- Install Python and upgrade pip:
.. code-block:: bash
sudo apt-get install python3
sudo pip install --upgrade pip
- Install all required packages:
.. code-block:: bash
pip install --user setuptools pyserial click cryptography future pyparsing pyelftools
Building
--------
If you have all the dependencies met, it is time to build the libraries.
To build using the default configuration:
.. code-block:: bash
./build.sh
Custom Build
************
There are some options to help you create custom libraries. You can use the following options:
Usage
^^^^^
.. code-block:: bash
build.sh [-s] [-A arduino_branch] [-I idf_branch] [-i idf_commit] [-c path] [-t <target>] [-b <build|menuconfig|idf_libs|copy_bootloader|mem_variant>] [config ...]
Skip Install/Update
^^^^^^^^^^^^^^^^^^^
Skip installing/updating of ESP-IDF and all components
.. code-block:: bash
./build.sh -s
This option can be used if you already have the ESP-IDF and all components already in your environment.
Set Arduino-ESP32 Branch
^^^^^^^^^^^^^^^^^^^^^^^^
Set which branch of arduino-esp32 to be used for compilation
.. code-block:: bash
./build.sh -A <arduino_branch>
Set ESP-IDF Branch
^^^^^^^^^^^^^^^^^^
Set which branch of ESP-IDF is to be used for compilation
.. code-block:: bash
./build.sh -I <idf_branch>
Set the ESP-IDF Commit
^^^^^^^^^^^^^^^^^^^^^^
Set which commit of ESP-IDF to be used for compilation
.. code-block:: bash
./build.sh -i <idf_commit>
Deploy
^^^^^^
Deploy the build to github arduino-esp32
.. code-block:: bash
./build.sh -d
Set the Arduino-ESP32 Destination Folder
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Set the arduino-esp32 folder to copy the result to. ex. '$HOME/Arduino/hardware/espressif/esp32'
.. code-block:: bash
./build.sh -c <path>
This function is used to copy the compiled libraries to the Arduino folder.
Set the Target
^^^^^^^^^^^^^^
Set the build target(chip). ex. 'esp32s3'
.. code-block:: bash
./build.sh -t <target>
This build command will build for the ESP32-S3 target. You can specify other targets.
* esp32
* esp32s2
* esp32c3
* esp32s3
Set Build Type
^^^^^^^^^^^^^^
Set the build type. ex. 'build' to build the project and prepare for uploading to a board.
.. note:: This command depends on the ``-t`` argument.
.. code-block:: bash
./build.sh -t esp32 -b <build|menuconfig|idf_libs|copy_bootloader|mem_variant>
Additional Configuration
^^^^^^^^^^^^^^^^^^^^^^^^
Specify additional configs to be applied. ex. 'qio 80m' to compile for QIO Flash@80MHz. Requires -b
.. note:: This command requires the ``-b`` to work properly.
.. code-block:: bash
./build.sh -t esp32 -b idf_libs qio 80m

View File

@ -28,7 +28,7 @@ Currently, the Arduino ESP32 supports the following peripherals with Arduino API
+---------------+---------------+---------------+---------------+-------------------------------+
| I2C | Yes | Yes | Yes | |
+---------------+---------------+---------------+---------------+-------------------------------+
| I2S | No | No | No | WIP |
| I2S | Yes | No | No | WIP |
+---------------+---------------+---------------+---------------+-------------------------------+
| LEDC | Yes | Yes | Yes | |
+---------------+---------------+---------------+---------------+-------------------------------+
@ -64,12 +64,7 @@ Notes
.. note:: Some peripherals are not available for all ESP32 families. To see more details about it, see the corresponding SoC at `Product Selector <https://products.espressif.com>`_ page.
Datasheet
^^^^^^^^^
* `ESP32 <https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf>`_
* `ESP32-S2 <https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf>`_
* `ESP32-C3 <https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf>`_
.. include:: common/datasheet.inc
APIs
----
@ -78,13 +73,6 @@ The Arduino ESP32 offers some unique APIs, described in this section:
.. toctree::
:maxdepth: 1
Bluetooth <api/bluetooth>
Deep Sleep <api/deepsleep>
ESPNOW <api/espnow>
GPIO <api/gpio>
I2C <api/i2c>
RainMaker <api/rainmaker>
Reset Reason <api/reset_reason>
USB <api/usb.rst>
Wi-Fi <api/wifi>
:glob:
api/*

View File

@ -62,7 +62,7 @@ JTAG Dedicated GPIOs
SD/SDIO/MMC HostController Dedicated GPIOs
Motor PWM Any GPIO
SDIO/SPI SlaveController Dedicated GPIOs
UART Any GPIO
UART Any GPIO[1]
I2C Any GPIO
I2S Any GPIO
LED PWM Any GPIO
@ -72,8 +72,11 @@ Parallel QSPI Dedicated GPIOs
EMAC Dedicated GPIOs
Pulse Counter Any GPIO
TWAI Any GPIO
USB Dedicated GPIOs
============================== ===================================
[1] except for the download/programming mode decided by the bootloader.
This table is present on each datasheet provided by Espressif.
Usage Examples
@ -106,16 +109,11 @@ To change the pins, we must call the ``Wire.setPins(int sda, int scl);`` functio
A similar approach also applies for the other peripherals.
.. include:: ../common/datasheet.inc
Resources
---------
* `ESP32`_ (Datasheet)
* `ESP32-S2`_ (Datasheet)
* `ESP32-C3`_ (Datasheet)
.. _Espressif Systems: https://www.espressif.com
.. _Espressif Product Selector: https://products.espressif.com/
.. _ESP32: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
.. _ESP32-S2: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
.. _ESP32-C3: https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
.. _IO MUX GPIO: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#iomuxgpio

View File

@ -0,0 +1,697 @@
###########
Preferences
###########
Introduction
------------
The Preferences library is unique to arduino-esp32. It should be considered as the replacement for the Arduino EEPROM library.
It uses a portion of the on-board non-volatile memory (NVS) of the ESP32 to store data. This data is retained across restarts and loss of power events to the system.
Preferences works best for storing many small values, rather than a few large values. If you need to store large amounts of data, consider using a file system library such as LitteFS.
The Preferences library is usable by all ESP32 variants.
Preferences Attributes
----------------------
Preferences data is stored in NVS in sections called a "``namespace``". Within each namespace are a set of ``key-value`` pairs. The "``key``" is the name of the data item and the "``value``" is, well, the value of that piece of data. Kind of like variables. The key is the name of the variable and the value is its value. Like variables, a ``key-value`` pair has a data type.
Multiple namespaces are permitted within NVS. The name of each namespace must be unique. The keys within that namespace are unique to that namespace. Meaning the same key name can be used in multiple namespaces without conflict.
Namespace and key names are case sensitive.
Each key name must be unique within a namespace.
Namespace and key names are character strings and are limited to a maximum of 15 characters.
Only one namespace can be open (in use) at a time.
Library Overview
----------------
Library methods are provided to:
- create a namespace;
- open and close a namespace;
- store and retrieve data within a namespace for supported data types;
- determine if a key value has been initialized;
- delete a ``key-value`` pair;
- delete all ``key-value`` pairs in a namespace;
- determine data types stored against a key;
- determine the number of key entries available in the namespace.
Preferences directly suports the following data types:
.. table:: **Table 1 — Preferences Types**
:align: center
+-------------------+-------------------+---------------+
| Preferences Type | Data Type | Size (bytes) |
+===================+===================+===============+
| Bool | bool | 1 |
+-------------------+-------------------+---------------+
| Char | int8_t | 1 |
+-------------------+-------------------+---------------+
| UChar | uint8_t | 1 |
+-------------------+-------------------+---------------+
| Short | int16_t | 2 |
+-------------------+-------------------+---------------+
| UShort | uint16_t | 2 |
+-------------------+-------------------+---------------+
| Int | int32_t | 4 |
+-------------------+-------------------+---------------+
| UInt | uint32_t | 4 |
+-------------------+-------------------+---------------+
| Long | int32_t | 4 |
+-------------------+-------------------+---------------+
| ULong | uint32_t | 4 |
+-------------------+-------------------+---------------+
| Long64 | int64_t | 8 |
+-------------------+-------------------+---------------+
| ULong64 | uint64_t | 8 |
+-------------------+-------------------+---------------+
| Float | float_t | 8 |
+-------------------+-------------------+---------------+
| Double | double_t | 8 |
+-------------------+-------------------+---------------+
| | const char* | |
| String +-------------------+ variable |
| | String | |
+-------------------+-------------------+---------------+
| Bytes | uint8_t | variable |
+-------------------+-------------------+---------------+
String values can be stored and retrieved either as an Arduino String or as a null terminated ``char`` array (C-string).
Bytes type is used for storing and retrieving an arbitrary number of bytes in a namespace.
Workflow
--------
Preferences workflow, once everything is initialized, is pretty simple.
To store a value:
- Open the namespace in read-write mode.
- Put the value into the key.
- Close the namespace.
To retrieve a value:
- Open the namespace in read-only mode.
- Use the key to get the value.
- Close the namespace.
*(Technically, you can retrieve a value if the namespace is open in either read-only or read-write mode but it's good practice to open the namespace in read-only mode if you are only retrieving values.)*
When storing information, a "``put[PreferencesType]``" method referenced to its key is used.
When retrieving information a "``get[PreferencesType]``" method referenced to its key is used.
Ensuring that the data types of your “``get``'s” and “``put``'s” all match, youre good to go.
The nuance is in initializing everything at the start.
Before you can store or retrieve anything using Preferences, both the namespace and the key within that namespace need to exist. So the workflow is:
#. Create or open the namespace.
#. Test for the existence of a key that should exist if the namespace has been initialized.
#. If that key does not exist, create the key(s).
#. Carry on with the rest of your sketch where data can now be stored and retrieved from the namespace.
Each step is discussed below.
.. note::
From here on when referring in general to a method used to store or retrieve data we'll use the shorthand "``putX``" and "``getX``" where the "``X``" is understood to be a Preferences Type; Bool, UInt, Char, and so on from the Preferences Types table above.
..
Create or Open the Namespace
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In your sketch, first insert a declaration of a ``Preferences`` object by including a line like;
.. code-block:: arduino
Preferences mySketchPrefs; // "mySketchPrefs" is the name of the Preferences object.
// Can be whatever you want.
This object is used with the Preferences methods to access the namespace and the key-value pairs it contains.
A namespace is made available for use with the ``.begin`` method:
.. code-block:: arduino
mySketchPrefs.begin("myPrefs", false)
If the namespace does not yet exist, this will create and then open the namespace ``myPrefs``.
If the namespace already exists, this will open the namespace ``myPrefs``.
If the second argument is ``false`` the namespace is opened in read-write (RW) mode — values can be stored in to and retrieved from the namespace. If it is ``true`` the namespace is opened in read-only (RO) mode — values can be retrieved from the namespace but nothing can be stored.
Test for Initial Existence of Your Key(s)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When the ESP32 boots, there is no inherent way to know if this is the very first time it has ever powered on or if it is a subsequent launch and it has run its sketch before. We can use Preferences to store information that is retained across reboots that we can read, and based on that, decide if this is a first-time run and take the required actions if so.
We do this by testing for the existence of a certain key within a namespace. If that key exists, it is safe to assume the key was created during the first-time run of the sketch and so the namespace has already been initialized.
To determine if a key exists, use:
.. code-block:: arduino
isKey("myTestKey")
This returns ``true`` if ``"myTestKey"`` exists in the namespace, and ``false`` if it does not.
By example, consider this code segment:
.. code-block:: arduino
Preferences mySketchPrefs;
String doesExist;
mySketchPrefs.begin("myPrefs", false); // open (or create and then open if it does not
// yet exist) the namespace "myPrefs" in RW mode.
bool doesExist = mySketchPrefs.isKey("myTestKey");
if (doesExist == false) {
/*
If doesExist is false, we will need to create our
namespace key(s) and store a value into them.
*/
// Insert your "first time run" code to create your keys & assign their values below here.
}
else {
/*
If doesExist is true, the key(s) we need have been created before
and so we can access their values as needed during startup.
*/
// Insert your "we've been here before" startup code below here.
}
Creating Namespace Keys and Storing Values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To create a key, we use one of the ``.putX`` methods, matching ``"X"`` to the Preferences Type of the data we wish to store:
.. code-block:: arduino
myPreferences.putX("myKeyName", value)
If ``"myKeyName"`` does not exist in the namespace, it is first created and then ``value`` is stored against that keyname. The namespace must be open in RW mode to do this. Note that ``value`` is not optional and must be provided with every "``.putX``" statement. Thus every key within a namespace will always hold a valid value.
An example is:
.. code-block:: arduino
myPreferences.putFloat("pi", 3.14159265359); // stores an float_t data type
// against the key "pi".
Reading Values From a Namespace
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Once a key exists in a namespace and the namespace is open, its value is retrieved using one of the ``getX`` methods, matching ``"X"`` to the type of data stored against that key.
.. code-block:: arduino
myPreferences.getX("myKeyName")
Like so:
.. code-block:: arduino
String myString = myPreferences.getString("myStringKey");
This will retrieve the String value from the namespace key ``"myStringKey"`` and assign it to the String type variable ``myString``.
Summary
~~~~~~~
So the basics of using Preferences are:
#. You cannot store into or retrieve from a ``key-value`` pair until a namespace is created and opened and the key exists in that namespace.
#. If the key already exists, it was created the first time the sketch was run.
#. A key value can be retrieved regardless of the mode in which the namespace was opened, but a value can only be stored if the namespace is open in read-write mode.
#. Data types of the “``get``'s” and “``put``'s” must match.
#. Remember the 15 character limit for namespace and key names.
Real World Example
------------------
Here is part of a ``setup()`` function that uses Preferences.
Its purpose is to set either a factory default configuration if the system has never run before, or use the last configuration if it has.
When started, the system has no way of knowing which of the above conditions is true. So the first thing it does after opening the namespace is check for the existence of a key that we have predetermined can only exist if we have previously run the sketch. Based on its existence we decide if a factory default set of operating parameters should be used (and in so doing create the namespace keys and populate the values with defaults) or if we should use operating parameters from the last time the system was running.
.. code-block:: arduino
#include <Preferences.h>
#define RW_MODE false
#define RO_MODE true
Preferences stcPrefs;
void setup() {
// not the complete setup(), but in setup(), include this...
stcPrefs.begin("STCPrefs", RO_MODE); // Open our namespace (or create it
// if it doesn't exist) in in RO mode.
bool tpInit = stcPrefs.isKey("nvsInit"); // Test for the existence of the "already initialized" key.
if (tpInit == false) {
// If tpInit is 'false', the key "nvsInit" does not yet exist therefore this
// must be our first-time run. We need to set up our Preferences namespace keys. So...
stcPrefs.end(); // close the namespace in RO mode and...
stcPrefs.begin("STCPrefs", RW_MODE); // reopen it in RW mode.
// The .begin() method created the "STCPrefs" namespace and since this is our
// first-time run we will create our keys and store the initial "factory default" values.
stcPrefs.putUChar("curBright", 10);
stcPrefs.putString("talChan", "one");
stcPrefs.putLong("talMax", -220226);
stcPrefs.putBool("ctMde", true);
stcPrefs.putBool("nvsInit", true); // Create the "already initialized" key and store a value.
// The "factory defaults" are created and stored so...
stcPrefs.end(); // Close the namespace in RW mode and...
stcPrefs.begin("STCPrefs", RO_MODE); // reopen it in RO mode so the setup code
// outside this first-time run 'if' block
// can retrieve the run-time values
// from the "STCPrefs" namespace.
}
// Retrieve the operational parameters from the namespace
// and save them into their run-time variables.
currentBrightness = stcPrefs.getUChar("curBright"); //
tChannel = stcPrefs.getString("talChan"); // The LHS variables were defined
tChanMax = stcPrefs.getLong("talMax"); // earlier in the sketch.
ctMode = stcPrefs.getBool("ctMde"); //
// All done. Last run state (or the factory default) is now restored.
stcPrefs.end(); // Close our preferences namespace.
// Carry on with the rest of your setup code...
// When the sketch is running, it updates any changes to an operational parameter
// to the appropriate key-value pair in the namespace.
}
Utility Functions
-----------------
There are a few other functions useful when working with namespaces.
Deleting key-value Pairs
~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: arduino
preferences.clear();
..
- Deletes *all* the key-value pairs in the currently opened namespace.
- The namespace still exists.
- The namespace must be open in read-write mode for this to work.
.. code-block:: arduino
preferences.remove("keyname");
..
- Deletes the "keyname" and value associated with it from the currently opened namespace.
- The namespace must be open in read-write mode for this to work.
- Tip: use this to remove the "test key" to force a "factory reset" during the next reboot (see the *Real World Example* above).
If either of the above are used, the ``key-value`` pair will need to be recreated before using it again.
Determining the Number of Available Keys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For each namespace, Preferences keeps track of the keys in a key table. There must be an open entry in the table before a key can be created. This method will return the number of entires available in the table.
.. code-block:: arduino
freeEntries()
..
To send to the serial monitor the number of available entries the following could be used.
.. code-block:: arduino
Preferences mySketchPrefs;
mySketchPrefs.begin("myPrefs", true);
size_t whatsLeft = freeEntries(); // this method works regardless of the mode in which the namespace is opened.
Serial.printf("There are: %u entries available in the namespace table.\n, whatsLeft);
mySketchPrefs.end();
..
The number of available entries in the key table changes depending on the number of keys in the namespace and also the dynamic size of certain types of data stored in the namespace. Details are in the `Preferences API Reference`_.
Do note that the number of entries in the key table does not guarantee that there is room in the opened NVS namespace for all the data to be stored in that namespace. Refer to the espressif `Non-volatile storage library`_ documentation for full details.
Determining the Type of a key-value Pair
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Keeping track of the data types stored against a key-value pair is one of the bookkeeping tasks left to you. Should you want to discover the Preferences data type stored against a given key, use this method:
.. code-block:: arduino
getType("myKey")
..
As in:
.. code-block:: arduino
PreferenceType whatType = getType("myKey");
..
The value returned is a ``PreferenceType`` value that maps to a Preferences Type. Refer to the description in the `Preferences API Reference`_ for details.
Working with Large Data
-----------------------
Recall that the Preferences library works best for storing many small values, rather than a few large values. Regardless, it may be desirable to store larger amounts of arbitrary data than what is provided by the basic types in the Preferences Types table above.
The library provides the following methods to facilitate this.
.. code-block:: arduino
putBytes("myBytesKey", value, valueLen)
getBytes("myBytesKey", buffer, valueLen)
getBytesLength("myBytesKey")
..
The ``put`` and ``get`` ``Bytes`` methods store and retrieve the data. The ``getBytesLength`` method is used to find the size of the data stored against the key (which is needed to retrieve ``Bytes`` data).
As the names of the methods imply, they operate on variable length bytes of data (often referred to as a "blob") and not on individual elements of a certain data type.
Meaning if you store for example an array of type ``int16_t`` against a ``Bytes`` type key, the value of that key becomes a series of bytes with no associated data type. Or if you like, all data stored as a blob gets converted to a series of ``uint8_t`` type bytes.
As a result, when using the ``getBytes`` method to retrieve the value of the key, what is returned to the buffer is a series of ``uint8_t`` bytes. It is up to you to manage the data types and size of the arrays and buffers when retrieving ``Bytes`` data.
Fortunately this is not as difficult as it may sound as the ``getBytesLength`` method and the ``sizeof`` operator help with keeping track of it all.
This is best explained with an example. Here the ``Bytes`` methods are used to store and retrieve an array, while ensuring the data type is preserved.
.. code-block:: arduino
/*
* An example sketch using the Preferences "Bytes" methods
* to store and retrieve an arbitrary number of bytes in
* a namespace.
*/
#include <Preferences.h>
#define RO_MODE true
#define RW_MODE false
void setup() {
Preferences mySketchPrefs;
Serial.begin(115200);
delay(250);
mySketchPrefs.begin("myPrefs", RW_MODE); // open (or create) the namespace "myPrefs" in RW mode
mySketchPrefs.clear(); // delete any previous keys in this namespace
// Create an array of test values. We're using hex numbers throughout to better show how the bytes move around.
int16_t myArray[] = { 0x1112, 0x2122, 0x3132, 0x4142, 0x5152, 0x6162, 0x7172 };
Serial.println("Printing myArray...");
for (int i = 0; i < sizeof(myArray) / sizeof(int16_t); i++) {
Serial.print(myArray[i], HEX); Serial.print(", ");
}
Serial.println("\r\n");
// In the next statement, the second sizeof() needs to match the data type of the elements of myArray
Serial.print("The number of elements in myArray is: "); Serial.println( sizeof(myArray) / sizeof(int16_t) );
Serial.print("But the size of myArray in bytes is: "); Serial.println( sizeof(myArray) );
Serial.println("");
Serial.println("Storing myArray into the Preferences namespace \"myPrefs\" against the key \"myPrefsBytes\".");
// Note: in the next statement, to store the entire array, we must use the
// size of the arrray in bytes, not the number of elements in the array.
mySketchPrefs.putBytes( "myPrefsBytes", myArray, sizeof(myArray) );
Serial.print("The size of \"myPrefsBytes\" is (in bytes): "); Serial.println( mySketchPrefs.getBytesLength("myPrefsBytes") );
Serial.println("");
int16_t myIntBuffer[20] = {}; // No magic about 20. Just making a buffer (array) big enough.
Serial.println("Retrieving the value of myPrefsBytes into myIntBuffer.");
Serial.println(" - Note the data type of myIntBuffer matches that of myArray");
mySketchPrefs.getBytes( "myPrefsBytes", myIntBuffer, mySketchPrefs.getBytesLength("myPrefsBytes") );
Serial.println("Printing myIntBuffer...");
// In the next statement, sizeof() needs to match the data type of the elements of myArray
for (int i = 0; i < mySketchPrefs.getBytesLength("myPrefsBytes") / sizeof(int16_t); i++) {
Serial.print(myIntBuffer[i], HEX); Serial.print(", ");
}
Serial.println("\r\n");
Serial.println("We can see how the data from myArray is actually stored in the namespace as follows.");
uint8_t myByteBuffer[40] = {}; // No magic about 40. Just making a buffer (array) big enough.
mySketchPrefs.getBytes( "myPrefsBytes", myByteBuffer, mySketchPrefs.getBytesLength("myPrefsBytes") );
Serial.println("Printing myByteBuffer...");
for (int i = 0; i < mySketchPrefs.getBytesLength("myPrefsBytes"); i++) {
Serial.print(myByteBuffer[i], HEX); Serial.print(", ");
}
Serial.println("");
}
void loop() {
;
}
..
The resulting output is:
::
Printing myArray...
1112, 2122, 3132, 4142, 5152, 6162, 7172,
The number of elements in myArray is: 7
But the size of myArray in bytes is: 14
Storing myArray into the Preferences namespace "myPrefs" against the key "myPrefsBytes".
The size of "myPrefsBytes" is (in bytes): 14
Retrieving the value of myPrefsBytes into myIntBuffer.
- Note the data type of myIntBuffer matches that of myArray
Printing myIntBuffer...
1112, 2122, 3132, 4142, 5152, 6162, 7172,
We can see how the data from myArray is actually stored in the namespace as follows.
Printing myByteBuffer...
12, 11, 22, 21, 32, 31, 42, 41, 52, 51, 62, 61, 72, 71,
You can copy the sketch and change the data type and values in ``myArray`` and follow along with the code and output to see how the ``Bytes`` methods work. The data type of ``myIntBuffer`` should be changed to match that of ``myArray`` (and check the "``sizeof()``'s" where indicated in the comments).
The main takeaway is to remember you're working with bytes and so attention needs to be paid to store all the data based on the size of its type and to manage the buffer size and data type for the value retrieved.
Multiple Namespaces
-------------------
As stated earlier, multiple namespaces can exist in the Preferences NVS partition. However, only one namespace at a time can be open (in use).
If you need to access a different namespace, close the one before opening the other. For example:
.. code-block:: arduino
Preferences currentNamespace;
currentNamespace.begin("myNamespace", false);
// do stuff...
currentNamespace.end(); // closes 'myNamespace'
currentNamespace.begin("myOtherNamespace", false); // opens a different Preferences namesspace.
// do other stuff...
currentNamespace.end(); // closes 'myOtherNamespace'
Here the "``currentNamespace``" object is reused, but different Preferences objects can be declared and used. Just remember to keep it all straight as all "``putX``'s" and "``getX``'s", etc. will only operate on the single currently opened namespace.
A Closer Look at ``getX``
--------------------------
Methods in the Preferences library return a status code that can be used to determine if the method completed successfully. This is described in the `Preferences API Reference`_.
Assume we have a key named "``favourites``" that contains a value of a ``String`` data type.
After executing the statement:
.. code-block:: arduino
dessert = mySketchPrefs.getString("favourites");
..
the variable ``dessert`` will contain the value of the string stored against the key ``"favourites"``.
But what if something went wrong and the ``getString`` call failed to retrieve the key value? How would we be able to detect the error?
With Preferences, the ``getX`` methods listed in Table 2 below will return a default value if an error is encountered.
.. table:: **Table 2 — getX Methods Defaults**
:align: center
+------------------+-----------------+
| Preferences | Default Return |
| Type | Value |
+==================+=================+
| Char, UChar, | 0 |
| | |
| Short, UShort, | |
| | |
| Int, UInt, | |
| | |
| Long, ULong, | |
| | |
| Long64, ULong64 | |
+------------------+-----------------+
| Bool | false |
+------------------+-----------------+
| Float | NAN |
| | |
| Double | |
+------------------+-----------------+
| String (String) | "" |
+------------------+-----------------+
| String (* buf) | \\0 |
+------------------+-----------------+
Thus to detect an error we could compare the value returned against its default return value and if they are equal assume an error occurred and take the appropriate action.
But what if a method default return value is also a potential legitimate value? How can we then know if an error occurred?
As it turns out, the complete form of the ``getX`` methods for each of the Preferences Types in Table 2 is:
.. code-block:: arduino
preferences.getX("myKey", myDefault)
..
In this form the method will return either the value associated with "``myKey``" or, if an error occurred, return the value ``myDefault``, where ``myDefault`` must be the same data type as the ``getX``.
Returning to the example above:
.. code-block:: arduino
dessert = mySketchPrefs.getString("favourites", "gravel");
..
will assign to the variable ``dessert`` the String ``gravel`` if an error occurred, or the value stored against the key ``favourites`` if not.
If we predetermine a default value that is outside all legitimate values, we now have a way to test if an error actually occurred.
In summary, if you need to confirm that a value was retrieved without error from a namespace, use the complete form of the ``getX`` method with a predetermined default "this can only happen if an error" value and compare that against the value returned by the call. Otherwise, you can omit the default value as the call will return the default for that particular ``getX`` method.
Additional detail is given in the `Preferences API Reference`_.
Advanced Item
-------------
In the arduino-esp32 implementation of Preferences there is no method to completely remove a namespace. As a result, over the course of a number of projects, it is possible that the ESP32 NVS Preferences partition becomes cluttered or full.
To completely erase and reformat the NVS memory used by Preferences, create and run a sketch that contains:
.. code-block:: arduino
#include <nvs_flash.h>
void setup() {
nvs_flash_erase(); // erase the NVS partition and...
nvs_flash_init(); // initialize the NVS partition.
while (true);
}
void loop() {
;
}
..
.. warning::
**You should download a new sketch to your board immediately after running the above or else it will reformat the NVS partition every time it is powered up or restarted!**
Resources
---------
* `Preferences API Reference <../api/preferences.html>`_
* `Non-volatile storage library`_ (espressif-IDF API Reference)
* `Official ESP-IDF documentation`_ (espressif-IDF Reference)
.. _Non-volatile storage library: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/storage/nvs_flash.html
.. _Official ESP-IDF documentation: https://docs.espressif.com/projects/esp-idf/en/stable
Contribute
----------
.. ==*Do not change! Keep as is.*==
To contribute to this project, see `How to contribute`_.
If you have any **feedback** or **issue** to report on this tutorial, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
Before creating a new issue, be sure to try the Troubleshooting and to check if the same issue was already created by someone else.
.. _How to Contribute: https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst
.. ---- EOF ----

View File

@ -3,10 +3,8 @@ Tutorials
#########
.. toctree::
:maxdepth: 2
:caption: Tutorials:
:maxdepth: 1
:glob:
Blink <blink>
Basic <basic>
DFU <dfu>
GPIO Matrix and Pin Mux <io_mux>
*

21
idf_component.yml Normal file
View File

@ -0,0 +1,21 @@
description: "Arduino core for ESP32, ESP32-S and ESP32-C series of SoCs"
url: "https://github.com/espressif/arduino-esp32"
targets:
- esp32
- esp32s2
- esp32s3
- esp32c3
tags:
- arduino
files:
include:
- "cores/**/*"
- "variants/esp32/**/*"
- "variants/esp32s2/**/*"
- "variants/esp32s3/**/*"
- "variants/esp32c3/**/*"
- "libraries/**/*"
- "CMakeLists.txt"
- "Kconfig.projbuild"
exclude:
- "**/*"

View File

@ -4,6 +4,7 @@
#include "IPAddress.h"
#include "IPv6Address.h"
#include "Print.h"
#include "Stream.h"
#include <functional>
extern "C" {
#include "lwip/ip_addr.h"

View File

@ -10,6 +10,10 @@
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif
BluetoothSerial SerialBT;
void setup() {

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