Compare commits

...

317 commits

Author SHA1 Message Date
Limor "Ladyada" Fried
eeab5cf9da
Merge pull request #23 from adafruit/update-tinyuf2-partition-order
change(partitions): Reorder No OTA TinyUF2 partition scheme to come first on 4MB boards
2025-07-30 20:46:33 -04:00
tyeth
138ea12d9f change(partitions): Reorder No OTA TinyUF2 partition scheme to come first on 4MB boards 2025-07-29 16:56:17 +01:00
Me No Dev
6359af9a0a
Merge pull request #11641 from espressif/feat/esp-zigbee-sdk-166
feat(zigbee): Update ESP-ZIGBEE-SDK to 1.6.6
2025-07-29 13:31:44 +03:00
Lucas Saavedra Vaz
f5b08cd812
feat(codeql): Add CodeQL analysis for interpreted languages (#11662) 2025-07-28 13:38:14 -03:00
Me No Dev
e998f5be8f
Merge pull request #11640 from espressif/feat/updated-template
feat(github): Update template type
2025-07-28 15:08:36 +03:00
Me No Dev
13bacf5086
Merge pull request #11639 from espressif/feat/remove-forum
feat(github): remove ESP32 forum from issue template
2025-07-28 15:08:04 +03:00
Me No Dev
9902934412
Merge pull request #11629 from angelnu/patch-1
Allow calls to timer functions within ISR
2025-07-28 15:07:05 +03:00
Me No Dev
1a56a1dcca
Merge pull request #11608 from PaulaScharf/master
Add senseBox Eye board
2025-07-28 15:06:45 +03:00
Me No Dev
288672980c
Merge pull request #11661 from espressif/fix/idf-component-logs
fix(component): Use external diag logs to avoid error
2025-07-28 14:59:51 +03:00
Jan Procházka
311955ccbb fix(component): Use external diag logs to avoid error 2025-07-28 11:59:01 +02:00
pre-commit-ci-lite[bot]
a5e85f675e
ci(pre-commit): Apply automatic fixes 2025-07-28 07:44:47 +00:00
Paula Scharf
e375698ade feat(board): spelling 2025-07-28 09:44:04 +02:00
pre-commit-ci-lite[bot]
0dcb1d1178
ci(pre-commit): Apply automatic fixes 2025-07-28 06:56:12 +00:00
Paula Scharf
ed6e95d4fc feat(board): use existing led API 2025-07-28 08:46:14 +02:00
Jan Procházka
b3152a4ffc feat(zigbee): Update SDK to latest 2025-07-25 14:10:32 +02:00
Parsaabasi
10e73be714
feat(github): Update template type 2025-07-25 12:49:46 +02:00
Parsaabasi
5c24611b91
feat(github): remove ESP32 forum from issue template 2025-07-25 12:35:55 +02:00
pre-commit-ci-lite[bot]
e3a0a3a6c5
ci(pre-commit): Apply automatic fixes 2025-07-24 11:22:13 +00:00
Angel Nunez Mencias
d55646344d
Merge branch 'master' into patch-1 2025-07-24 00:42:53 +02:00
Angel Nunez Mencias
126039663f
fix: conditional logs when not ISR 2025-07-24 00:09:17 +02:00
Me No Dev
c7520ccef0
fix(report): Update Issue-report.yml for version 3.3.0 2025-07-23 17:15:59 +03:00
Me No Dev
dbaf6a3226
Merge pull request #10884 from espressif/release/v3.3.x
Arduino ESP32 v3.3 based on ESP-IDF v5.5 (master)
2025-07-23 15:28:45 +03:00
Wulu
3da3ad2f2d
feat(board): Add onboard LED support for Waveshare ESP32-S3 Zero (#11630)
Defines the standard LED_BUILTIN and RGB_BUILTIN macros for the Waveshare ESP32-S3 Zero, allowing its onboard WS2812 RGB LED to be controlled via standard Arduino APIs.
2025-07-23 15:28:19 +03:00
Angel Nunez Mencias
67c59a2021
fix: remove log from IRAM function 2025-07-23 07:26:03 +02:00
Angel Nunez Mencias
0bdad7f2a3
Merge branch 'master' into patch-1 2025-07-23 07:23:37 +02:00
Angel Nunez Mencias
e92e631811
feat: Allow calls to timer functions within ISR 2025-07-23 07:11:11 +02:00
pre-commit-ci-lite[bot]
6fdfccf21b
ci(pre-commit): Apply automatic fixes 2025-07-22 22:46:36 +00:00
Me No Dev
2b3b4f05d5
Merge branch 'master' into release/v3.3.x 2025-07-23 01:45:13 +03:00
Jan Procházka
ae634a92e3
fix(zigbee): Fix RGB color calculation (#11624) 2025-07-23 01:44:36 +03:00
Jan Procházka
f08efa1fa3
feat(docs): Updaze Zigbee docs with latest changes (#11627) 2025-07-23 01:43:23 +03:00
Lucas Saavedra Vaz
a14ce89715
fix(tamc_termod_s3): Fix header includes (#11625) 2025-07-23 01:38:01 +03:00
Me No Dev
69d891434b
IDF release/v5.5 b66b5448 (#11626)
IDF release/v5.5 b66b5448
2025-07-23 01:37:23 +03:00
Me No Dev
554de56f40
IDF release/v5.5 25c7c119 (#11623) 2025-07-22 11:23:49 +03:00
Jan Procházka
c369dca062
feat(docs): Add Zigbee library API documentation (#11525)
* feat(docs): Add Zigbee library documentation

* fix: Remove helper scripts

* fix: Proper class naming for better readability

* fix(docs): Fix typos

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* ci(pre-commit): Apply automatic fixes

* fix(docs): Precommit fixes

* fix(docs): Precommit fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-22 00:35:28 +03:00
Me No Dev
4c51968acf
Merge branch 'master' into release/v3.3.x 2025-07-21 15:49:41 +03:00
Me No Dev
4a3c6d7fbb
feat(netif): Allow setting interface's routing priority (#11617)
* feat(netif): Allow setting interface's routing priority

* feat(netif): Rename route priority method names and add notes

* feat(netif): Print route prio for each interface
2025-07-21 15:49:15 +03:00
Me No Dev
f1712943b4
fix(ppp): Detach PPP RST pin from periman on end (#11620) 2025-07-21 15:48:05 +03:00
Jan Procházka
995e603d3a
fix(zigbee): Replace assert with error log to solve immediate crash (#11614)
* fix(zigbee): Replace assert with error log to solve immediate crash

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-21 15:47:43 +03:00
Jan Procházka
cb3329be60
feat(zigbee): Add callback option for default response message (#11613)
* feat(zigbee): Add cb option for default response message

* fix(example): Add timeout and fix spelling

* feat(zigbee): Add global default response cb option

* fix(example): Use task for measure and sleep

* fix(zigbee): Remove debug logs

* ci(pre-commit): Apply automatic fixes

* fix(example): Add retry and fix typo

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-21 15:47:21 +03:00
Paula Scharf
349b11d2d8 feat(board): name tag lowercase 2025-07-20 23:00:05 +02:00
Paula Scharf
28e9076601 feat(board): build name uppercase 2025-07-20 22:53:35 +02:00
Paula Scharf
cf0a58908d feat(board): remove APOTA 2025-07-19 15:14:07 +02:00
Paula Scharf
439bbb8391 feat(board): use additional button for APOTA 2025-07-19 15:14:07 +02:00
Paula Scharf
cdf606af5f feat(board): updated tinyuf2 bins 2025-07-19 15:14:07 +02:00
Paula Scharf
f330585717 feat(board): update PID 2025-07-19 15:14:07 +02:00
Paula Scharf
76210797ed fix(board): add APOTA to senseBox Eye 2025-07-19 15:14:07 +02:00
Paula Scharf
6a33f0bfc1 fix(board): add APOTA description comments 2025-07-19 15:14:07 +02:00
Paula Scharf
9641de1b12 feat(board): add senseBox Eye board 2025-07-19 15:13:06 +02:00
Sugar Glider
3ad17de6aa
fix(build): make core compatible with IDF 5.3 (#11607)
* fix(uart): make it compatible with IDF 5.3

* fix(ci): Fix artifact names

* fix(build): Fix ESP_NOW and WiFi for IDF 5.3

* fix(build): Fix NetworkClient for IDF 5.3

* fix(build): Fix WiFi for IDF 5.3

* fix(build): Fix WiFi Captive Portal for IDF 5.3

---------

Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>
Co-authored-by: me-no-dev <hristo@espressif.com>
2025-07-18 19:02:55 +03:00
Lucas Saavedra Vaz
211a0ce143
fix(ci): Fix artifact names 2025-07-18 09:15:48 -03:00
me-no-dev
000336bad0 fix(build): Enable I2C FIFO mode only on IDF 5.4.2+ 2025-07-18 11:25:36 +03:00
me-no-dev
530c1a43fe fix(build): Enable I2C FIFO mode only on IDF 5.4.2+ 2025-07-18 11:19:50 +03:00
me-no-dev
346e7f4138 fix(build): Enable I2C FIFO mode only on IDF 5.5+ 2025-07-18 11:18:13 +03:00
me-no-dev
6cb5184487 fix(build): Fix build for IDF 5.3.3+ and older releases 2025-07-18 11:12:22 +03:00
me-no-dev
98d309f84a feat(ci): Enable builds on IDF 5.3, 5.4 and 5.5 2025-07-18 10:44:01 +03:00
me-no-dev
a69c71f6ad feat(core): Update core version to 3.3.0 2025-07-16 19:55:53 +03:00
Me No Dev
5ccd9523d6
Merge branch 'master' into release/v3.3.x 2025-07-16 19:53:58 +03:00
Sugar Glider
6015fd73e0
feat(openthread): native API extension (#11598)
* feat(openthread): native API extension

* fix(openthread): wrong return type and parameter

* fix(openthread): wrong field reference

* fix(openthread): CR/LF fix

* feat(openthread): print leader RLOC information

* feat(openthread): code improvements

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-16 19:53:36 +03:00
pre-commit-ci-lite[bot]
ac05f18720
ci(pre-commit): Apply automatic fixes 2025-07-16 12:12:43 +00:00
Sugar Glider
3f32903125
Merge branch 'master' into release/v3.3.x 2025-07-16 09:10:59 -03:00
Me No Dev
ce7ef9c2ba
IDF release/v5.5 cf8dad07 (#11601)
IDF release/v5.5 cf8dad07
2025-07-16 13:42:07 +03:00
Sugar Glider
82d56bc679
feat(gpio): new functional interrupt lambda example (#11589)
* feat(gpio): new functional interrupt lambda example

* fix(readme): schematic diagram allignment

* fix(example): uses volatile for ISR variables

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(example): uses volatile for ISR variables

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(example): uses volatile data type also for the pointers

* fix(readme): clear documentation

* feat(example): improves ISR execution time

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat(gpio): simplifies the example and documentation

* feat(gpio): uses IRAM lambda and fixes volatile operation

* fix(doc): fixing documentation apresentation

* ci(pre-commit): Apply automatic fixes

* fix(ci): Update README.md

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-07-16 11:51:31 +03:00
Lucas Saavedra Vaz
1f0d4b5dc0
ci(gitlab): Initial GitLab setup (#11577)
* ci(gitlab): Initial GitLab setup

* fix(version): Add to version update script

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-14 19:17:56 +03:00
Sugar Glider
0a45a06142
feat(wire): std::functional Wire slave callback functions (#11582)
This PR enhances the Wire library to support std::function–based callbacks for I2C slave mode, enabling the use of lambdas and captured contexts.

- Replaces raw function pointers in TwoWire and HardwareI2C with std::function for onRequest and onReceive
- Updates constructors, method signatures, and default initializations to use std::function
- Adds new example sketch, CI config, and documentation updates demonstrating the functional callback API
2025-07-12 02:12:36 -03:00
Sugar Glider
c6a3bcb014
feat(matter): removing wifi requirement for H2 and C5 (#11581)
This PR removes WiFi provisioning support from CI and examples (shifting to Thread/BLE provisioning), updates the CI configs for all Matter examples to drop the WiFi requirement, and adds new API keywords and a fresh “LambdaSingleCallbackManyEPs” example.

- Deleted the WiFiProvWithinMatter example (its .ino and ci.json) since BLE is now used for provisioning.
- Stripped "CONFIG_SOC_WIFI_SUPPORTED=y" from the CI JSON of existing examples to test Thread-only builds.
- Updated keywords.txt with new Matter API identifiers and introduced a new “LambdaSingleCallbackManyEPs” example with CI and source
2025-07-12 00:11:41 -03:00
Sugar Glider
4ee17dea04
feat(matter): new matter lambda function example (#11561)
Adds a new Matter Library example using lambda function to creat 6 endpoints using a single callback
2025-07-11 11:25:27 -03:00
Me No Dev
fbf3c11daa
Merge branch 'master' into release/v3.3.x 2025-07-09 14:06:56 +03:00
Lucas Saavedra Vaz
87b718a59c
fix(merge): Fix merging CN Json (#11574) 2025-07-09 13:25:16 +03:00
Lucas Saavedra Vaz
ee021855a1
feat(docs_version): Update docs in update-version script (#11564)
* feat(docs_version): Update docs in update-version script

* fix(logging): Fix log message

* fix(idf_version): Add error if IDF version is not found
2025-07-09 13:24:42 +03:00
Me No Dev
df3db3c9dc
Merge branch 'master' into release/v3.3.x 2025-07-08 17:59:48 +03:00
Lucas Saavedra Vaz
ccc0a69ef8
change(esptool): Upgrade esptool to release v5.0.0 (#11563) 2025-07-08 17:58:36 +03:00
Lucas Saavedra Vaz
6a5839acb2
change(esptool): Upgrade esptool to release v5.0.0 (#11562) 2025-07-08 17:56:23 +03:00
Me No Dev
2cb6fbccdb
Add access methods to get the Wire bus number and I2C bus handle (#11570)
* feat(i2c): Add method to access the I2C bus handle

* feat(wire): Add access method to get the I2C bus number

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-08 16:18:42 +03:00
Me No Dev
241e2576be
fix(async): Update IP setup in AsyncUDP (#11569)
* fix(async): Update IP setup in AsyncUDP

* fix(udp): Revert to IP_SET_TYPE_VAL in connect
2025-07-08 16:00:51 +03:00
Lucas Saavedra Vaz
040e0ca42a
fix(dangerjs): Disable target branch rule (#11565) 2025-07-08 13:09:59 +03:00
Jan Procházka
e2c7578fa8
feat(zigbee): Add Fan Control endpoint support (#11559)
* feat(zigbee): Add Fan Control endpoint support

* fix(zigbee): Update logs and change device_id

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-08 13:08:56 +03:00
Jason2866
b709a78283
fix deprecated warnings caaused from esptool v5.0.0 (#11556) 2025-07-07 13:01:50 +03:00
Daniel.Cao
d3c5a82eed
fix(board): Update PSRAM configuration for RAK3112 to fix PSRAM error (#11552)
* fix(board): Update PSRAM configuration for RAK3112 to fix PSRAM error

* feat(board): RAK3112 add WisBlock module pin definitions to pins_arduino.h

* fix(board): Update RAK3112 flash mode and boot settings for improved performance

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Daniel.Cao <daniel.cao@rakwireless.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-07 11:56:44 +03:00
Me No Dev
1426927c83
fix(matter): Fix MatterSmartButon.ino when CHIPOBLE is on 2025-07-04 18:37:56 +03:00
Me No Dev
f84fab5592
Merge branch 'master' into release/v3.3.x 2025-07-04 17:14:12 +03:00
Me No Dev
aab542d658
Update Issue-report.yml to add v 3.2.1 2025-07-03 23:14:53 +03:00
Dogus Cendek
0b9c9362de
Add Deneyap Kart v2 (#11545)
* Updated Pins of Devkits

Deleted soc_caps.h library and related commands at Deneyap Kart 1A v2, Deneyap Kart 1A, Deneyap Mini and Deneyap Mini v2.
Added TX1 and RX1 pins and updated LED pin definition at all Devkits.
Added BOOT (BT) pins at Deneyap Kart, Deneyap Kart 1A, Deneyap Mini and Deneyap Kart G.
Changed D0 and D1 pin numbers at Deneyap Kart G.
Changed D12, D13, D14, D15, PWM0 and PWM1 pin numbers at Deneyap Kart 1A v2.
Added A8, T0, T1, T2, T3, T4, T5, T6, T7, T8, D16, D17, D18, D19, PWM2, PWM3, PWM4 and BAT pin numbers at Deneyap Kart 1A v2.
Changed A2, A3, A4 (T0) and A5 (T1) pin numbers at Deneyap Kart and Deneyap Kart 1A.
Renamed DA2 (DAC2) pin as DA0 (DAC0) and changed DAC1 and DAC2 pin numbers at Deneyap Mini and Deneyap Mini v2.

* Updated board.txt of all Devkits

Updated board.txt of all Devkits

* Remove Repeating Pin Definition

Remove Repeating Pin Definition

* Fix Pin Definition

Remove repeating pin definitions of SPI, I2C and DAC.
Update RGB LED definition for using digitalWrite() command with RGB LED.

* Remove Repeating Pin Definitions

Remove repeating pin definitions of LEDB, SPI, I2C and DAC.

* Update RGB LED definition

Update RGB LED definition for using digitalWrite() command with RGB LED.

* Fix broken links for external library test

Fix broken links for external library test

* Update UploadMode Config of Deneyap Kart 1A v2

Update UploadMode Config of Deneyap Kart 1A v2

* Add Deneyap Kart v2

Add pin definitions and configs of Deneyap Kart v2.

* Update UploadMode config

Hardware CDC is default now.

* Fixed typo fault

Fixed typo fault

* Fixed build.board parameter

Fixed build.board parameter

* Removed unsupported Flash sizes and RAM type

Removed unsupported Flash sizes and RAM type from menu.

* Remove unsupported partition options

Remove unsupported partition options

* Fixed Annotations and Space

* Update pins_arduino.h
2025-07-03 23:13:42 +03:00
me-no-dev
ac961f671a Update core version to 3.2.1 2025-07-03 16:42:28 +03:00
Jan Procházka
18f647611b
fix(spi): Fix bus clock for ESP32-P4 + remove S2 leftover (#11547)
* fix(spi): Fix bus clock for ESP32-P4

* fix(ci): Ignore unused-variable warning

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-03 16:39:46 +03:00
Sugar Glider
c2d23258f1
feat(matter): enables BLE Matter commissioning with NimBLE (#11537)
* feat(matter): enables BLE Matter commissioning with NimBLE

* fix(matter): commentary typo and formatting

* fix(matter): commentary typo and formatting

* fix(matter): removes forcing second network clustter

* fix(matter): adds matter source code to CMakeLists.txt

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-03 12:25:51 +03:00
Me No Dev
d4e5c5f969
IDF release/v5.5 adb3f2a5 (#11543)
IDF release/v5.5 adb3f2a5
2025-07-03 12:25:33 +03:00
Me No Dev
70696df2d6
Merge branch 'master' into release/v3.3.x 2025-07-03 12:25:04 +03:00
Paula Scharf
12e881b6d6
fix(board): Update variant.cpp for senseBox MCU-S2 ESP32-S2 (#11532)
* fix(board): Update variant.cpp for senseBox MCU-S2 ESP32-S2

* fix(board):  translate comments

* ci(pre-commit): Apply automatic fixes

* fix(board): translate comments

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-02 22:22:20 +03:00
Paul Price
33c8438263
Add FED4 board (#11536)
* Added Fed 4 board

* fixed boards.txt

* fixed board.txt again

* added usb pid address

* fixed typo: updated name to upper case

* fix(fed4): update PID and change partition scheme to default_16MB

* fix(fed4): remove unused OPI flash mode configurations

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-02 15:48:40 +03:00
John
6474127dd4
Update ZigbeeColorDimmableLight to clamp color hue and saturation to 0-254 (Fixes #11527) (#11528)
* Clamp Zigbee color saturation to 0-254

* Clamp hue to 0-254 for Zigbee color lights

* Use std::min instead of ternary operator

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-02 15:48:03 +03:00
Daniel.Cao
7f75e445f7
feat(board): add support for RAKwireless RAK3112 (#11485)
* feat(rak3112): add pins_arduino.h for RAKWireless RAK3112 module

* feat(rak3112): update pins_arduino.h to define LED pins and update board.txt

* Delete the redundant configuration information in board.txt

* Restore the incorrect modifications to board.txt

* Delete blank lines

* Move the rak configuration information to the end of the boards.txt .

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Daniel.Cao <daniel.cao@rakwireless.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-07-02 15:23:01 +03:00
HighDoping
bc7a549876
fix(example): led flash not working if not using default model in camera example. (#11466)
* fix(example): led flash not working if not using default model in camera example

fix(example): add camera_config.h and enable LED FLASH based on board model

fix(example): Remove face detection description as no longer supported

* fix(example): add header guard for board_config.h
2025-07-02 14:54:12 +03:00
Me No Dev
212b12b625
IDF release/v5.4 (#11517)
* IDF release/v5.4 dfa785ed

* IDF release/v5.4 72775cd6

* IDF release/v5.4 858a988d
2025-07-02 14:41:39 +03:00
Me No Dev
f4fdecc60c
fix(csrf): Fix SCRF vulnerability in OTA examples and libraries (#11530)
* fix(csrf): Fix SCRF vulnerability in WebUpdate.ino

* fix(csrf): Prevent CSRF on other OTA examples

* fix(csrf): Require auth user and pass to be changed

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-07-02 14:41:06 +03:00
Jason2866
8cf0818d82
make adresses for partitions.bin and boot_app0.bin configureable (#11534) 2025-07-02 14:17:00 +03:00
Me No Dev
2592a7b3bb
feat(p4): Add method to set the pins for SDIO to WiFi chip (#11513)
* feat(p4): Add method to set the pins for SDIO to WiFi chip

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-30 16:03:38 +03:00
LusimiCollado
6e60f2f6b9
feat(variant): add kode dot ESP32-S3 board with QSPI LCD, SD and GPIO … (#11371)
* feat(variant): add KodeDot ESP32-S3 board with QSPI LCD, SD and GPIO header

* fix(kodedot): Reorder board definitions and translate comments to English

* fix(kodedot): Clean up OTA override and remove unused partition menu for kode dot

* fix(kodedot): Build board changed from ESP32S3_DEV to KODE_DOT on kode dot board

* ci(pre-commit): Fix whitespace, EOLs and codespell 'Analog'

* ci(pre-commit): Add bash script formatter

* fix(merge): New name and description for custom merge tool and change partitions table to variants folder
2025-06-30 13:18:02 +03:00
Mattias Schäffersmann
6476260e8f
fix(esp32): Fix appending to Strings longer than 64k (#11523)
If oldLen is truncated to uint16_t, appending to a String
that is longer than 65535 bytes will create a broken string.
2025-06-30 13:04:11 +03:00
Lucas Saavedra Vaz
6754b1962c
feat(esp_now): Add support for ESP NOW V2 (#11524)
* feat(esp_now): Add support for ESP NOW V2

* fix(esp_now): Return -1 on error
2025-06-30 12:02:12 +03:00
Kuba Andrýsek
9a35d9455f
feat(SDFS): Add destructor for SD card to clean up resources (#11521)
* feat(test): Enhance NVS test

* fix(nvs): Remove unused Unity header and improve Serial wait loop

* refactor(nvs): Extract string increment logic into a separate function

* refactor(test): Format long strings in expect_exact calls for better readability

* feat(SDFS): Add destructor to clean up resources
2025-06-30 11:50:49 +03:00
Lucas Saavedra Vaz
875b923035
ci(ext_lib): Skip P4 in ArduinoBLE test (#11520) 2025-06-30 11:50:17 +03:00
Lucas Saavedra Vaz
ff3cc813fc
Merge branch 'master' into release/v3.3.x 2025-06-26 13:17:18 +03:00
Lucas Saavedra Vaz
21640ac82a
fix(webserver): Validate header inputs 2025-06-26 12:43:50 +03:00
Me No Dev
5871a80616
Merge branch 'master' into release/v3.3.x 2025-06-24 17:26:45 +03:00
Me No Dev
9e61fa7e4b
IDF release/v5.4 (#11512)
* IDF release/v5.4 f0f2980d

* fix(p4): Allow custom pins on P4 for ESP-Hosted
2025-06-24 17:23:50 +03:00
Jan Procházka
0213200b3d ci(sizes): Use commit id in report-size-delta action 2025-06-24 14:40:53 +02:00
Jan Procházka
e9b0930f9d ci(sizes): Update sizes workflow action 2025-06-24 14:34:17 +02:00
Lucas Saavedra Vaz
30fb3cbb4f
fix(docs): Fix links and versions (#11505)
* fix(docs): Fix links and versions

* fix(docs): Apply suggestions and leftover substitutions
2025-06-24 14:43:27 +03:00
Jan Procházka
b7e5169ea1
fix(spi): Update spi bus for esp32s2 (#11510) 2025-06-24 14:43:05 +03:00
me-no-dev
882ef25a36 fix(p4): Update hosted and wifi_remote components 2025-06-24 12:35:18 +03:00
Me No Dev
36d049659b
IDF release/v5.5 (#11504)
* IDF release/v5.5 4c3d086c

* fix(prov): Enable BLE provisioning with NimBLE

* fix(uart): idf 5.5 new gpio_iomux_* functions (#11507)

* fix(uart): idf 5.5 new gpio_iomux_* functions

* fix(uart): formatting and style

* fix(uart): commentaries style fix

* fix(uart): commentaries style fix

* fix(uart): commentaries style fix

* fix(uart): support to any idf 5.x version

* fix(uart): changing assert in order to avoid reset

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>

* IDF release/v5.5 cbe9388f

---------

Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-24 12:30:29 +03:00
Sugar Glider
bad975daa5
fix(uart): removes assert() to avoid reset (#11508) 2025-06-24 09:37:07 +03:00
Kuba Andrýsek
95ae8cf9c6
feat(test): Enhance NVS test (#11481)
* feat(test): Enhance NVS test

* fix(nvs): Remove unused Unity header and improve Serial wait loop

* refactor(nvs): Extract string increment logic into a separate function

* refactor(test): Format long strings in expect_exact calls for better readability
2025-06-23 15:02:47 +03:00
Me No Dev
18c909a8fd
Merge branch 'master' into release/v3.3.x 2025-06-23 14:49:32 +03:00
Lucas Saavedra Vaz
dc82467ba4
fix(esp_now): Fix broadcast example and use nullptr (#11490)
* fix(esp_now): Fix example and use nullptr

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-23 14:48:37 +03:00
Lucas Saavedra Vaz
1c79eb823c
feat(NimBLE): Add support for NimBLE (#11424)
* feat(NimBLE): Add support for NimBLE

Co-authored-by: h2zero <ryan@nable-embedded.io>

* ci(pre-commit): Apply automatic fixes

* fix(nimble): Fix typo in BLEClient

---------

Co-authored-by: h2zero <ryan@nable-embedded.io>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-23 14:47:49 +03:00
me-no-dev
febca6b2f1 fix(p4): Update hosted and wifi_remote components 2025-06-23 12:11:32 +03:00
Me No Dev
29035dc689
Merge branch 'master' into release/v3.3.x 2025-06-22 21:04:01 +03:00
Sugar Glider
9d84c78cf2
feat(uart): fixes pin attach for any IDF 5.x (#11499)
* feat(uart): fixes pin attach for any IDF 5.x

* fix(uart): commentary typo error

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(uart): commentary typo error

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(uart): commentary typo error

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(uart): commentary style fix

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-22 21:02:36 +03:00
Me No Dev
bf55924b67
Merge branch 'master' into release/v3.3.x 2025-06-21 15:46:46 +03:00
Sugar Glider
01e4d5debb
feat(uart): fixes loopback function after IDF changes (#11492)
* feat(uart): fixes loopback function after IDF changes

IDF 5.4.1 has added a new function called uart_release_pin() that is called whenever new pins are set or when uart driver is deleted.

This has a side effect that causes RX pin to never work again with the loopback function. Other changes also have removed some GPIO setup that was necessary for the GPIO loopback mode work.

The PR forces a full RX Pin setup in order to make it work in GPIO Matrix with Loopback TX Signal

* feat(uart): adds missing include file

* feat(uart): removes not necessary part of the code

* fix(uart): commentaries style fix

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-21 15:45:26 +03:00
Sugar Glider
ccda9c5f84
feat(matter): Adds Matter Events callback plus example (#11465)
* feat(matter): Adds Matter Events callback and related example
2025-06-20 15:28:07 -03:00
Olaf
23c6abc1ac
Proper EDNS handling and cleaner NOERROR response in DNSSERVER (#11411)
* Proper EDNS handling and cleaner NOERROR response

* fix:  library.properties

reverting version number update - as it is done automatically

* ci(pre-commit): Apply automatic fixes

* Spelling Corrected  and minor clarification in comments

* Removing commented out code fragments

* ci(pre-commit): Apply automatic fixes

* fix(pr): Fix typo

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-06-20 12:52:21 +03:00
Me No Dev
05fbda2d6d
Merge branch 'master' into release/v3.3.x 2025-06-20 12:25:31 +03:00
Jason2866
016077e245
changes for updated esptool.py v5 (#11488) 2025-06-20 12:25:03 +03:00
Lucas Saavedra Vaz
02be6e8826
feat(esptool): Upgrade to esptool v5 (#11487) 2025-06-20 12:23:18 +03:00
Wulu
51f1367d57
fix(docs): correct code block indentation in core_compatibility.rst (#11471)
* fix(docs): correct code block indentation in core compatibility guide

* fix(docs): remove extra colon causing rendering error in core_compatibility.rst
2025-06-20 12:22:01 +03:00
Ludovic BOUÉ
f7889116b1
feat(openthread): Add RLOC16 in otPrintNetworkInformation() (#11480)
* feat(openthread): Add RLOC16 in otPrintNetworkInformation()
2025-06-18 14:55:11 -03:00
Jan Procházka
6d4886cd1f
feat(spi): Add return values to SPI begin (#11477) 2025-06-17 16:23:35 +03:00
is-qian
4bc5ffc88d
fix: Delete 8M flash option for xiao_esp32_s3_plus. (#11476) 2025-06-17 13:39:33 +03:00
Jan Procházka
7462b09bb4
feat(LEDC): Add Gamma Fade support and enhance auto channel/timer selection for multi-group (#11464)
* feat(ledc): Enhance LEDC auto channel/timer selection for multi-group support

* feat(ledc): Add Gamma Fade support

* fix(example): Update comments

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-16 14:44:11 +03:00
Sugar Glider
ef995b6564
feat(openthread): adds native api (#11474)
* feat(openthread): adds native api

* feat(openthread): adds source code to CMakeLists.txt

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-16 13:15:54 +03:00
SooDragon
228393708d
fix: Update Pin compatability (#11473)
fix: Update Pin compatability
2025-06-16 11:12:33 +03:00
Me No Dev
0f72681fa0
Merge branch 'master' into release/v3.3.x 2025-06-10 14:30:19 +03:00
Paula Scharf
422e52684b
fix(msc): remove weak function declaration of tud_msc_is_writable_cb (#11353)
Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>
2025-06-10 14:29:27 +03:00
Me No Dev
aaeabb5b87
Merge branch 'master' into release/v3.3.x 2025-06-10 13:28:31 +03:00
whatsABetterNick
d71135e2ca
Fix(I2S example): make fix to the ESP32 I2S simple tone example (#10954)
* made some fix to the ESP32 I2S simple tone example

* edit the I2S - simple tone example

* edit the I2S - simple tone example

* some edit

* edit comment

* edit

* edit

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-10 13:27:47 +03:00
Lucas Saavedra Vaz
c21ef70a15
fix(release): Replace all assets with chinese mirrors (#11323)
* fix(release): Replace all assets with chinese mirrors

* feat(release): Add script to append "-cn" to versions

* docs(install): Add instructions for users in China
2025-06-10 13:09:27 +03:00
Jan Procházka
cbdaee6f52
feat(ledc): Improve timer management with frequency/resolution matching (#11452)
* feat(ledc): Improve timer management with frequency/resolution matching

* fix(ci): Fix uninitialized timer variable warning

* Update cores/esp32/esp32-hal-ledc.c

Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-10 12:57:07 +03:00
Niki Waibel
d6a76da0a5
fix(libraries/asyncudp): IPv4 ONLY listenMulticast() (#11444)
AsyncUDP::listenMulticast() properly receives packets sent to IPv4
multicast addresses like 239.1.2.3, but it is not receiving packets sent
to IPv6 multicast addresses like ff12::6ood:cafe.

The root cause is a bit hidden: listen(NULL, port) would match
AsyncUDP::listen(const ip_addr_t *addr, uint16_t port), which calls
_udp_bind(_pcb, addr, port), which uses the lwIP API to call
udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) at
the end. If lwIP has LWIP_IPV4 enabled, it checks if ipaddr == NULL and
sets it to IP4_ADDR_ANY. So an IPv6 address is never bound.

This fix checks the IP address passed to AsyncUDP::listenMulticast(). If
it is an IPv6 address, it constructs and passes the IPv6 any address
(::); otherwise (IPv4), it constructs and passes the IPv4 any address
(0.0.0.0).
2025-06-10 11:55:43 +03:00
Jan Procházka
0aada091e1
feat(zigbee): Support min/max setting for Analog EP (#11451)
* feat(zigbee): Support min max for Analog EP

* feat(zigbee): Use cfloat FLT_MAX

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-10 11:31:17 +03:00
Lucas Saavedra Vaz
89ff465328
feat(esptool): Upgrade to esptool v5 (#11433)
* feat(esptool): Upgrade to esptool v5

* fix(script): Update script for better handling of esptool

* fix(script): Get proper download url

* fix(script): Apply copilot suggestions
2025-06-10 11:19:32 +03:00
Me No Dev
0007815a11
feat(p4): Add 32MB Flash Partitions to ESP32-P4 (#11453)
* feat(p4): Add 32MB Flash Partitions to ESP32-P4

* feat(p4): Add 32MB flash size option

---------

Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
2025-06-10 11:00:20 +03:00
Jan Procházka
af47bd3008
fix(ci): Process only needed files in publish sizes (#11439) 2025-06-10 10:59:56 +03:00
i3water
ee347baa7d
feat(boards): update wifiduinov2&wifiduino32s3 boards setting (#11440)
* update wifiduinov2&wifiduino32s3 boards setting

* fix wifiduinov2&wifiduino32s3 build board error.

* fix wifiduinov2(esp32c3) board setting

* fix wifiduinov2(esp32c3) cdc on boot default setting.

* fix wifiduino32s3 spi pin set

* change wifiduino32s3 spi pin to spi1

* remove 32Mb flash size

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-10 10:29:46 +03:00
Jason2866
610d951f9d
include "esp_bt.h" only when existing (#11438) 2025-06-10 10:29:29 +03:00
SooD
1bac8de384
fix: Updated the tools options for Geekble Mini (#11437)
fix: Updated the tools options for Geekble Mini
2025-06-10 10:29:11 +03:00
Me No Dev
e9813c6a52
Merge branch 'master' into release/v3.3.x 2025-06-04 19:12:52 +03:00
SooD
31d22e6ed0
fix: change geekble nano board setting (#11432)
add PSRAM Setting
2025-06-04 18:49:09 +03:00
Jan Procházka
0ab9a0fe6f
feat(zigbee): Update to esp-zigbee-sdk 1.6.5 and fix ci.json files (#11436)
* feat(zigbee): Update esp-zigbee-sdk and fix ci.json files

* fix(ci): Check if LED_BUILTIN exist

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-04 18:48:48 +03:00
Jan Procházka
e3018b6719
feat(zigbee): Add method to set/get/report analog output (#11431)
* feat(zigbee): Add methot to set,get,report analog output

* fix(ci): Update json file for example

* fix(zigbee): Add missing keywords

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-04 17:40:52 +03:00
Jan Procházka
cae66e65a3
feat(zigbee): Add endpoint identification in read handlers + command structures fix (#11425)
* feat(zigbee): Add endpoint identification in read handlers

* fix(zigbee): initialize Zigbee command structures with zeros

* fix(zigbee): Spelling correction

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-04 17:40:28 +03:00
Jason2866
375f2c002d
C2: Disable network provisioning (#11423) 2025-06-04 17:40:12 +03:00
Jason2866
460b89201b
make BT core code execution conditional from include esp_bt.h (#11413)
* make code execution conditional from include esp_bt.h.h

* only one if

* Update esp32-hal-bt.c
2025-06-04 17:39:54 +03:00
Me No Dev
a2880a4c17
feat(ap): Add support for DHCP Captive Portal (opt 114) (#11412)
* feat(ap): Add support for DHCP Captive Portal (opt 114)

* feat(ap): No need to guard the function

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-06-04 17:39:34 +03:00
Kevin Sidwar
b5c5655cf0
Support HTTP 204 (#11408)
HTTP 204 is a successful return code which indicates No Content. While it's appropriate to return a 304 if the server has content for a device but it hasn't change, it is more accurate for a server to return a 204 if it simply doesn't have any firmware files for a particular device.

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-06-04 17:39:19 +03:00
Lucas Saavedra Vaz
6f56df2a09
feat(codeowners): Initial CODEOWNERS setup (#11397)
* feat(codeowners): Initial CODEOWNERS setup

* fix(comment): Improve comment

* fix(codeowners): Add teams

* fix(codeowners): Apply suggestions

* fix(codeowners): Add missing libraries
2025-06-04 16:19:44 +03:00
me-no-dev
a6bba43d32 fix(c5): Enable components for ESP32-C5 2025-05-30 19:12:34 +03:00
Me No Dev
6ce7e254c4
IDF release/v5.5 (#11369)
* IDF release/v5.5 719b1b2b

* fix(build): Add dependency on esp_http_client

* fix(build): Add dependency on esp_https_ota

* IDF release/v5.5 28ac0243
2025-05-30 17:18:32 +03:00
Me No Dev
b7698461ac
Merge branch 'master' into release/v3.3.x 2025-05-30 15:54:01 +03:00
Me No Dev
f3ae2a65e2
IDF release/v5.4 (#11406)
* fix(build): Update APB frequency set routine

* IDF release/v5.4 aed8bdc8
2025-05-30 15:18:57 +03:00
Me No Dev
72a582b908
feat(ssl): Do not check if client is connected if already disconnected (#11356) 2025-05-27 16:51:23 +03:00
Me No Dev
15038e64b3
Merge branch 'master' into release/v3.3.x 2025-05-27 13:34:03 +02:00
Jan Procházka
91fd517cf1
feat(zigbee): Check the type of leave signal (#11385)
* feat(zigbee): Check the type of leave signal

* Update libraries/Zigbee/src/ZigbeeCore.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update libraries/Zigbee/src/ZigbeeCore.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-05-27 14:33:30 +03:00
Thomas J.
31bfcb27ce
add board yb_esp32s3_drv (#11388) 2025-05-27 14:16:37 +03:00
Lucas Saavedra Vaz
fa275971cd
Update gen_esp32part.py (#11391)
* Update gen_esp32part.py

* change(tools): Push generated binaries to PR

* fix(formatting): Apply formatter

* change(tools): Push generated binaries to PR

* fix(gen_esp32part): Remove unnecessary generator

* change(tools): Push generated binaries to PR

* fix flake8 (#11393)

---------

Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-27 14:16:13 +03:00
Jacob Williams
d960f61e0a
fix(board): Alfredo-NoU3 changed default upload mode from Hardware CDC and JTAG to USB-OTG (#11403)
* fix(board): Alfredo-NoU3 changed default upload mode from Hardware CDC and JTAG to USB-OTG

* feat(board): Add Alfredo NoU2

* Revert "feat(board): Add Alfredo NoU2"

This reverts commit 35ba26acd9da17477f3ee14a1e3f63fd11df5f8d.
2025-05-27 14:15:54 +03:00
Jan Procházka
7bafc1b19b
feat(zigbee): Add AC DC ElectricalMeasurement support (#11384)
* feat(zigbee): Add AC DC ElectricalMeasurement support

* ci(pre-commit): Apply automatic fixes

* ci(): fix precommit codespell

* ci(pre-commit): Add spaces between numbers and units

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-05-27 14:10:18 +03:00
Jan Procházka
6c3528ac69
feat(zigbee): Add support for Binary input EP + Analog EP extension (#11339)
* feat(zigbee): Add binary input and analog extension

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat(zigbee): Remove setBinaryInputReporting

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-05-27 13:41:38 +03:00
Vlastimil Hajek
07d662a7fc
fix: crash on watchdog timeout on iddle task (#11376) 2025-05-27 13:15:41 +03:00
Jan Procházka
542274d5ea
feat(zigbee): Remove static variables, improve binding, new example (#11316)
* feat(zigbee): Remove static variables, improve binding, new example

* feat(example): Add missing header

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-05-27 13:13:47 +03:00
Ludovic BOUÉ
9090b46da5
feat(esp32): Zigbee power outlet example (#11296)
* feat(esp32): Zigbee power outlet example

Zigbee power outlet example

* feat(esp32): Zigbee power outlet example

Change username

* feat(esp32): Zigbee power outlet example

Remove old comment

* fix(zigbee): fix power outlet compile errors and update example

* fix(example): Update readme

* fix(example): Update ci json file

* ci(pre-commit): Apply automatic fixes

* fix(): precommit codespell

---------

Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-05-27 13:13:28 +03:00
qhddz
d85b75c219
add dfrobot lorawan esp32s3 board (#11362)
* add dfrobot_lorawan_esp32s3 board

* Update pins_arduino.h

* Update pins_arduino.h

remove duplicate macro definitions

* Update pins_arduino.h

* update board.txt

* add other menu items

* delete OPI Flash

* Update pins_arduino.h

* Update pins_arduino.h
2025-05-22 18:31:31 +02:00
me-no-dev
3f63a4929f fix(build): Add dependency on esp_http_client 2025-05-19 13:54:12 +02:00
Jan Procházka
13cd0d3c3f
fix(rainmaker): Fix the 8MB partition scheme (#11363) 2025-05-15 11:14:58 +02:00
me-no-dev
5540afa1ea feat(ci): Run push CI against IDF v5.5 2025-05-15 11:13:32 +02:00
Me No Dev
d69ad5e747
Merge branch 'master' into release/v3.3.x 2025-05-15 11:10:58 +02:00
Me No Dev
69cd5a0a66
IDF master 7cf5dacd (#11358) 2025-05-15 11:10:00 +02:00
Me No Dev
8d5a026c98
IDF release/v5.4 (#11357)
* IDF release/v5.4 8ad0d3d8

* IDF release/v5.4 fd37cd46

* IDF release/v5.4 fe753553
2025-05-15 10:56:48 +02:00
Jason2866
bc08c49579
Update version for wifi remote (#11344) 2025-05-13 12:25:39 +02:00
Me No Dev
a83bb93b6d
Merge branch 'master' into release/v3.3.x 2025-05-13 11:49:03 +02:00
Me No Dev
6f92b604f6
IDF release/v5.4 (#11212)
* fix(i2c): update i2c_ll_slave_init for IDF 5.4

* IDF release/v5.4 8ad0d3d8
2025-05-13 11:46:58 +02:00
Unexpected Maker
210edfeaa6
Added new Unexpected Maker SQUiXL and EDGES3[D] boards. (#11350)
* Added new Unexpected Maker SQUiXL and EDGES3[D] boards.

Signed-off-by: Seon Rozenblum <seonr@3sprockets.com>

* Seems we are being picky about board names now ;)

Signed-off-by: Seon Rozenblum <seonr@3sprockets.com>

* Seems I have to have SPI pins defined for SQUiXL, or compiling breaks

Signed-off-by: Seon Rozenblum <seon@unexpectedmaker.com>

---------

Signed-off-by: Seon Rozenblum <seonr@3sprockets.com>
Signed-off-by: Seon Rozenblum <seon@unexpectedmaker.com>
2025-05-13 11:46:15 +02:00
Me No Dev
602f1f6e7f
IDF master (#11342)
* fix(ci): ESP32-P4 hosted compile fail (#11341)

* fix(ci): Update changes for P4 and C5 builds with latest IDF

* IDF master aaebc374

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-05-07 16:24:33 +03:00
Stian Coward
15e71a6afd
fix(esp32): Add missing vflip status in esp32-cam example (#11335)
Toggle switch for V-Flip will now indicate correct status in frontend when loading the webpage
2025-05-07 11:50:32 +03:00
Limor "Ladyada" Fried
158c7aec42
Add new board: Sparkle Motion Stick (#11330)
* add new version of sparklemotion

* updated change as requested

* fix

* fix clang complaints
2025-05-07 11:03:54 +03:00
Me No Dev
b115acea40
IDF master (#11289)
* fix(libs): Ensure compilation with ESP32-C5

* fix(i2c): Update I2C Slave init call

* IDF master 465b159c

* ci(simple_ble): Add check for BLE supported

* IDF master 38628f98

---------

Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>
2025-05-01 02:15:03 +03:00
Me No Dev
c9efce6342
Merge branch 'master' into release/v3.3.x 2025-04-29 10:55:47 +03:00
Lucas Saavedra Vaz
543fad2bdf
fix(spi): Add missing initializer for ss_invert (#11320)
* fix(spi): Add missing initializer for ss_invert

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-29 10:49:23 +03:00
Lucas Saavedra Vaz
de72a03ca5
docs(mirror): Add Chinese mirror links (#11317) 2025-04-29 10:46:44 +03:00
Sugar Glider
d63b876f93
feat(uart): simplifies UART example based on MODBUS standard (#11309)
* feat(uart): simplifies UART example based on MODBUS standard

* fix(uart): fixes a uart example typo

* feat(uart): replaces UART0 by Serial0 in the code

* ci(pre-commit): Apply automatic fixes

* fix(uart): typo error message in commentary

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-29 08:58:10 +03:00
Luca Burelli
16fcdeb0be
fix(arduino): restore proper pin remapping functionality (#11315)
Commit 0773dd7619 from PR #10841 broke pin
remapping by moving its application too early in the definition process.
This commit restores the original order of includes, ensuring that pin
remapping is applied correctly.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
2025-04-29 08:57:51 +03:00
UltimumControl
b461e01e22
New SPI invert hardware SS function in hall-spi and SPI library (#11297)
* Add files via upload

* Add files via upload

* Update SPI.h

* Update esp32-hal-spi.c

renamed invert_out to ss_invert to be more intuitive

* Update esp32-hal-spi.h

Removed the out from the function name spiSSInvertout.

* Update SPI.cpp

Removed the out from the function name spiSSInvertout.

* Update cores/esp32/esp32-hal-spi.c

Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-28 20:45:31 +03:00
microbots
9193c9db1e
Update boards.txt with updated CodeCell board variant (#11313)
* Update boards.txt

* Update boards.txt

* Update boards.txt

* Update boards.txt

---------

Co-authored-by: Carl Bugeja <carlb20@gmail.com>
2025-04-28 20:27:17 +03:00
Sugar Glider
8d121e075f
feat(rmt): fixes example to run correctly within IDF 5.x (#11292)
* feat(rmt): fixes exaple to run correctly within IDF 5.x

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-28 18:46:12 +03:00
Lewis He
5df9b64023
Update LilyGo T-Watch-S3-Ultra and T-LoRa-Pager variants (#11299)
* Update LilyGo variants

* Update T-Watch-S3-Ultra variants

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-28 18:45:54 +03:00
Lucas Saavedra Vaz
8ed97f6fa8
ci(release): Add package JSON with chinese mirrors (#11288)
* ci(release): Add package JSON with chinese mirrors

* fix(comment): Fix comment with proper description
2025-04-28 18:45:31 +03:00
Lucas Saavedra Vaz
5262f5ad5e
ci(idf): Use included IDF examples in CI (#11240)
* ci(idf): Use included IDF examples in CI

* fix(example): sets Matter version to be 1.3 or higher

* feat(matter): sets c++ 2a as default

* feat(matter): Update README.md

* fix(matter): instructions about using more than one sdkconfig file

---------

Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
2025-04-28 18:45:12 +03:00
Me No Dev
23f3600a4b
Merge branch 'master' into release/v3.3.x 2025-04-23 20:20:51 +03:00
Sugar Glider
571c2f74f2
feat(uart): sets correct ESP32/S2 clock source for the example (#11286)
* feat(uart): sets correct ESP32/S2 clock source for the example

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-23 20:20:23 +03:00
Sugar Glider
51023aea79
feat(ledc): clear all fields added to ledc struct in IDF 5.4 (#11276)
* feat(ledc): clear all fields added to ledc struct in IDF 5.4

* feat(ledc): use memset for all ledc struct

* fix(ledc): typo - missing semi collon

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-23 20:20:05 +03:00
Me No Dev
03e9c45084
IDF master (#11204)
* fix(esp-now): Update TX Callback

* IDF master d930a386

---------

Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com>
2025-04-23 15:50:58 +03:00
Me No Dev
5d0c4b3507
Merge branch 'master' into release/v3.3.x 2025-04-22 11:47:28 +03:00
Lucas Saavedra Vaz
c110ca8295
docs(language): Enforce English on contributions and issues (#11267) 2025-04-22 11:46:59 +03:00
Lucas Saavedra Vaz
a8bead7efb
fix(gpio): Fix GPIO warning message (#11268) 2025-04-22 09:16:46 +03:00
Lucas Saavedra Vaz
e0d4d176ea
ci(pre-commit): Lock versions to SHA and apply fixes (#11248)
* ci(pre-commit): Execute codespell after formatting changes

* ci(pre-commit): Lock versions to hash

* fix(pre-commit): Apply pre-commit fixes
2025-04-22 09:16:32 +03:00
Jason2866
42ae2426af
fix C5 compile (#11255) 2025-04-21 19:32:51 +03:00
Lucas Saavedra Vaz
ae2ae8dfa0
Merge branch 'master' into release/v3.3.x 2025-04-14 14:28:03 -03:00
Me No Dev
f1223663dd
fix(wifi): Workaround bug in esp_wifi_get_protocol() (#11239)
* fix(wifi): Workaround bug in esp_wifi_get_protocol()

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-14 13:54:47 +03:00
Jason2866
9cad83bacf
check for CONFIG_BT_BLUEDROID_ENABLED in esp32-hal-misc.c (#11234)
* check for `CONFIG_BT_BLUEDROID_ENABLED` in esp32-hal-misc.c

* overseen changes to `CONFIG_BT_BLUEDROID_ENABLED`
2025-04-14 12:13:55 +03:00
Mathieu Carbou
60c8206ee6
feat(logging): Arduino log redirection (#11159)
* feat(logging): Arduino log redirection

* fix(uart): log will only use ets_printf() for uart and cdc

* feat(uart_cdc): when CDC is logging, UART is silent

* feat(uart_cdc): when CDC is logging, UART is silent

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-14 12:08:33 +03:00
Sugar Glider
3fcc316d3c
fix(usb_hid): duplicated CONSUMER_CONTROL_PLAY_PAUSE (#11242) 2025-04-14 11:24:30 +03:00
Sugar Glider
bd4b32522c
feat(usb): add a few more consumer control HID commands (#11227) 2025-04-09 11:57:12 +03:00
Sugar Glider
be57376b6b
fix(usb): uninitilized variable warning message (#11222) 2025-04-09 11:56:52 +03:00
Sugar Glider
2647cbbbc2
refactor(rmt): refactored RMT loopback example (#11221)
* feat(rmt): refactored RMT loopback example

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-09 11:56:32 +03:00
Jason2866
8e8b1cbd31
Use CONFIG_BT_BLUEDROID_ENABLED for enabling (#11214)
Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
2025-04-09 11:26:13 +03:00
Jan Procházka
d3509ef98b
feat(zigbee): Add battery voltage attribute support (#11210)
* feat(zigbee): Add battery voltage attribute support

* Update libraries/Zigbee/src/ZigbeeEP.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-09 11:25:58 +03:00
Jacob Williams
7f60945018
fix(board): Alfredo NoU3 pins_arduino.h uses uint8_t but it causes error with esp32-hal-gpio.h (#11206)
* fix(board): Alfredo NoU3 include stdint.h

* fix(hal_gpio): lets pins_arduino.h to use stdint and stdbool types

* feat(pins_arduino): fixes lack of stdint in the right place

* fix(pins_arduino): reverts all changes to this file

* fix(pins_arduino): reverts all changes to this file

* fix(pins_arduino): reverts all changes back to original pr

---------

Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
2025-04-09 11:25:39 +03:00
Gonzalo Brusco
0cc8eab836
Add an option to force IDF's default UART clock source (#11191)
* Add an option to force IDF's default UART clock source

* feat(uart): adds function to set clock source

* feat(uart): add uart clock source selection method

* feat(uart): add uart hall function to set the uart clock source

* feat(uart): add function to set the uart clock source

* feat(uart): set clock source as necessary

* fix(uart): missing class qualifier declaration

* fix(uart): fixing a typo and non LP UART SoC clk src setting

* fix(uart): variable name, typo error

* fix(uart): retores previous identation reducing diff load

* feat(uart): apply CONFIG_ARDUINO_SERIAL_FORCE_IDF_DEFAULT_CLOCK_SOURCE to LP UART

* feat(uart): adds option for UART_CLK_SRC_DEFAULT

* feat(uart): adds option for setting default uart clock source from IDF

* feat(uart): documents UART_CLK_SRC_DEFAULT as option in header file

* feat(uart): documents using the IDF default uart clock source

* fix(uart): type missmatch may cause error

* fix(uart): type missmatch may cause error, test for -1

* feat(uart): considering both HP and LP default uart clock source

* feat(uart): improve the defined value for UART_CLK_SRC_DEFAULT

* fix(uart): using uart_sclk_t as hal level parameter

* feat(uart): apply default LP uart clock source

* fix(uart): considers that it may set the LP UART as well

* feat(uart): using UART SCLK enum for uart clock source values

* fix(uart): using UART_CLK_SRC_RTC now

* fix(uart): documentation using UART_CLK_SRC_RTC now

* fix(uart): fix old commentary that is not correct anymore

* fix(uart): wrong identation in code line

* fix(uart): using uart number as argument instead

* fix(uart): using uart number as argument in setClockSource()

* fix(uart): using uart number as parameter in uartSetClockSource()

* feat(uart): update Kconfig.projbuild to reflect functionality

* feat(uart): removing Kconfig.projbuild option to force default clk src

* feat(uart): removes kconfig option to force uart default clk src

* fix(uart): replacing #if #endif by #if #elif #endif for the same enum

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-09 11:25:06 +03:00
Sugar Glider
b333bf2697
fix(zigbeeEP): review of names and memory allocation (#11199)
* fix(zigbeeEP): review of names and memory allocation

* fix(zigbeeEP): destructor shall free any allocated memory

* fix(zigbee_ep): forgotten var name change

* feat(zigbee_ep): use static heap memory for manufacturer and model names

* feat(zigbee_ep): changed model and manufacturer to heap

* feat(zigbee_ep): use static heap memory allocation

* fix(zigbee_ep): using stack only for adding attribute

* feat(zigbee_ep): reverting back read data type

* fix(zigbee_ep): rooling back to use malloc for remote attr reading

* feat(zigbee_ep): check malloc return for null

* fix(zigbee_ep): replace nullptr by NULL after C malloc()

* ci(pre-commit): Apply automatic fixes

* fix(zigbee_ep): fix variable scope

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(zigbee_ep): fix variable scope

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-05 18:47:38 +03:00
Jan Procházka
23ded939ea
feat(zigbee): Add PM2.5 endpoint support (#11205)
* feat(zigbee): Add PM2.5 endpoint support

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-04-05 18:46:20 +03:00
Sugar Glider
22f07d01c8
fix(rmt): memset all config structs to zero before using (#11203)
* fix(rmt): memset all config structs to zero to increase code safety
2025-04-01 09:36:19 -03:00
Lewis He
7b0298b462
Modify T-LoRa-Pager device PID (#11194)
Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
2025-03-31 11:06:18 +03:00
Me No Dev
998bf80248
Merge branch 'master' into release/v3.3.x 2025-03-29 23:48:18 +02:00
Me No Dev
fbca62fd68
Update Issue-report.yml with the latest versions 2025-03-29 14:13:57 +02:00
Me No Dev
a61961d5c9
IDF master (#11150)
* IDF master ee77c489

* IDF master ee77c489

* IDF master 50be9735

* IDF master 23c73cdc

* IDF master a45d713b
2025-03-28 10:48:39 +02:00
Me No Dev
dac2dd907d
Merge branch 'master' into release/v3.3.x 2025-03-28 10:48:05 +02:00
Lewis He
de184bd0cb
Update LilyGo variants and add new variants (#11192)
* Update LilyGo T-Watch-S3 definition and expansion options

* Update LilyGo T-Watch-Ultra definition and expand options

* Added variant LilyGo-T-LoRa-Pager

* Update partition table order

* Update LilyGo board partition table order

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-28 10:38:31 +02:00
Me No Dev
1014937965
IDF release/v5.4 (#11149)
* IDF release/v5.4 5cbd2a38

* fix(ci): Disable RainMaker examples on ESP32

* IDF release/v5.4 5cbd2a38

* IDF release/v5.4 2f7dcd86
2025-03-28 10:37:48 +02:00
Jan Procházka
a3b6fe61ba
feat(zigbee): Add check, boolean returns, fix Analog, add optional reset on factoryReset (#11153)
* feat(zigbee): Add checks on setting attrs and commands

* feat(zigbee): Add error info in the logs

* fix(zigbee): Fix memory leak, print esp_zb_zcl_status_t error, remove analogValue from analog EP

* feat(example): Update factoryResetoption in sleepy example

* fix(zigbee): Add error checks to Illuminance EP

* fix(zigbee): Return false on first error hit

* fix(zigbee): Apply same formatting on all returns

* fix(zigbee): Add check when adding a OTA cluster

* fix(zigbee): release locks before returning

* fix(zigbee): use correct return in doorWindowHandle

* fix/zigbee): Add missing return in WindowCovering

* fix(zigbee): Added a note of future task

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-27 22:13:48 +02:00
SooDragon
bbaabb183a
fix: Geekble Nano board setup update (#11131)
* Geekble Nano board setup update

Geekble Nano board setup update

* fix: erase Comment Line

fix: erase Comment Line

* revert re-naming

revert re-naming
2025-03-27 14:52:32 +02:00
Me No Dev
d81c19534f
Merge branch 'master' into release/v3.3.x 2025-03-27 13:39:40 +02:00
Me No Dev
17258930e6
fix(wifi_scan): Fix some edge cases where WiFi Scan may fail (#11188) 2025-03-27 13:38:04 +02:00
MikaFromTheRoof
e37435c442
feat(zigbee): Add Illuminance sensor endpoint (#11171)
* Added Zigbee light sensor

* Add comment for macro

* Some last corrections

* refactor(zigbee): changed class name to ZigbeeIlluminanceSensor

* feat(zigbee): Illumanance sensor update

* fix(zigbee): Change name of macro to avoid possible conflict with esp-zigbee-sdk

* Update keywords.txt

* fix(zigbee): Add Illuminance to Cmake file

* fix(example): Update Illuminance example

* ci(pre-commit): Apply automatic fixes

* Update Zigbee_Illuminance_Sensor.ino

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-27 12:56:30 +02:00
FidelSch
86221479b7
fix: BLEAdvertising methods return error codes (#11154)
* fix: BLEAdvertising methods return error codes

Some methods returned void even if they could produce an error, in which case they failed silently. They now return the corresponding error code.

* fix: methods which could error out return bool

Changed from returning esp_error_t, in order to be more arduino compatible.

---------

Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
2025-03-27 12:35:19 +02:00
Sugar Glider
1ca9dab521
fix(arduino_pins): fixes Lolin-C3-Pico and C3-Mini RGB LED pin + C3-Pico SPI SCK pin definition (#11186)
* fix(arduino_pins): fixes RGB LED pin and SPI SCK pin definition

* fix(arduino_pins): lolin-c3-mini rgb led pin
2025-03-27 12:32:36 +02:00
Lucas Saavedra Vaz
caa597143c
ci(workflows): Lock actions to commits and improve readability (#11147)
* Revert "ci(actions): Replace changed-files (#11130)"

This reverts commit ba2ab1e4bb.

* ci(workflows): Lock actions to commits and improve readability
2025-03-27 12:31:31 +02:00
ShuishengPeng
98611d46dc
fix: Add 16M flash option for xiao_esp32_s3_plus (#11183)
* fix: xiao_esp32_s3_plus supports 16M flash, adds 16M flash and 16M partition table options

* fix: remove empty lines

---------

Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
2025-03-27 12:29:57 +02:00
Me No Dev
df51bc3aa5
fix(eth): Set the ETH properties at the correct time (#11182)
* fix(eth): Set the ETH properties at the correct time

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-27 12:29:31 +02:00
Me No Dev
9dddc142fc
fix(net): Use network_event_handle_t for internal callbacks (#11179)
* fix(net): Use network_event_handle_t for internal callbacks

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-27 12:29:11 +02:00
Marcel
cd7f4218e7
Fix(esp32s3usbotg) stdbool dependency in pins_arduino.h (#11155)
* Fix(esp32s3usbotg) stdbool dependency in pins_arduino.h

* fix(board): Remove comment in pins_arduino.h

---------

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-03-24 15:26:49 +02:00
Sugar Glider
6273c4ffd8
fix(freertos_stats): remove volatile c++ 20 deprecated warning (#11158) 2025-03-24 14:59:42 +02:00
Lucas Saavedra Vaz
cc2632b3bb
fix(ext_lib): Fix ESPAsyncWebServer URL and examples (#11160) 2025-03-24 14:51:25 +02:00
Math0XK
6c04a93153
Add a Default 32MB partition (#11143)
* Add a Default 32MB partition

This is a complementary addition to use 32MB boards in PlatformIO like the ESP32-S3-DevKitC-1-N32R8V.

* Edited Board file

Added partition "default_32MB" to the menu

* Delete tools/boards.txt

* Edited boards.txt

Added the "default_32MB" partition to the menu

* feat(boards): adds app13M_data7M_32MB to s3 octal

* fix(board): format linux new line

* fix(boards): trying to make it \n and not \r\n

* add change to esp32s3-octal board too

This reverts commit 3afddfc2ce5281d8cd0344bc91665665d4179040, reversing
changes made to a9f64003bad5a2dcc1bd7f66e8494c9f8c8dd2e2.

* fix(boards): setting eol as /n

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-20 22:11:11 +02:00
TANAKA Masayuki
7fda434d89
fix(rmt): Fixed protocol name in RMTReadXJT examples (#11136)
* fix(rmt): Fixed protocol name in RMTReadXJT examples

I couldn't find a protocol called D12.
I found LR12 so I'll fix that.

* feat(RMT): changing example commentary to reflect D16 protocol

---------

Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
2025-03-20 21:52:36 +02:00
Me No Dev
7c1ac1ae60 feat(wifi): Add support for 2.4GHz and 5GHz band switching (#11045)
* feat(wifi): Add support for 2.4GHz and 5GHz band switching

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-20 02:10:20 +02:00
Jason2866
d66eeb7754 c5 flash base address is 0x2000 (#11037)
* c5 flash base address is 0x2000

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-20 02:10:20 +02:00
Me No Dev
3fe2fe5311 IDF master 0461e2ff (#11018) 2025-03-20 02:10:20 +02:00
Me No Dev
e30e3c30f1 IDF master (#10999)
* IDF master c71d74e2

* IDF master 81e8b752

* IDF master 877057db
2025-03-20 02:10:20 +02:00
Me No Dev
042015efc8 IDF master (#10981)
* IDF master 1160a86b

* fix(ci): Do not compile RainMaker examples on ESP32
2025-03-20 02:10:20 +02:00
Me No Dev
6283c15ae2 IDF master (#10887)
* feat(ci): Run sketches on ESP32-C5

* IDF master 1160a86b

* fix(zigbee): Remove RCP mode from ESP32-C5
2025-03-20 02:10:20 +02:00
me-no-dev
75de09ef29 fix(board): Update ESP32-C5 Dev Kit Pinout 2025-03-20 02:09:27 +02:00
me-no-dev
f45cd7bf33 fix(psram): Add support for ESP32-C5 PSRAM 2025-03-20 02:09:27 +02:00
Jan Procházka
9fbcb345b7 fix(c5): Update PIN_RGB_LED in pins_arduino.h 2025-03-20 02:09:27 +02:00
me-no-dev
8af81cdf09 fix(ci): Fix/stop some examples for C5 2025-03-20 02:09:27 +02:00
Jason2866
d9d3bf48d3 add c5 bootloader location to pioarduino script (#10889)
* add c5 bootloader location to pioarduino script

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-20 02:09:27 +02:00
Jan Procházka
100ed8e895 fix(c5): Update debug log in setCpuFrequencyMhz 2025-03-20 02:09:27 +02:00
me-no-dev
0894d7db68 fix(report): Add missing chip names 2025-03-20 02:09:27 +02:00
me-no-dev
af5abd5f61 fix(c5): Update bootloader location 2025-03-20 02:09:27 +02:00
me-no-dev
bf90cbd183 fix(examples): Add changes required to some examples 2025-03-20 02:09:27 +02:00
me-no-dev
88cda9ff59 feat(idf): Add initial support for IDF v5.5 and ESP32-C5 2025-03-20 02:09:27 +02:00
Lucas Saavedra Vaz
66abd86ce9
fix(camera_webserver): Fix typo in OV2640 definition (#11145) 2025-03-20 02:06:20 +02:00
Sugar Glider
18709faa90
fix(uart): uart rx timeout validation with proper log message (#11141)
* feat(uart): adds a function to calculate maximum valid rx timeout

* fix(uart): check uart rx timeout value and log an error msg

* fix(uart): changes log message to a more clear one

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-20 02:02:20 +02:00
Jan Procházka
e2915c48e8
feat(zigbee): Save network channel after 1st joining for faster rejoin (#11123)
* feat(zigbee): Save network channel after 1st joining for faster rejoin

* ci(pre-commit): Apply automatic fixes

* feat(zigbee): Add channel mask reset after timeout

* feat(zigbee): Add the resetChannelMask to all Begin methods

* feaz(zigbee): Move function to private and add set method

* fix(example): Remove test from device mode name

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-19 14:08:56 +02:00
Sugar Glider
8e62997bfd
fix(UART): sets the correct uart clock source when using begin(baudrate) (#11122)
* fix(uart): uart begin does not set the clock source when baudrate changes

* fix(uart): returns success on baud rate change operation

* fix(code): uart typo - missing ( in the code

* fix(uart): replacing mutex lock to avoid double lock

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-17 17:36:44 +02:00
Sugar Glider
74ee9df48c
fix(uart): Fixes UART CI script to work with Arduino Core 3.2.x (#11077)
* fix(uart): ci uart test fail on esp32s2 after uart break

* fix(uart): ci error with change pins test on ESP32

* fix(uart): ci test with perimgr using esp32 fails

* feat(uart): avoid electrical noise before setting pins

* fix(uart_ci): fixes the UART CI sketch due to IDF 5.3 pull up change

* fix(uart_ci): keeping previous formatting and applying changes

* feat(uart_ci): trick for passing esp32 wokwi ci test

Wokwi ESP32 fails with the pinMode() in line 56|58
Real device with Arduino Core 3.1.2 and 3.2 needs it to fix the issue.
This patch will skip the pinMode() when compiling with Wokwi and make it pass the CI test case.

* feat(uart_ci): reverting the wokwi patch, once it didn't make any difference

* fix(wokwi): Change CPU freq to 80

* fix(wokwi): Change CPU freq to 120

* ci(pre-commit): Apply automatic fixes

* fix(uart_ci): fixes a couple typos in commentatries

---------

Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-17 17:36:10 +02:00
Lucas Saavedra Vaz
ba2ab1e4bb
ci(actions): Replace changed-files (#11130) 2025-03-17 15:20:30 +02:00
Lucas Saavedra Vaz
f7c1efccaa
docs(esp32p4): Add missing information and improve organization (#11081)
* docs(esp32p4): Add missing information and improve organization

* docs(datasheets): Add missing datasheets

* docs(readme): Reorder title

* docs(typos): Fix typos
2025-03-17 12:37:41 +02:00
Lucas Saavedra Vaz
2a3de9c415
test(i2c): Do not use delta as Wokwi timing can be inconsistent (#11080)
* test(i2c): Do not use delta as Wokwi timing can be inconsistent

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-13 12:02:43 +02:00
Lucas Saavedra Vaz
c2b0482511
ci(hw): Fix files being overwritten (#11019)
Co-authored-by: Sugar Glider <rodrigo.garcia@espressif.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2025-03-13 11:44:23 +02:00
Ludovic BOUÉ
07d6a5a0d2
feat(Zigbee): Adding Zigbee Wind speed sensor endpoint (#10455)
* Create ZigbeeWindSpeedSensor.h

* Create ZigbeeWindSpeedSensor.cpp

* Update ZigbeeWindSpeedSensor.cpp

* Update ZigbeeWindSpeedSensor.cpp

* Create ZigbeeWindSpeedSensor.ino

* Update ZigbeeWindSpeedSensor.ino

* Update ZigbeeWindSpeedSensor.ino

* Create ci.json

* Rename ZigbeeWindSpeedSensor.ino to Zigbee_Wind_Speed_Sensor.ino

* Rename ci.json to ci.json

* Update CMakeLists.txt

* Update Zigbee_Wind_Speed_Sensor.ino

* Update Zigbee_Wind_Speed_Sensor.ino

* Update Zigbee_Wind_Speed_Sensor.ino

* Update ZigbeeWindSpeedSensor.cpp

* Update ZigbeeWindSpeedSensor.cpp

Use ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID device id

* feat(zigbee): Add windspeed sensor endpoint

* Update Zigbee.h

Add ZigbeeWindSpeedSensor.h

* update example

* add missing sdkconfig include

* add readme

* ci(pre-commit): Apply automatic fixes

* Update README.md

---------

Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-12 15:38:09 +02:00
Me No Dev
bda7c48117
IDF release/v5.4 d4aa25a3 (#11060)
IDF release/v5.4 d4aa25a3
2025-03-11 00:26:18 +02:00
Sugar Glider
e8a243c1db
fix(network): fixes a macro name conflict warning (#11068)
* fix(network): fixes a macro name conflict warning

* feat(networking): removed local maco definition in favor of IDF one
2025-03-10 22:18:12 +02:00
Sugar Glider
d9dbc4af41
fix(matter): examples must set pin to Digital Mode after analogWrite() and before digitalWrite() (#11070)
* fix(matter): itshall set digital mode before digitalWrite

* fix(matter): example must set pin in digital mode before writting

* fix(matter): example shall set digital mode before writing

* fix(matter): digitalMode necessary before digitalWrite(LOW)

* fix(matter): example must set digital mode after analogwrite

* fix(matter): wrong copy paste

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-10 22:00:34 +02:00
Sugar Glider
e680e7b538
fix(matter): removes a few matter 1.4 / IDF 5.4 compilation warning messages (#11067)
* fix(matter): uninitialized fields warning

* fix(matter): uninitialized fields warning
2025-03-10 21:21:25 +02:00
Jan Procházka
2276f0b794
fix(zigbee): Add manuf_code to report attribure commands (#11066) 2025-03-10 21:21:00 +02:00
Jan Procházka
665d6f8e8d
fix(zigbee): Use correct attributeID in setAnalogInputReporting (#11065) 2025-03-10 21:20:34 +02:00
Me No Dev
bf5265c7d8
feat(eth): Add setters for negotiation, speed and duplex modes (#11053)
* feat(eth): Add setters for negotiation, speed and duplex modes

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-10 21:20:07 +02:00
Me No Dev
eeb6a26ed1
fix(wifi): Disable properly LR mode if it was enabled before (#11052)
* fix(wifi): Disable properly LR mode if it was enabled before

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-03-10 21:19:46 +02:00
Me No Dev
8575d04ab5
fix(eth): Fix RMII Ethernet not being able to be restarted (#11048) 2025-03-10 21:19:22 +02:00
Oli
4677ea6ad8
Fix to issue #11044 (#11064)
Fix to a copy-paste error that causes a Guru Meditation crash with Zigbee Analog Example.
2025-03-10 13:53:43 +02:00
Sugar Glider
efb02d30ac
feat(gpio): allows mixing digital and analog read/write operations (#11016)
* feat(gpio): allows mixing digital and analog read/write operations

* fix(gpio): simple mistake in calling __pinMode() fnuction

* fix(gpio): simple mistake in calling __pinMode() fnuction

* feat(gpio): update the log message to tell the solution for the error.

* feat(gpio): warn user about digitalRead() used with non GPIO pin

* fix(gpio): wrong peripheral manager test case
2025-03-09 13:20:59 +02:00
Sugar Glider
fb5f11b638
feat(matter): necessary changes to insights version for esp_matter (#11042)
* feat(matter): necessary changes to insights version for esp_matter

* feat(rainmaker): update RainMaker version to 1.5.2
2025-03-08 00:00:58 +02:00
Lucas Saavedra Vaz
9e2f755641
test(i2c): Add test to scan bus (#11022)
* test(i2c): Add test to scan bus

* test(i2c): Add scan test with wifi running

* fix(i2c): Simplify test
2025-03-05 13:33:20 +02:00
iranl
684a9312e6
fix(bt): Compile error on ESP32-P4 (#11035)
* fix(bt): Fix compile error on ESP32-P4

* fix(bt): Fix compile error on ESP32-P4
2025-03-05 12:45:11 +02:00
oddlama
7575fa0ce8
fix(zigbee): use correct carbon dioxide cluster function in setTolerance (#11015)
* fix(zigbee): use correct carbon dioxide cluster function in setTolerance

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-02-26 11:50:28 +02:00
Lucas Saavedra Vaz
e3bcc58672
ci(esp32p4): Add missing options for P4 (#11014)
Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
2025-02-26 11:49:42 +02:00
Jan Procházka
923da957e4
feat(zigbee): Add ZigbeeGateway endpoint support + Time Cluster bugfix (#11009)
* fix(zigbee): Remove the need of native ieee802154 radio

* feat(zigbee): Add ZigbeeGateway endpoint support

* fix(zigbee): Fix TimeCluster missing status attribute

* feat(zigbee): Add new src to CMakeLists

* feaz(zigbee): Update keywords.txt with latest updates

* feat(zigbee): Add 8MB Zigbee ZCZR partitions to other socs

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
2025-02-26 11:49:24 +02:00
Lucas Saavedra Vaz
7485c653bb
ci(zigbee): Check if Zigbee is enabled for CI tests (#11012)
* ci(zigbee): Check if Zigbee is enabled for CI tests

* ci(zigbee): Fix requirements

* fix(zigbee): Use LED_BUILTIN for range extender

* fix(zigbee): Use default GPIO if LED_BUILTINnot defined
2025-02-25 18:00:39 +02:00
Gonzalo Brusco
09d89c6da1
Fix HardwareSerial config (#11007) 2025-02-25 17:58:10 +02:00
oddlama
1467d87454
fix(zigbee): use correct pressure cluster function in setTolerance (#11008)
Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
2025-02-25 10:17:17 +02:00
Hoan Pham
c76c2eab37
Update of Boards.txt & variants - Adding CYObot board - 3rd party board (#10947)
* Adding CYObot board - 3rd party board

1. Adding Pin Header file for CYObot to variants folder
2. Add CYObot config to boards.txt

* feat(cyobot): adding cyobot_v2_esp32s3 board

Change comments in pin header file for cyobot board

* fix(cyobot_v2_esp32s3): fix variant name

fix variant name for cyobot board

* fix(boards.txt): fix name of CYOBot board

- Change name to uppercase

* fix(CYOBot): fix boards.txt & pin_arduino.h

* fix(pins_arduino.h): capitalize name

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-02-25 10:13:35 +02:00
Me No Dev
b33470e44b
IDF release/v5.4 (#10998)
* IDF release/v5.4 bcb3c32d

* fix(zigbee): Remove the need of native ieee802154 radio

---------

Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
2025-02-25 10:13:10 +02:00
SooDragon
0c18b17ac4
feat(boards): Add Geekble-nano-ESP32S3 (#11005)
* add new board

add new board

* fix(board): add LED_BUILTIN #define

---------

Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
2025-02-25 10:07:12 +02:00
Eric Lewis
164fcc6a61
fix(board): Update feathers3 wire1 pin definition (#11001)
* update feathers3 wire1 pin definition

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com>
2025-02-25 10:06:54 +02:00
Lucas Saavedra Vaz
39be694127
ci(runners): Bump runner images version (#10960)
* ci(runners): Bump runner images version

* ci(arm): Use github arm images
2025-02-25 10:06:18 +02:00
Lucas Saavedra Vaz
988dbe2973
ci(test): Skip some PSRAM tests in P4 2025-02-22 01:27:17 -03:00
Lucas Saavedra Vaz
42bd7456ce
ci(test): Fix GPIO test 2025-02-21 23:54:52 -03:00
Lucas Saavedra Vaz
543a647f2c
ci(test): Fix PSRAM test 2025-02-21 23:47:01 -03:00
SooDragon
003db9e4c0
Update pins_arduino.h (#11000) 2025-02-21 12:27:11 +02:00
pwclay
9a783a5d2c
feat(zigbee): Add Analog endpoint device (input, output, value clusters) (#10950)
* add analog sensor modules

* feat(zigbee): Add analog value, input and output support

* fix(zigbee): add missing functiong to header file

* fix(zigbee): Update log messages

* ci(pre-commit): Apply automatic fixes

* fix(example): Fix comment typo

---------

Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-02-20 10:59:43 +02:00
Lucas Saavedra Vaz
cd95e4055b
ci(report): Add runtime tests report (#10764) 2025-02-20 00:52:01 +02:00
Lucas Saavedra Vaz
978b441cd4
test(wokwi): Add I2C Master test and enable GPIO and PSRAM tests (#10848)
* test(wokwi): Enable PSRAM test

* fix(tests): Add missing diagram for ESP32-P4

* test(wokwi): Enable GPIO test

* test(wokwi): Add I2C master test

* fix(tests): Add missing requirement and improve logging

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-02-19 23:32:06 +02:00
Jan Procházka
eec2af3d35
feat(zigbee): Add range extender device endpoint (#10970)
* feat(zigbee): Add range extender device endpoint

* ci(pre-commit): Apply automatic fixes

* fix(example): Fix typo catched by precommit

---------

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-02-19 23:31:37 +02:00
Rodrigo Garcia
5afafdf4c6
fix(matter): commentaries and messages related to factory reset (#10988)
* fix(matter): commentaries and messages related to the factory reset

* fix(matter): commentaries and messages typo
2025-02-19 23:31:08 +02:00
Rodrigo Garcia
646785e086
feat(LP_UART): Implements the ESP32-C6/ESP32-P4 Low Power UART as a possible HardwareSerial port (#10967)
* feat(uart): adds low power uart peripheral into hardware serial class

* feat(lp_uart): pin setting for lp uart plus esp32p4 fixes

* fix(uart): keeps the test as it was before.

* fix(uart): updates the copyright year reference

* fix(uart): updates the copyright year reference

* feat(lp_uart): supports any number of lp uart port for the future

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-02-19 01:01:18 +02:00
me-no-dev
55f4f1bfa8 Update core version to 3.2.0 2025-02-18 19:10:54 +02:00
Me No Dev
8e9f7c31c9
IDF release/v5.4 e37d33cc (#10980) 2025-02-18 17:00:36 +02:00
Me No Dev
783271b6b5
Merge pull request #10890 from P-R-O-C-H-Y/libs/update-zigbee-1.6.2
fix(zigbee): Update esp-zigbee-sdk to 1.6.3 + necessary fixes
2025-02-18 14:01:16 +02:00
Me No Dev
35feed5077
Merge pull request #10832 from espressif/release/v3.2.x
Arduino 3.2.0 based on ESP-IDF v5.4
2025-02-18 11:54:51 +02:00
Me No Dev
f0cf3b1af6 feat(i2c): Add support for the new I2C driver in IDF v5.4 (#10858)
* feat(i2c): Add support for the new I2C driver in IDF v5.4

* fix(build): Add the new driver to CMakeLists.txt

* fix(i2c): Guard sleep retention

Not all chips can restore I2C bus after light sleep

* ci(pre-commit): Apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-02-18 10:11:55 +02:00
Me No Dev
18cbd762c9 feat(eth): Add support for generic IEEE 802.3 driver (#10859) 2025-02-18 10:11:55 +02:00
me-no-dev
50d85a6e9d fix(ci): Run CI against ESP-IDF v5.4 2025-02-18 10:11:55 +02:00
Me No Dev
47343a43f7 feat(idf): Add support for IDF v5.4 (#10823) 2025-02-18 10:11:55 +02:00
Jan Procházka
20e5e706be fix(boards): Delete removed Zigbee RCP mode 2025-02-17 09:47:29 +01:00
Jan Procházka
a4ecdb1a0f feat(zigbee): Bump esp-zigbee-sdk to 1.6.3 2025-02-14 18:32:14 +01:00
Jan Procházka
7089c0a188 fix(zigbee): Update esp-zigbee-sdk to 1.6.2 + necessary changes 2025-01-22 13:34:39 +01:00
618 changed files with 35212 additions and 6861 deletions

View file

@ -1,7 +1,7 @@
[codespell] [codespell]
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check/.codespellrc # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check/.codespellrc
# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here: # In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here:
ignore-words-list = ba,licence,ot,dout,als,exten ignore-words-list = ba,licence,ot,dout,als,exten,emac
skip = ./.git,./.licenses,__pycache__,.clang-format,.codespellrc,.editorconfig,.flake8,.prettierignore,.yamllint.yml,.gitignore,boards.txt,platform.txt,programmers.txt skip = ./.git,./.licenses,__pycache__,.clang-format,.codespellrc,.editorconfig,.flake8,.prettierignore,.yamllint.yml,.gitignore,boards.txt,platform.txt,programmers.txt
builtin = clear,informal,en-GB_to_en-US builtin = clear,informal,en-GB_to_en-US
check-filenames = check-filenames =

81
.github/CODEOWNERS vendored Normal file
View file

@ -0,0 +1,81 @@
# CODEOWNERS for ESP32 Arduino Core
# This file is used to specify the code owners for the ESP32 Arduino Core.
# Read more about CODEOWNERS:
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# Note that order matters. The last matching pattern will be used.
# The default owners are the active developers of the ESP32 Arduino Core.
# Refrain from using @espressif/arduino-esp32 to avoid spamming non-developers with review requests.
* @espressif/arduino-devs
# CI
/.github/ @lucasssvaz @me-no-dev @P-R-O-C-H-Y
/.github/codeql/ @lucasssvaz
/.gitlab/ @lucasssvaz
/tests/ @lucasssvaz @P-R-O-C-H-Y
# Tools
/tools/ @me-no-dev
/tools/pre-commit/ @lucasssvaz
/tools/add_lib.sh @P-R-O-C-H-Y
# Pre-commit
/.* @lucasssvaz # Files in root directory that start with a dot.
# Git Files
/.gitignore @espressif/arduino-devs
/.gitmodules @espressif/arduino-devs
# Documentation
/docs/ @pedrominatel
/.github/ISSUE_TEMPLATE/ @pedrominatel
/.github/PULL_REQUEST_TEMPLATE.md @pedrominatel
/.readthedocs.yaml @pedrominatel
/*.md @pedrominatel
# Boards
/variants/ @P-R-O-C-H-Y
/boards.txt @P-R-O-C-H-Y
# Arduino as Component
/idf_component_examples/ @SuGlider
/idf_component.yml @SuGlider @me-no-dev
/CMakeLists.txt @SuGlider @me-no-dev
/Kconfig.projbuild @SuGlider @me-no-dev
# Build System
/package.json @me-no-dev
/platform.txt @me-no-dev
/programmers.txt @me-no-dev
/package/ @me-no-dev
# Libraries
/libraries/ArduinoOTA/ @me-no-dev
/libraries/AsyncUDP/ @me-no-dev
/libraries/BLE/ @lucasssvaz @SuGlider
/libraries/ESP_I2S/ @me-no-dev
/libraries/ESP_NOW/ @P-R-O-C-H-Y @lucasssvaz
/libraries/ESP_SR/ @me-no-dev
/libraries/ESPmDNS/ @me-no-dev
/libraries/Ethernet/ @me-no-dev
/libraries/Matter/ @SuGlider
/libraries/NetBIOS/ @me-no-dev
/libraries/Network/ @me-no-dev
/libraries/OpenThread/ @SuGlider
/libraries/PPP/ @me-no-dev
/libraries/SPI/ @me-no-dev
/libraries/Update/ @me-no-dev
/libraries/USB/ @SuGlider @me-no-dev
/libraries/WiFi/ @me-no-dev
/libraries/WiFiProv/ @me-no-dev
/libraries/Wire/ @me-no-dev
/libraries/Zigbee/ @P-R-O-C-H-Y
# CI JSON
# Keep this after other libraries and tests to avoid being overridden.
**/ci.json @lucasssvaz
# The CODEOWNERS file should be owned by the developers of the ESP32 Arduino Core.
# Leave this entry as the last one to avoid being overridden.
/.github/CODEOWNERS @espressif/arduino-devs

View file

@ -5,6 +5,7 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
* Please note that we can only process feature requests reported in English to ensure effective communication and support. Feature requests written in other languages will be closed, with a request to rewrite them in English.
* We welcome any ideas or feature requests! It is helpful if you can explain exactly why the feature would be useful. * We welcome any ideas or feature requests! It is helpful if you can explain exactly why the feature would be useful.
* There are usually some outstanding feature requests in the [existing issues list](https://github.com/espressif/arduino-esp32/issues?q=is%3Aopen+is%3Aissue+label%3A%22Type%3A+Feature+request%22), feel free to add comments to them. * There are usually some outstanding feature requests in the [existing issues list](https://github.com/espressif/arduino-esp32/issues?q=is%3Aopen+is%3Aissue+label%3A%22Type%3A+Feature+request%22), feel free to add comments to them.
* If you would like to contribute, please read the [contributions guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html). * If you would like to contribute, please read the [contributions guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/contributing.html).

View file

@ -5,6 +5,7 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
* Please note that we can only process issues reported in English to ensure effective communication and support. Issues written in other languages will be closed, with a request to rewrite them in English.
* Before reporting a new issue please check and search in [List of existing issues](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue) * Before reporting a new issue please check and search in [List of existing issues](https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue)
* Please check [Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/index.html) * Please check [Online Documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/index.html)
* Take a look on [Troubleshooting guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html) * Take a look on [Troubleshooting guide](https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html)
@ -39,8 +40,13 @@ body:
label: Version label: Version
description: What version of Arduino ESP32 are you running? If possible, consider updating to the latest version. description: What version of Arduino ESP32 are you running? If possible, consider updating to the latest version.
options: options:
- latest master (checkout manually) - latest stable Release (if not listed below)
- latest development Release Candidate (RC-X) - latest development Release Candidate (RC-X)
- latest master (checkout manually)
- v3.3.0
- v3.2.1
- v3.2.0
- v3.1.3
- v3.1.2 - v3.1.2
- v3.1.1 - v3.1.1
- v3.1.0 - v3.1.0
@ -74,6 +80,17 @@ body:
- other - other
validations: validations:
required: true required: true
- type: dropdown
id: type
attributes:
label: Type
description: How would you define the type of the issue? Please select from the types below.
options:
- Task
- Bug
- Question
validations:
required: true
- type: input - type: input
id: IDE id: IDE
attributes: attributes:

View file

@ -3,6 +3,3 @@ contact_links:
- name: Arduino Core for Espressif Discord Server - name: Arduino Core for Espressif Discord Server
url: https://discord.gg/8xY6e9crwv url: https://discord.gg/8xY6e9crwv
about: Community Discord server for questions and help about: Community Discord server for questions and help
- name: ESP32 Forum - Arduino
url: https://esp32.com/viewforum.php?f=19
about: Official Forum for questions

26
.github/codeql/codeql-config.yml vendored Normal file
View file

@ -0,0 +1,26 @@
name: "CodeQL config"
packs:
- trailofbits/cpp-queries
- githubsecuritylab/codeql-cpp-queries
- githubsecuritylab/codeql-python-queries
queries:
- uses: security-extended
- uses: security-and-quality
query-filters:
- exclude:
query path:
- /^experimental\/.*/
- exclude:
tags contain:
- experimental
- exclude:
problem.severity:
- recommendation
- exclude:
id: tob/cpp/use-of-legacy-algorithm
paths-ignore:
- tests/**

View file

@ -4,6 +4,7 @@
# Usage: # Usage:
# python merge_packages.py package_esp8266com_index.json version/new/package_esp8266com_index.json # python merge_packages.py package_esp8266com_index.json version/new/package_esp8266com_index.json
# Written by Ivan Grokhotkov, 2015 # Written by Ivan Grokhotkov, 2015
# Updated by lucasssvaz to handle Chinese version sorting, 2025
# #
from __future__ import print_function from __future__ import print_function
@ -36,20 +37,19 @@ def merge_objects(versions, obj):
# Normalize ESP release version string (x.x.x) by adding '-rc<MAXINT>' (x.x.x-rc9223372036854775807) # Normalize ESP release version string (x.x.x) by adding '-rc<MAXINT>' (x.x.x-rc9223372036854775807)
# to ensure having REL above any RC # to ensure having REL above any RC. CN version will be sorted after the official version if they happen
# to be mixed (normally, CN and non-CN versions should not be mixed)
# Dummy approach, functional anyway for current ESP package versioning # Dummy approach, functional anyway for current ESP package versioning
# (unlike NormalizedVersion/LooseVersion/StrictVersion & similar crap) # (unlike NormalizedVersion/LooseVersion/StrictVersion & similar crap)
def pkgVersionNormalized(versionString): def pkgVersionNormalized(versionString):
verStr = str(versionString).replace("-cn", "")
verStr = str(versionString)
verParts = re.split(r"\.|-rc|-alpha", verStr, flags=re.IGNORECASE) verParts = re.split(r"\.|-rc|-alpha", verStr, flags=re.IGNORECASE)
if len(verParts) == 3: if len(verParts) == 3:
if sys.version_info > (3, 0): # Python 3 if "-cn" in str(versionString):
verStr = str(versionString) + "-rc" + str(sys.maxsize) verStr = verStr + "-rc" + str(sys.maxsize // 2)
else: # Python 2 else:
verStr = str(versionString) + "-rc" + str(sys.maxint) verStr = verStr + "-rc" + str(sys.maxsize)
elif len(verParts) != 4: elif len(verParts) != 4:
print("pkgVersionNormalized WARNING: unexpected version format: {0})".format(verStr), file=sys.stderr) print("pkgVersionNormalized WARNING: unexpected version format: {0})".format(verStr), file=sys.stderr)

33
.github/scripts/on-push-idf.sh vendored Normal file
View file

@ -0,0 +1,33 @@
#!/bin/bash
set -e
CHECK_REQUIREMENTS="./components/arduino-esp32/.github/scripts/sketch_utils.sh check_requirements"
# Export IDF environment
. ${IDF_PATH}/export.sh
# Find all examples in ./components/arduino-esp32/idf_component_examples
idf_component_examples=$(find ./components/arduino-esp32/idf_component_examples -mindepth 1 -maxdepth 1 -type d)
for example in $idf_component_examples; do
if [ -f "$example"/ci.json ]; then
# If the target is listed as false, skip the sketch. Otherwise, include it.
is_target=$(jq -r --arg target "$IDF_TARGET" '.targets[$target]' "$example"/ci.json)
if [[ "$is_target" == "false" ]]; then
printf "\n\033[93mSkipping %s for target %s\033[0m\n\n" "$example" "$IDF_TARGET"
continue
fi
fi
idf.py -C "$example" set-target "$IDF_TARGET"
has_requirements=$(${CHECK_REQUIREMENTS} "$example" "$example/sdkconfig")
if [ "$has_requirements" -eq 0 ]; then
printf "\n\033[93m%s does not meet the requirements for %s. Skipping...\033[0m\n\n" "$example" "$IDF_TARGET"
continue
fi
printf "\n\033[95mBuilding %s\033[0m\n\n" "$example"
idf.py -C "$example" -DEXTRA_COMPONENT_DIRS="$PWD/components" build
done

View file

@ -90,6 +90,7 @@ if [ "$BUILD_LOG" -eq 1 ]; then
fi fi
#build sketches for different targets #build sketches for different targets
build "esp32c5" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32p4" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}" build "esp32p4" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32s3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}" build "esp32s3" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"
build "esp32s2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}" build "esp32s2" "$CHUNK_INDEX" "$CHUNKS_CNT" "$BUILD_LOG" "$LOG_LEVEL" "$SKETCHES_FILE" "${SKETCHES_ESP32[@]}"

View file

@ -35,6 +35,8 @@ PACKAGE_JSON_MERGE="$GITHUB_WORKSPACE/.github/scripts/merge_packages.py"
PACKAGE_JSON_TEMPLATE="$GITHUB_WORKSPACE/package/package_esp32_index.template.json" PACKAGE_JSON_TEMPLATE="$GITHUB_WORKSPACE/package/package_esp32_index.template.json"
PACKAGE_JSON_DEV="package_esp32_dev_index.json" PACKAGE_JSON_DEV="package_esp32_dev_index.json"
PACKAGE_JSON_REL="package_esp32_index.json" PACKAGE_JSON_REL="package_esp32_index.json"
PACKAGE_JSON_DEV_CN="package_esp32_dev_index_cn.json"
PACKAGE_JSON_REL_CN="package_esp32_index_cn.json"
echo "Event: $GITHUB_EVENT_NAME, Repo: $GITHUB_REPOSITORY, Path: $GITHUB_WORKSPACE, Ref: $GITHUB_REF" echo "Event: $GITHUB_EVENT_NAME, Repo: $GITHUB_REPOSITORY, Path: $GITHUB_WORKSPACE, Ref: $GITHUB_REF"
echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID" echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID"
@ -339,9 +341,15 @@ jq_arg=".packages[0].platforms[0].version = \"$RELEASE_TAG\" | \
# Generate package JSONs # Generate package JSONs
echo "Generating $PACKAGE_JSON_DEV ..." echo "Generating $PACKAGE_JSON_DEV ..."
cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_DEV" cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_DEV"
# On MacOS the sed command won't skip the first match. Use gsed instead.
sed '0,/github\.com\//!s|github\.com/|dl.espressif.cn/github_assets/|g' "$OUTPUT_DIR/$PACKAGE_JSON_DEV" > "$OUTPUT_DIR/$PACKAGE_JSON_DEV_CN"
python "$SCRIPTS_DIR/release_append_cn.py" "$OUTPUT_DIR/$PACKAGE_JSON_DEV_CN"
if [ "$RELEASE_PRE" == "false" ]; then if [ "$RELEASE_PRE" == "false" ]; then
echo "Generating $PACKAGE_JSON_REL ..." echo "Generating $PACKAGE_JSON_REL ..."
cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_REL" cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_REL"
# On MacOS the sed command won't skip the first match. Use gsed instead.
sed '0,/github\.com\//!s|github\.com/|dl.espressif.cn/github_assets/|g' "$OUTPUT_DIR/$PACKAGE_JSON_REL" > "$OUTPUT_DIR/$PACKAGE_JSON_REL_CN"
python "$SCRIPTS_DIR/release_append_cn.py" "$OUTPUT_DIR/$PACKAGE_JSON_REL_CN"
fi fi
# Figure out the last release or pre-release # Figure out the last release or pre-release
@ -373,12 +381,14 @@ echo
if [ -n "$prev_any_release" ] && [ "$prev_any_release" != "null" ]; then if [ -n "$prev_any_release" ] && [ "$prev_any_release" != "null" ]; then
echo "Merging with JSON from $prev_any_release ..." echo "Merging with JSON from $prev_any_release ..."
merge_package_json "$prev_any_release/$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV" merge_package_json "$prev_any_release/$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV"
merge_package_json "$prev_any_release/$PACKAGE_JSON_DEV_CN" "$OUTPUT_DIR/$PACKAGE_JSON_DEV_CN"
fi fi
if [ "$RELEASE_PRE" == "false" ]; then if [ "$RELEASE_PRE" == "false" ]; then
if [ -n "$prev_release" ] && [ "$prev_release" != "null" ]; then if [ -n "$prev_release" ] && [ "$prev_release" != "null" ]; then
echo "Merging with JSON from $prev_release ..." echo "Merging with JSON from $prev_release ..."
merge_package_json "$prev_release/$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL" merge_package_json "$prev_release/$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL"
merge_package_json "$prev_release/$PACKAGE_JSON_REL_CN" "$OUTPUT_DIR/$PACKAGE_JSON_REL_CN"
fi fi
fi fi
@ -388,6 +398,8 @@ echo "Installing arduino-cli ..."
export PATH="/home/runner/bin:$PATH" export PATH="/home/runner/bin:$PATH"
source "${SCRIPTS_DIR}/install-arduino-cli.sh" source "${SCRIPTS_DIR}/install-arduino-cli.sh"
# For the Chinese mirror, we can't test the package JSONs as the Chinese mirror might not be updated yet.
echo "Testing $PACKAGE_JSON_DEV install ..." echo "Testing $PACKAGE_JSON_DEV install ..."
echo "Installing esp32 ..." echo "Installing esp32 ..."
@ -445,11 +457,15 @@ fi
echo "Uploading $PACKAGE_JSON_DEV ..." echo "Uploading $PACKAGE_JSON_DEV ..."
echo "Download URL: $(git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_DEV")" echo "Download URL: $(git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_DEV")"
echo "Pages URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV")" echo "Pages URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV")"
echo "Download CN URL: $(git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_DEV_CN")"
echo "Pages CN URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_DEV_CN" "$OUTPUT_DIR/$PACKAGE_JSON_DEV_CN")"
echo echo
if [ "$RELEASE_PRE" == "false" ]; then if [ "$RELEASE_PRE" == "false" ]; then
echo "Uploading $PACKAGE_JSON_REL ..." echo "Uploading $PACKAGE_JSON_REL ..."
echo "Download URL: $(git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_REL")" echo "Download URL: $(git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_REL")"
echo "Pages URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL")" echo "Pages URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL")"
echo "Download CN URL: $(git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_REL_CN")"
echo "Pages CN URL: $(git_safe_upload_to_pages "$PACKAGE_JSON_REL_CN" "$OUTPUT_DIR/$PACKAGE_JSON_REL_CN")"
echo echo
fi fi

57
.github/scripts/release_append_cn.py vendored Executable file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env python3
# Arduino IDE provides by default a package file for the ESP32. This causes version conflicts
# when the user tries to use the JSON file with the Chinese mirrors.
#
# The downside is that the Arduino IDE will always warn the user that updates are available as it
# will consider the version from the Chinese mirrors as a pre-release version.
#
# This script is used to append "-cn" to all versions in the package_esp32_index_cn.json file so that
# the user can select the Chinese mirrors without conflicts.
#
# If Arduino ever stops providing the package_esp32_index.json file by default,
# this script can be removed and the tags reverted.
import json
def append_cn_to_versions(obj):
if isinstance(obj, dict):
# Skip tools that are not from the esp32 package
packager = obj.get("packager")
if packager is not None and packager != "esp32":
return
for key, value in obj.items():
if key == "version" and isinstance(value, str):
if not value.endswith("-cn"):
obj[key] = value + "-cn"
else:
append_cn_to_versions(value)
elif isinstance(obj, list):
for item in obj:
append_cn_to_versions(item)
def process_json_file(input_path, output_path=None):
with open(input_path, "r", encoding="utf-8") as f:
data = json.load(f)
append_cn_to_versions(data)
if output_path is None:
output_path = input_path
with open(output_path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
print(f"Updated JSON written to {output_path}")
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("Usage: python release_append_cn.py input.json [output.json]")
else:
input_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
process_json_file(input_file, output_file)

View file

@ -16,7 +16,7 @@ function check_requirements { # check_requirements <sketchdir> <sdkconfig_path>
local requirements_or local requirements_or
if [ ! -f "$sdkconfig_path" ] || [ ! -f "$sketchdir/ci.json" ]; then if [ ! -f "$sdkconfig_path" ] || [ ! -f "$sketchdir/ci.json" ]; then
echo "ERROR: sdkconfig or ci.json not found" 1>&2 echo "WARNING: sdkconfig or ci.json not found. Assuming requirements are met." 1>&2
# Return 1 on error to force the sketch to be built and fail. This way the # Return 1 on error to force the sketch to be built and fail. This way the
# CI will fail and the user will know that the sketch has a problem. # CI will fail and the user will know that the sketch has a problem.
else else
@ -156,6 +156,7 @@ function build_sketch { # build_sketch <ide_path> <user_path> <path-to-ino> [ext
esp32c6_opts=$(echo "$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g') esp32c6_opts=$(echo "$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g')
esp32h2_opts=$(echo "$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g') esp32h2_opts=$(echo "$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g')
esp32p4_opts=$(echo "PSRAM=enabled,USBMode=default,$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g') esp32p4_opts=$(echo "PSRAM=enabled,USBMode=default,$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g')
esp32c5_opts=$(echo "$debug_level,$fqbn_append" | sed 's/^,*//;s/,*$//;s/,\{2,\}/,/g')
# Select the common part of the FQBN based on the target. The rest will be # Select the common part of the FQBN based on the target. The rest will be
# appended depending on the passed options. # appended depending on the passed options.
@ -191,6 +192,10 @@ function build_sketch { # build_sketch <ide_path> <user_path> <path-to-ino> [ext
[ -n "${options:-$esp32p4_opts}" ] && opt=":${options:-$esp32p4_opts}" [ -n "${options:-$esp32p4_opts}" ] && opt=":${options:-$esp32p4_opts}"
fqbn="espressif:esp32:esp32p4$opt" fqbn="espressif:esp32:esp32p4$opt"
;; ;;
"esp32c5")
[ -n "${options:-$esp32c5_opts}" ] && opt=":${options:-$esp32c5_opts}"
fqbn="espressif:esp32:esp32c5$opt"
;;
*) *)
echo "ERROR: Invalid chip: $target" echo "ERROR: Invalid chip: $target"
exit 1 exit 1
@ -244,7 +249,7 @@ function build_sketch { # build_sketch <ide_path> <user_path> <path-to-ino> [ext
build_dir="$ARDUINO_BUILD_DIR" build_dir="$ARDUINO_BUILD_DIR"
elif [ "$len" -eq 1 ]; then elif [ "$len" -eq 1 ]; then
# build_dir="$sketchdir/build" # build_dir="$sketchdir/build"
build_dir="$HOME/.arduino/tests/$sketchname/build.tmp" build_dir="$HOME/.arduino/tests/$target/$sketchname/build.tmp"
fi fi
output_file="$HOME/.arduino/cli_compile_output.txt" output_file="$HOME/.arduino/cli_compile_output.txt"
@ -254,7 +259,7 @@ function build_sketch { # build_sketch <ide_path> <user_path> <path-to-ino> [ext
for i in $(seq 0 $((len - 1))); do for i in $(seq 0 $((len - 1))); do
if [ "$len" -ne 1 ]; then if [ "$len" -ne 1 ]; then
# build_dir="$sketchdir/build$i" # build_dir="$sketchdir/build$i"
build_dir="$HOME/.arduino/tests/$sketchname/build$i.tmp" build_dir="$HOME/.arduino/tests/$target/$sketchname/build$i.tmp"
fi fi
rm -rf "$build_dir" rm -rf "$build_dir"
mkdir -p "$build_dir" mkdir -p "$build_dir"

View file

@ -11,9 +11,11 @@ function run_test {
local error=0 local error=0
local sdkconfig_path local sdkconfig_path
local extra_args local extra_args
local test_type
sketchdir=$(dirname "$sketch") sketchdir=$(dirname "$sketch")
sketchname=$(basename "$sketchdir") sketchname=$(basename "$sketchdir")
test_type=$(basename "$(dirname "$sketchdir")")
if [ "$options" -eq 0 ] && [ -f "$sketchdir"/ci.json ]; then if [ "$options" -eq 0 ] && [ -f "$sketchdir"/ci.json ]; then
len=$(jq -r --arg target "$target" '.fqbn[$target] | length' "$sketchdir"/ci.json) len=$(jq -r --arg target "$target" '.fqbn[$target] | length' "$sketchdir"/ci.json)
@ -25,9 +27,9 @@ function run_test {
fi fi
if [ "$len" -eq 1 ]; then if [ "$len" -eq 1 ]; then
sdkconfig_path="$HOME/.arduino/tests/$sketchname/build.tmp/sdkconfig" sdkconfig_path="$HOME/.arduino/tests/$target/$sketchname/build.tmp/sdkconfig"
else else
sdkconfig_path="$HOME/.arduino/tests/$sketchname/build0.tmp/sdkconfig" sdkconfig_path="$HOME/.arduino/tests/$target/$sketchname/build0.tmp/sdkconfig"
fi fi
if [ -f "$sketchdir"/ci.json ]; then if [ -f "$sketchdir"/ci.json ]; then
@ -43,22 +45,22 @@ function run_test {
fi fi
if [ ! -f "$sdkconfig_path" ]; then if [ ! -f "$sdkconfig_path" ]; then
printf "\033[93mSketch %s not built\nMight be due to missing target requirements or build failure\033[0m\n" "$sketchname" printf "\033[93mSketch %s build not found in %s\nMight be due to missing target requirements or build failure\033[0m\n" "$(dirname "$sdkconfig_path")" "$sketchname"
printf "\n\n\n" printf "\n\n\n"
return 0 return 0
fi fi
local right_target local compiled_target
right_target=$(grep -E "^CONFIG_IDF_TARGET=\"$target\"$" "$sdkconfig_path") compiled_target=$(grep -E "CONFIG_IDF_TARGET=" "$sdkconfig_path" | cut -d'"' -f2)
if [ -z "$right_target" ]; then if [ "$compiled_target" != "$target" ]; then
printf "\033[91mError: Sketch %s compiled for different target\n\033[0m\n" "$sketchname" printf "\033[91mError: Sketch %s compiled for %s, expected %s\033[0m\n" "$sketchname" "$compiled_target" "$target"
printf "\n\n\n" printf "\n\n\n"
return 1 return 1
fi fi
if [ "$len" -eq 1 ]; then if [ "$len" -eq 1 ]; then
# build_dir="$sketchdir/build" # build_dir="$sketchdir/build"
build_dir="$HOME/.arduino/tests/$sketchname/build.tmp" build_dir="$HOME/.arduino/tests/$target/$sketchname/build.tmp"
report_file="$sketchdir/$target/$sketchname.xml" report_file="$sketchdir/$target/$sketchname.xml"
fi fi
@ -81,7 +83,7 @@ function run_test {
if [ "$len" -ne 1 ]; then if [ "$len" -ne 1 ]; then
# build_dir="$sketchdir/build$i" # build_dir="$sketchdir/build$i"
build_dir="$HOME/.arduino/tests/$sketchname/build$i.tmp" build_dir="$HOME/.arduino/tests/$target/$sketchname/build$i.tmp"
report_file="$sketchdir/$target/$sketchname$i.xml" report_file="$sketchdir/$target/$sketchname$i.xml"
fi fi
@ -113,14 +115,14 @@ function run_test {
rm "$sketchdir"/diagram.json 2>/dev/null || true rm "$sketchdir"/diagram.json 2>/dev/null || true
result=0 result=0
printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "${extra_args[*]@Q}" printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}"
bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" ${extra_args[*]@Q}; exit \$?" || result=$? bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$?
printf "\n" printf "\n"
if [ $result -ne 0 ]; then if [ $result -ne 0 ]; then
result=0 result=0
printf "\033[95mRetrying test: %s -- Config: %s\033[0m\n" "$sketchname" "$i" printf "\033[95mRetrying test: %s -- Config: %s\033[0m\n" "$sketchname" "$i"
printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "${extra_args[*]@Q}" printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}"
bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" ${extra_args[*]@Q}; exit \$?" || result=$? bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$?
printf "\n" printf "\n"
if [ $result -ne 0 ]; then if [ $result -ne 0 ]; then
printf "\033[91mFailed test: %s -- Config: %s\033[0m\n\n" "$sketchname" "$i" printf "\033[91mFailed test: %s -- Config: %s\033[0m\n\n" "$sketchname" "$i"

View file

@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# Disable shellcheck warning about using 'cat' to read a file.
# shellcheck disable=SC2002 # shellcheck disable=SC2002
# For reference: add tools for all boards by replacing one line in each board # For reference: add tools for all boards by replacing one line in each board
@ -23,7 +24,15 @@ ESP_ARDUINO_VERSION_MINOR="$2"
ESP_ARDUINO_VERSION_PATCH="$3" ESP_ARDUINO_VERSION_PATCH="$3"
ESP_ARDUINO_VERSION="$ESP_ARDUINO_VERSION_MAJOR.$ESP_ARDUINO_VERSION_MINOR.$ESP_ARDUINO_VERSION_PATCH" ESP_ARDUINO_VERSION="$ESP_ARDUINO_VERSION_MAJOR.$ESP_ARDUINO_VERSION_MINOR.$ESP_ARDUINO_VERSION_PATCH"
# Get ESP-IDF version from push.yml (this way we can ensure that the version is correct even if the local libs are not up to date)
ESP_IDF_VERSION=$(grep "idf_ver:" .github/workflows/push.yml | sed 's/.*release-v\([^"]*\).*/\1/')
if [ -z "$ESP_IDF_VERSION" ]; then
echo "Error: ESP-IDF version not found in push.yml" >&2
exit 1
fi
echo "New Arduino Version: $ESP_ARDUINO_VERSION" echo "New Arduino Version: $ESP_ARDUINO_VERSION"
echo "ESP-IDF Version: $ESP_IDF_VERSION"
echo "Updating platform.txt..." echo "Updating platform.txt..."
cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > __platform.txt && mv __platform.txt platform.txt cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > __platform.txt && mv __platform.txt platform.txt
@ -31,6 +40,16 @@ cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > __platfor
echo "Updating package.json..." echo "Updating package.json..."
cat package.json | sed "s/.*\"version\":.*/ \"version\": \"$ESP_ARDUINO_VERSION\",/g" > __package.json && mv __package.json package.json cat package.json | sed "s/.*\"version\":.*/ \"version\": \"$ESP_ARDUINO_VERSION\",/g" > __package.json && mv __package.json package.json
echo "Updating docs/conf_common.py..."
cat docs/conf_common.py | \
sed "s/.. |version| replace:: .*/.. |version| replace:: $ESP_ARDUINO_VERSION/g" | \
sed "s/.. |idf_version| replace:: .*/.. |idf_version| replace:: $ESP_IDF_VERSION/g" > docs/__conf_common.py && mv docs/__conf_common.py docs/conf_common.py
echo "Updating .gitlab/workflows/common.yml..."
cat .gitlab/workflows/common.yml | \
sed "s/ESP_IDF_VERSION:.*/ESP_IDF_VERSION: \"$ESP_IDF_VERSION\"/g" | \
sed "s/ESP_ARDUINO_VERSION:.*/ESP_ARDUINO_VERSION: \"$ESP_ARDUINO_VERSION\"/g" > .gitlab/workflows/__common.yml && mv .gitlab/workflows/__common.yml .gitlab/workflows/common.yml
echo "Updating cores/esp32/esp_arduino_version.h..." echo "Updating cores/esp32/esp_arduino_version.h..."
cat 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_MAJOR.*/#define ESP_ARDUINO_VERSION_MAJOR $ESP_ARDUINO_VERSION_MAJOR/g" | \

236
.github/scripts/update_esptool.py vendored Normal file
View file

@ -0,0 +1,236 @@
#!/usr/bin/env python3
# This script is used to re-package the esptool if needed and update the JSON file
# for the Arduino ESP32 platform.
#
# The script has only been tested on macOS.
#
# For regular esptool releases, the generated packages already contain the correct permissions,
# extensions and are uploaded to the GitHub release assets. In this case, the script will only
# update the JSON file with the information from the GitHub release.
#
# The script can be used in two modes:
# 1. Local build: The build artifacts must be already downloaded and extracted in the base_folder.
# This is useful for esptool versions that are not yet released and that are grabbed from the
# GitHub build artifacts.
# 2. Release build: The script will get the release information from GitHub and update the JSON file.
# This is useful for esptool versions that are already released and that are uploaded to the
# GitHub release assets.
#
# For local build, the artifacts must be already downloaded and extracted in the base_folder
# set with the -l option.
# For example, a base folder "esptool" should contain the following folders extracted directly
# from the GitHub build artifacts:
# esptool/esptool-linux-aarch64
# esptool/esptool-linux-amd64
# esptool/esptool-linux-armv7
# esptool/esptool-macos-amd64
# esptool/esptool-macos-arm64
# esptool/esptool-windows-amd64
import argparse
import json
import os
import shutil
import stat
import tarfile
import zipfile
import hashlib
import requests
from pathlib import Path
def compute_sha256(filepath):
sha256 = hashlib.sha256()
with open(filepath, "rb") as f:
for block in iter(lambda: f.read(4096), b""):
sha256.update(block)
return f"SHA-256:{sha256.hexdigest()}"
def get_file_size(filepath):
return os.path.getsize(filepath)
def update_json_for_host(tmp_json_path, version, host, url, archiveFileName, checksum, size):
with open(tmp_json_path) as f:
data = json.load(f)
for pkg in data.get("packages", []):
for tool in pkg.get("tools", []):
if tool.get("name") == "esptool_py":
tool["version"] = version
if url is None:
# If the URL is not set, we need to find the old URL and update it
for system in tool.get("systems", []):
if system.get("host") == host:
url = system.get("url").replace(system.get("archiveFileName"), archiveFileName)
break
else:
print(f"No old URL found for host {host}. Using empty URL.")
url = ""
# Preserve existing systems order and update or append the new system
systems = tool.get("systems", [])
system_updated = False
for i, system in enumerate(systems):
if system.get("host") == host:
systems[i] = {
"host": host,
"url": url,
"archiveFileName": archiveFileName,
"checksum": checksum,
"size": str(size),
}
system_updated = True
break
if not system_updated:
systems.append({
"host": host,
"url": url,
"archiveFileName": archiveFileName,
"checksum": checksum,
"size": str(size),
})
tool["systems"] = systems
with open(tmp_json_path, "w") as f:
json.dump(data, f, indent=2, sort_keys=False, ensure_ascii=False)
f.write("\n")
def update_tools_dependencies(tmp_json_path, version):
with open(tmp_json_path) as f:
data = json.load(f)
for pkg in data.get("packages", []):
for platform in pkg.get("platforms", []):
for dep in platform.get("toolsDependencies", []):
if dep.get("name") == "esptool_py":
dep["version"] = version
with open(tmp_json_path, "w") as f:
json.dump(data, f, indent=2, sort_keys=False, ensure_ascii=False)
f.write("\n")
def create_archives(version, base_folder):
archive_files = []
for dirpath in Path(base_folder).glob("esptool-*"):
if not dirpath.is_dir():
continue
base = dirpath.name[len("esptool-"):]
if "windows" in dirpath.name:
zipfile_name = f"esptool-v{version}-{base}.zip"
print(f"Creating {zipfile_name} from {dirpath} ...")
with zipfile.ZipFile(zipfile_name, "w", zipfile.ZIP_DEFLATED) as zipf:
for root, _, files in os.walk(dirpath):
for file in files:
full_path = os.path.join(root, file)
zipf.write(full_path, os.path.relpath(full_path, start=dirpath))
archive_files.append(zipfile_name)
else:
tarfile_name = f"esptool-v{version}-{base}.tar.gz"
print(f"Creating {tarfile_name} from {dirpath} ...")
for root, dirs, files in os.walk(dirpath):
for name in dirs + files:
os.chmod(os.path.join(root, name), stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
stat.S_IRGRP | stat.S_IXGRP |
stat.S_IROTH | stat.S_IXOTH)
with tarfile.open(tarfile_name, "w:gz") as tar:
tar.add(dirpath, arcname=dirpath.name)
archive_files.append(tarfile_name)
return archive_files
def determine_hosts(archive_name):
if "linux-amd64" in archive_name:
return ["x86_64-pc-linux-gnu"]
elif "linux-armv7" in archive_name:
return ["arm-linux-gnueabihf"]
elif "linux-aarch64" in archive_name:
return ["aarch64-linux-gnu"]
elif "macos-amd64" in archive_name:
return ["x86_64-apple-darwin"]
elif "macos-arm64" in archive_name:
return ["arm64-apple-darwin"]
elif "windows-amd64" in archive_name:
return ["x86_64-mingw32", "i686-mingw32"]
else:
return []
def update_json_from_local_build(tmp_json_path, version, base_folder, archive_files):
for archive in archive_files:
print(f"Processing archive: {archive}")
hosts = determine_hosts(archive)
if not hosts:
print(f"Skipping unknown archive type: {archive}")
continue
archive_path = Path(archive)
checksum = compute_sha256(archive_path)
size = get_file_size(archive_path)
for host in hosts:
update_json_for_host(tmp_json_path, version, host, None, archive_path.name, checksum, size)
def update_json_from_release(tmp_json_path, version, release_info):
assets = release_info.get("assets", [])
for asset in assets:
if (asset.get("name").endswith(".tar.gz") or asset.get("name").endswith(".zip")) and "esptool" in asset.get("name"):
asset_fname = asset.get("name")
print(f"Processing asset: {asset_fname}")
hosts = determine_hosts(asset_fname)
if not hosts:
print(f"Skipping unknown archive type: {asset_fname}")
continue
asset_url = asset.get("browser_download_url")
asset_checksum = asset.get("digest").replace("sha256:", "SHA-256:")
asset_size = asset.get("size")
if asset_checksum is None:
asset_checksum = ""
print(f"Asset {asset_fname} has no checksum. Please set the checksum in the JSON file.")
for host in hosts:
update_json_for_host(tmp_json_path, version, host, asset_url, asset_fname, asset_checksum, asset_size)
def get_release_info(version):
url = f"https://api.github.com/repos/espressif/esptool/releases/tags/v{version}"
response = requests.get(url)
response.raise_for_status()
return response.json()
def main():
parser = argparse.ArgumentParser(description="Repack esptool and update JSON metadata.")
parser.add_argument("version", help="Version of the esptool (e.g. 5.0.dev1)")
parser.add_argument("-l", "--local", dest="base_folder", help="Enable local build mode and set the base folder with unpacked artifacts")
args = parser.parse_args()
script_dir = Path(__file__).resolve().parent
json_path = (script_dir / "../../package/package_esp32_index.template.json").resolve()
tmp_json_path = Path(str(json_path) + ".tmp")
shutil.copy(json_path, tmp_json_path)
local_build = args.base_folder is not None
if local_build:
os.chdir(args.base_folder)
os.environ['COPYFILE_DISABLE'] = 'true' # this disables including resource forks in tar files on macOS
# Clear any existing archive files
for file in Path(args.base_folder).glob("esptool-*.*"):
file.unlink()
archive_files = create_archives(args.version, args.base_folder)
update_json_from_local_build(tmp_json_path, args.version, args.base_folder, archive_files)
else:
release_info = get_release_info(args.version)
update_json_from_release(tmp_json_path, args.version, release_info)
print(f"Updating esptool version fields to {args.version}")
update_tools_dependencies(tmp_json_path, args.version)
shutil.move(tmp_json_path, json_path)
print(f"Done. JSON updated at {json_path}")
if __name__ == "__main__":
main()

View file

@ -15,7 +15,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ github.event.client_payload.branch }} ref: ${{ github.event.client_payload.branch }}
@ -32,13 +32,13 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ github.event.client_payload.branch }} ref: ${{ github.event.client_payload.branch }}
- run: npm install - run: npm install
- name: Setup jq - name: Setup jq
uses: dcarbone/install-jq-action@v1.0.1 uses: dcarbone/install-jq-action@e397bd87438d72198f81efd21f876461183d383a # v3.0.1
- id: set-test-chunks - id: set-test-chunks
name: Set Chunks name: Set Chunks
@ -64,7 +64,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ github.event.client_payload.branch }} ref: ${{ github.event.client_payload.branch }}
@ -74,7 +74,7 @@ jobs:
FQBN: ${{ toJSON(matrix.chunk) }} FQBN: ${{ toJSON(matrix.chunk) }}
- name: Compile sketch - name: Compile sketch
uses: P-R-O-C-H-Y/compile-sketches@main uses: P-R-O-C-H-Y/compile-sketches@a62f069b92dc8f5053da4ac439ea6d1950cf6379 # main
with: with:
platforms: | platforms: |
${{ env.REPOSITORY }} ${{ env.REPOSITORY }}

View file

@ -22,10 +22,10 @@ jobs:
steps: steps:
# This step makes the contents of the repository available to the workflow # This step makes the contents of the repository available to the workflow
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup jq - name: Setup jq
uses: dcarbone/install-jq-action@v1.0.1 uses: dcarbone/install-jq-action@e397bd87438d72198f81efd21f876461183d383a # v3.0.1
- name: Get board name - name: Get board name
run: bash .github/scripts/find_new_boards.sh ${{ github.repository }} ${{github.base_ref}} run: bash .github/scripts/find_new_boards.sh ${{ github.repository }} ${{github.base_ref}}
@ -47,7 +47,7 @@ jobs:
steps: steps:
# This step makes the contents of the repository available to the workflow # This step makes the contents of the repository available to the workflow
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Check if build.board is uppercase - name: Check if build.board is uppercase
run: | run: |
@ -60,7 +60,7 @@ jobs:
fi fi
- name: Get libs cache - name: Get libs cache
uses: actions/cache@v4 uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with: with:
key: libs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package/package_esp32_index.template.json', 'tools/get.py') }} key: libs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package/package_esp32_index.template.json', 'tools/get.py') }}
path: | path: |
@ -73,7 +73,7 @@ jobs:
./tools/xtensa-* ./tools/xtensa-*
- name: Compile sketch - name: Compile sketch
uses: P-R-O-C-H-Y/compile-sketches@main uses: P-R-O-C-H-Y/compile-sketches@a62f069b92dc8f5053da4ac439ea6d1950cf6379 # main
with: with:
platforms: | platforms: |
${{ env.REPOSITORY }} ${{ env.REPOSITORY }}

View file

@ -12,13 +12,13 @@ on:
jobs: jobs:
find-changed-tools: find-changed-tools:
name: Check if tools have been changed name: Check if tools have been changed
runs-on: ubuntu-20.04 runs-on: ubuntu-latest
outputs: outputs:
any_changed: ${{ steps.verify-changed-files.outputs.any_changed }} any_changed: ${{ steps.verify-changed-files.outputs.any_changed }}
all_changed_files: ${{ steps.verify-changed-files.outputs.all_changed_files }} all_changed_files: ${{ steps.verify-changed-files.outputs.all_changed_files }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
fetch-depth: 2 fetch-depth: 2
ref: ${{ github.event.pull_request.head.ref }} ref: ${{ github.event.pull_request.head.ref }}
@ -30,7 +30,7 @@ jobs:
echo "Make sure you are using a branch inside the repository and not a fork." echo "Make sure you are using a branch inside the repository and not a fork."
- name: Verify Python Tools Changed - name: Verify Python Tools Changed
uses: tj-actions/changed-files@v41 uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
id: verify-changed-files id: verify-changed-files
with: with:
fetch_depth: "2" fetch_depth: "2"
@ -40,6 +40,7 @@ jobs:
tools/espota.py tools/espota.py
tools/gen_esp32part.py tools/gen_esp32part.py
tools/gen_insights_package.py tools/gen_insights_package.py
- name: List all changed files - name: List all changed files
shell: bash shell: bash
run: | run: |
@ -55,7 +56,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [windows-latest, macos-latest, ubuntu-20.04, ARM] os: [windows-latest, macos-latest, ubuntu-latest, ubuntu-24.04-arm]
include: include:
- os: windows-latest - os: windows-latest
TARGET: win64 TARGET: win64
@ -64,14 +65,12 @@ jobs:
- os: macos-latest - os: macos-latest
TARGET: macos TARGET: macos
SEPARATOR: ":" SEPARATOR: ":"
- os: ubuntu-20.04 - os: ubuntu-latest
TARGET: linux-amd64 TARGET: linux-amd64
SEPARATOR: ":" SEPARATOR: ":"
- os: ARM - os: ubuntu-24.04-arm
CONTAINER: python:3.8-bullseye
TARGET: arm TARGET: arm
SEPARATOR: ":" SEPARATOR: ":"
container: ${{ matrix.CONTAINER }} # use python container on ARM
env: env:
DISTPATH: pytools-${{ matrix.TARGET }} DISTPATH: pytools-${{ matrix.TARGET }}
PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi" PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi"
@ -90,27 +89,30 @@ jobs:
for tool in ${{ env.CHANGED_TOOLS }}; do for tool in ${{ env.CHANGED_TOOLS }}; do
echo "tool $tool was changed" echo "tool $tool was changed"
done done
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
token: ${{ secrets.TOOLS_UPLOAD_PAT }} token: ${{ secrets.TOOLS_UPLOAD_PAT }}
ref: ${{ github.event.pull_request.head.ref }} ref: ${{ github.event.pull_request.head.ref }}
- name: Set up Python 3.8 - name: Set up Python 3.8
# Skip setting python on ARM because of missing compatibility: https://github.com/actions/setup-python/issues/108 uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
if: matrix.os != 'ARM'
uses: actions/setup-python@master
with: with:
python-version: 3.8 python-version: 3.8
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install pyinstaller requests pip install pyinstaller requests
- name: Build with PyInstaller - name: Build with PyInstaller
shell: bash shell: bash
run: | run: |
for tool in ${{ env.CHANGED_TOOLS }}; do for tool in ${{ env.CHANGED_TOOLS }}; do
pyinstaller --distpath ./${{ env.DISTPATH }} -F --icon=.github/pytools/espressif.ico tools/$tool.py pyinstaller --distpath ./${{ env.DISTPATH }} -F --icon=.github/pytools/espressif.ico tools/$tool.py
done done
- name: Sign binaries - name: Sign binaries
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
env: env:
@ -123,12 +125,14 @@ jobs:
{ {
./.github/pytools/Sign-File.ps1 -Path ./${{ env.DISTPATH }}/$node.exe ./.github/pytools/Sign-File.ps1 -Path ./${{ env.DISTPATH }}/$node.exe
} }
- name: Test binaries - name: Test binaries
shell: bash shell: bash
run: | run: |
for tool in ${{ env.CHANGED_TOOLS }}; do for tool in ${{ env.CHANGED_TOOLS }}; do
./${{ env.DISTPATH }}/$tool${{ matrix.EXTEN }} -h ./${{ env.DISTPATH }}/$tool${{ matrix.EXTEN }} -h
done done
- name: Push binary to tools - name: Push binary to tools
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
env: env:
@ -139,8 +143,9 @@ jobs:
cp -f ./${{ env.DISTPATH }}/$tool.exe tools/$tool.exe cp -f ./${{ env.DISTPATH }}/$tool.exe tools/$tool.exe
done done
bash .github/scripts/upload_py_tools.sh "${{ env.CHANGED_TOOLS }}" bash .github/scripts/upload_py_tools.sh "${{ env.CHANGED_TOOLS }}"
- name: Archive artifact - name: Archive artifact
uses: actions/upload-artifact@master uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: ${{ env.DISTPATH }} name: ${{ env.DISTPATH }}
path: ${{ env.DISTPATH }} path: ${{ env.DISTPATH }}

31
.github/workflows/codeql_actions.yml vendored Normal file
View file

@ -0,0 +1,31 @@
name: CodeQL Actions Analysis
on:
workflow_dispatch:
push:
branches:
- master
pull_request:
paths:
- ".github/workflows/*.yml"
- ".github/workflows/*.yaml"
jobs:
codeql-analysis:
name: CodeQL Actions Analysis
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Initialize CodeQL
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
languages: actions
config-file: ./.github/codeql/codeql-config.yml
- name: Run CodeQL Analysis
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
category: "Analysis: Actions"

30
.github/workflows/codeql_python.yml vendored Normal file
View file

@ -0,0 +1,30 @@
name: CodeQL Python Analysis
on:
workflow_dispatch:
push:
branches:
- master
pull_request:
paths:
- "**/*.py"
jobs:
codeql-analysis:
name: CodeQL Python Analysis
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Initialize CodeQL
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
languages: python
config-file: ./.github/codeql/codeql-config.yml
- name: Run CodeQL Analysis
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
category: "Analysis: Python"

View file

@ -12,16 +12,17 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out PR head - name: Check out PR head
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: DangerJS pull request linter - name: DangerJS pull request linter
uses: espressif/shared-github-dangerjs@v1 uses: espressif/shared-github-dangerjs@fb17367fd3e8ff7412603b8e946d9b19ffdb2d7f # v1
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
instructions-cla-link: "https://cla-assistant.io/espressif/arduino-esp32" instructions-cla-link: "https://cla-assistant.io/espressif/arduino-esp32"
instructions-contributions-file: "docs/en/contributing.rst" instructions-contributions-file: "docs/en/contributing.rst"
rule-max-commits: "false" rule-max-commits: "false"
rule-target-branch: "false"
commit-messages-min-summary-length: "10" commit-messages-min-summary-length: "10"

View file

@ -21,14 +21,16 @@ jobs:
run: run:
shell: bash shell: bash
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
submodules: true submodules: true
- uses: actions/setup-python@v5
- uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
with: with:
cache-dependency-path: docs/requirements.txt cache-dependency-path: docs/requirements.txt
cache: "pip" cache: "pip"
python-version: "3.10" python-version: "3.10"
- name: Build - name: Build
run: | run: |
sudo apt update sudo apt update
@ -38,8 +40,9 @@ jobs:
cd ./docs cd ./docs
PATH=/home/runner/.local/bin:$PATH pip3 install -r requirements.txt --prefer-binary PATH=/home/runner/.local/bin:$PATH pip3 install -r requirements.txt --prefer-binary
PATH=/home/runner/.local/bin:$PATH SPHINXOPTS="-W" build-docs -l en PATH=/home/runner/.local/bin:$PATH SPHINXOPTS="-W" build-docs -l en
- name: Archive Docs - name: Archive Docs
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: docs name: docs
path: docs path: docs

View file

@ -26,14 +26,17 @@ jobs:
run: | run: |
echo "Release workflow failed. Exiting..." echo "Release workflow failed. Exiting..."
exit 1 exit 1
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
submodules: true submodules: true
- uses: actions/setup-python@v5
- uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
with: with:
cache-dependency-path: docs/requirements.txt cache-dependency-path: docs/requirements.txt
cache: "pip" cache: "pip"
python-version: "3.10" python-version: "3.10"
- name: Deploy Documentation - name: Deploy Documentation
env: env:
# Deploy to production server # Deploy to production server

View file

@ -15,7 +15,9 @@ jobs:
name: Build GitHub Pages name: Build GitHub Pages
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Copy Files - name: Copy Files
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -9,7 +9,8 @@
{ {
"name": "ArduinoBLE", "name": "ArduinoBLE",
"exclude_targets": [ "exclude_targets": [
"esp32s2" "esp32s2",
"esp32p4"
], ],
"sketch_path": [ "sketch_path": [
"~/Arduino/libraries/ArduinoBLE/examples/Central/Scan/Scan.ino" "~/Arduino/libraries/ArduinoBLE/examples/Central/Scan/Scan.ino"
@ -23,16 +24,44 @@
] ]
}, },
{ {
"source-url": "https://github.com/me-no-dev/ESPAsyncWebServer.git", "source-url": "https://github.com/ESP32Async/ESPAsyncWebServer.git",
"required-libs": [ "required-libs": [
{"source-url": "https://github.com/me-no-dev/AsyncTCP.git"} {"source-url": "https://github.com/ESP32Async/AsyncTCP.git"}
], ],
"exclude_targets": [], "exclude_targets": [],
"sketch_path": [ "sketch_path": [
"~/Arduino/libraries/ESPAsyncWebServer/examples/Auth/Auth.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/CORS/CORS.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/CaptivePortal/CaptivePortal.ino", "~/Arduino/libraries/ESPAsyncWebServer/examples/CaptivePortal/CaptivePortal.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino", "~/Arduino/libraries/ESPAsyncWebServer/examples/CatchAllHandler/CatchAllHandler.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/regex_patterns/regex_patterns.ino", "~/Arduino/libraries/ESPAsyncWebServer/examples/ChunkResponse/ChunkResponse.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/simple_server/simple_server.ino" "~/Arduino/libraries/ESPAsyncWebServer/examples/ChunkRetryResponse/ChunkRetryResponse.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/EndBegin/EndBegin.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Filters/Filters.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/FlashResponse/FlashResponse.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/HeaderManipulation/HeaderManipulation.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Headers/Headers.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Json/Json.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Logging/Logging.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/MessagePack/MessagePack.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Middleware/Middleware.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Params/Params.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/PartitionDownloader/PartitionDownloader.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/PerfTests/PerfTests.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/RateLimit/RateLimit.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Redirect/Redirect.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/RequestContinuation/RequestContinuation.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/RequestContinuationComplete/RequestContinuationComplete.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/ResumableDownload/ResumableDownload.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Rewrite/Rewrite.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/ServerSentEvents/ServerSentEvents.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/ServerState/ServerState.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/SkipServerMiddleware/SkipServerMiddleware.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/SlowChunkResponse/SlowChunkResponse.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/StaticFile/StaticFile.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Templates/Templates.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/Upload/Upload.ino",
"~/Arduino/libraries/ESPAsyncWebServer/examples/WebSocket/WebSocket.ino"
] ]
}, },
{ {

View file

@ -62,10 +62,10 @@ jobs:
steps: steps:
# This step makes the contents of the repository available to the workflow # This step makes the contents of the repository available to the workflow
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Compile sketch - name: Compile sketch
uses: P-R-O-C-H-Y/compile-sketches@main uses: P-R-O-C-H-Y/compile-sketches@a62f069b92dc8f5053da4ac439ea6d1950cf6379 # main
with: with:
platforms: | platforms: |
${{ env.REPOSITORY }} ${{ env.REPOSITORY }}
@ -80,7 +80,7 @@ jobs:
- --warnings="all" - --warnings="all"
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: ${{ env.SKETCHES_REPORTS_ARTIFACT_NAME }}-${{ matrix.target }} name: ${{ env.SKETCHES_REPORTS_ARTIFACT_NAME }}-${{ matrix.target }}
path: ${{ env.SKETCHES_REPORTS_PATH }} path: ${{ env.SKETCHES_REPORTS_PATH }}
@ -92,7 +92,7 @@ jobs:
steps: steps:
# Check out repository # Check out repository
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
token: ${{ env.GITHUB_TOKEN }} token: ${{ env.GITHUB_TOKEN }}
fetch-depth: "0" fetch-depth: "0"
@ -102,14 +102,14 @@ jobs:
# This step is needed to get the size data produced by the compile jobs # This step is needed to get the size data produced by the compile jobs
- name: Download sketches reports artifact - name: Download sketches reports artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with: with:
pattern: ${{ env.SKETCHES_REPORTS_ARTIFACT_NAME }}-* pattern: ${{ env.SKETCHES_REPORTS_ARTIFACT_NAME }}-*
merge-multiple: true merge-multiple: true
path: ${{ env.SKETCHES_REPORTS_PATH }} path: ${{ env.SKETCHES_REPORTS_PATH }}
- name: Report results - name: Report results
uses: P-R-O-C-H-Y/report-size-deltas@main uses: P-R-O-C-H-Y/report-size-deltas@4a79caa6dcc3579024293638b97156106edc588e # main
with: with:
sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }} sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }}
destination-file: ${{ env.RESULT_LIBRARY_TEST_FILE }} destination-file: ${{ env.RESULT_LIBRARY_TEST_FILE }}
@ -136,8 +136,9 @@ jobs:
env: env:
PR_NUM: ${{ github.event.number }} PR_NUM: ${{ github.event.number }}
run: echo $PR_NUM > pr_num.txt run: echo $PR_NUM > pr_num.txt
- name: Upload PR number - name: Upload PR number
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: pr_number name: pr_number
path: ./pr_num.txt path: ./pr_num.txt

View file

@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Report success - name: Report success
uses: actions/github-script@v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
script: | script: |
const owner = '${{ github.repository_owner }}'; const owner = '${{ github.repository_owner }}';
@ -43,7 +43,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Report pending - name: Report pending
uses: actions/github-script@v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
script: | script: |
const owner = '${{ github.repository_owner }}'; const owner = '${{ github.repository_owner }}';

View file

@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout latest commit - name: Checkout latest commit
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
fetch-depth: 2 fetch-depth: 2
@ -34,7 +34,7 @@ jobs:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
- name: Set up Python 3 - name: Set up Python 3
uses: actions/setup-python@v5 uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
with: with:
cache-dependency-path: tools/pre-commit/requirements.txt cache-dependency-path: tools/pre-commit/requirements.txt
cache: "pip" cache: "pip"
@ -46,7 +46,7 @@ jobs:
echo "PY_HASH=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV echo "PY_HASH=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
- name: Restore pre-commit cache - name: Restore pre-commit cache
uses: actions/cache/restore@v4 uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: restore-cache id: restore-cache
with: with:
path: | path: |
@ -58,13 +58,13 @@ jobs:
- name: Get changed files - name: Get changed files
id: changed-files id: changed-files
uses: tj-actions/changed-files@v42.0.2 uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
- name: Run pre-commit hooks in changed files - name: Run pre-commit hooks in changed files
run: pre-commit run --color=always --show-diff-on-failure --files ${{ steps.changed-files.outputs.all_changed_files }} run: pre-commit run --color=always --show-diff-on-failure --files ${{ steps.changed-files.outputs.all_changed_files }}
- name: Save pre-commit cache - name: Save pre-commit cache
uses: actions/cache/save@v4 uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
if: ${{ always() && steps.restore-cache.outputs.cache-hit != 'true' }} if: ${{ always() && steps.restore-cache.outputs.cache-hit != 'true' }}
continue-on-error: true continue-on-error: true
with: with:
@ -73,7 +73,7 @@ jobs:
key: ${{ steps.restore-cache.outputs.cache-primary-key }} key: ${{ steps.restore-cache.outputs.cache-primary-key }}
- name: Push changes using pre-commit-ci-lite - name: Push changes using pre-commit-ci-lite
uses: pre-commit-ci/lite-action@v1.1.0 uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
# Only push changes in PRs # Only push changes in PRs
if: ${{ always() && github.event_name == 'pull_request' }} if: ${{ always() && github.event_name == 'pull_request' }}
with: with:

View file

@ -44,12 +44,12 @@ jobs:
- name: Read the pr_num file - name: Read the pr_num file
id: pr_num_reader id: pr_num_reader
uses: juliangruber/read-file-action@v1 uses: juliangruber/read-file-action@b549046febe0fe86f8cb4f93c24e284433f9ab58 # v1.1.7
with: with:
path: ./artifacts/workflows/pr_num.txt path: ./artifacts/workflows/pr_num.txt
- name: Report results - name: Report results
uses: P-R-O-C-H-Y/report-size-deltas@libs uses: P-R-O-C-H-Y/report-size-deltas@256d1f13e4195cd7fd436d2f959e6dc4d5e4b406 # libs
with: with:
sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }} sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }}
github-token: ${{ env.GITHUB_TOKEN }} github-token: ${{ env.GITHUB_TOKEN }}

View file

@ -14,8 +14,8 @@ jobs:
name: Sizes Comparison Results name: Sizes Comparison Results
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout gh-pages branch
uses: actions/checkout@v4 # This step checks out the repository's code at gh-pages branch uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: gh-pages ref: gh-pages
@ -34,7 +34,7 @@ jobs:
mv v2.x_cli_compile/*.json artifacts/sizes-report/master/ mv v2.x_cli_compile/*.json artifacts/sizes-report/master/
- name: Report results - name: Report results
uses: P-R-O-C-H-Y/report-size-deltas@sizes_v2 uses: P-R-O-C-H-Y/report-size-deltas@2043188c68f483a7b50527c4eacf609d05bb67a5 # sizes_v2
with: with:
sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }} sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }}
github-token: ${{ env.GITHUB_TOKEN }} github-token: ${{ env.GITHUB_TOKEN }}

View file

@ -21,8 +21,8 @@ jobs:
github.event.workflow_run.conclusion == 'success' github.event.workflow_run.conclusion == 'success'
steps: steps:
- name: Checkout code - name: Checkout gh-pages branch
uses: actions/checkout@v4 # This step checks out the repository's code at gh-pages branch uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: gh-pages ref: gh-pages
@ -44,28 +44,29 @@ jobs:
gh api "$artifacts_url" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact gh api "$artifacts_url" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact
do do
IFS=$'\t' read name url <<< "$artifact" IFS=$'\t' read name url <<< "$artifact"
# Only process pr_number and pr_cli_compile artifacts
if [[ "$name" == "pr_number" || "$name" =~ ^pr_cli_compile_[0-9]+$ ]]; then
gh api $url > "$name.zip" gh api $url > "$name.zip"
unzip -j "$name.zip" -d "temp_$name" unzip -o -j "$name.zip" -d "temp_$name"
if [[ "$name" == "pr_number" ]]; then if [[ "$name" == "pr_number" ]]; then
mv "temp_$name"/* sizes-report mv "temp_$name"/* sizes-report
elif [[ "$name" == "pr_cli"* ]]; then elif [[ "$name" =~ ^pr_cli_compile_[0-9]+$ ]]; then
mv "temp_$name"/* sizes-report/pr mv "temp_$name"/* sizes-report/pr
else
mv "temp_$name"/* sizes-report
fi fi
rm -r "temp_$name" rm -r "temp_$name"
fi
done done
echo "Contents of parent directory:" echo "Contents of parent directory:"
ls -R .. ls -R ..
- name: Read the pr_num file - name: Read the pr_num file
id: pr_num_reader id: pr_num_reader
uses: juliangruber/read-file-action@v1 uses: juliangruber/read-file-action@b549046febe0fe86f8cb4f93c24e284433f9ab58 # v1.1.7
with: with:
path: ./artifacts/sizes-report/pr_num.txt path: ./artifacts/sizes-report/pr_num.txt
- name: Report results - name: Report results
uses: P-R-O-C-H-Y/report-size-deltas@sizes_v2 uses: P-R-O-C-H-Y/report-size-deltas@bea91d2c99ca80c88a883b39b1c4012f00ec3d09 # sizes_v2
with: with:
sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }} sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }}
github-token: ${{ env.GITHUB_TOKEN }} github-token: ${{ env.GITHUB_TOKEN }}

View file

@ -31,6 +31,7 @@ on:
- "!libraries/**.properties" - "!libraries/**.properties"
- "!libraries/**.py" - "!libraries/**.py"
- "package/**" - "package/**"
- "idf_component_examples/**"
- "tools/**.py" - "tools/**.py"
- "platform.txt" - "platform.txt"
- "programmers.txt" - "programmers.txt"
@ -45,12 +46,13 @@ on:
- "!.github/scripts/tests_*" - "!.github/scripts/tests_*"
- "!.github/scripts/upload_*" - "!.github/scripts/upload_*"
- "variants/esp32/**/*" - "variants/esp32/**/*"
- "variants/esp32s2/**/*"
- "variants/esp32s3/**/*"
- "variants/esp32c2/**/*"
- "variants/esp32c3/**/*" - "variants/esp32c3/**/*"
- "variants/esp32c5/**/*"
- "variants/esp32c6/**/*" - "variants/esp32c6/**/*"
- "variants/esp32h2/**/*" - "variants/esp32h2/**/*"
- "variants/esp32p4/**/*"
- "variants/esp32s2/**/*"
- "variants/esp32s3/**/*"
concurrency: concurrency:
group: build-${{github.event.pull_request.number || github.ref}} group: build-${{github.event.pull_request.number || github.ref}}
@ -65,7 +67,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ !(github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/')) }} if: ${{ !(github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/')) }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- run: bash ./.github/scripts/check-cmakelists.sh - run: bash ./.github/scripts/check-cmakelists.sh
gen-chunks: gen-chunks:
@ -81,13 +83,13 @@ jobs:
chunks: ${{ steps.set-chunks.outputs.chunks }} chunks: ${{ steps.set-chunks.outputs.chunks }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
fetch-depth: 2 fetch-depth: 2
- name: Get changed files - name: Get changed files
id: changed-files id: changed-files
uses: tj-actions/changed-files@v44 uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
with: with:
files_yaml: | files_yaml: |
core: core:
@ -98,11 +100,12 @@ jobs:
- 'platform.txt' - 'platform.txt'
- 'programmers.txt' - 'programmers.txt'
- "variants/esp32/**/*" - "variants/esp32/**/*"
- "variants/esp32s2/**/*"
- "variants/esp32s3/**/*"
- "variants/esp32c3/**/*" - "variants/esp32c3/**/*"
- "variants/esp32c6/**/*" - "variants/esp32c6/**/*"
- "variants/esp32h2/**/*" - "variants/esp32h2/**/*"
- "variants/esp32p4/**/*"
- "variants/esp32s2/**/*"
- "variants/esp32s3/**/*"
libraries: libraries:
- 'libraries/**/examples/**' - 'libraries/**/examples/**'
- 'libraries/**/src/**' - 'libraries/**/src/**'
@ -122,7 +125,7 @@ jobs:
- 'idf_component.yml' - 'idf_component.yml'
- 'Kconfig.projbuild' - 'Kconfig.projbuild'
- 'CMakeLists.txt' - 'CMakeLists.txt'
- "variants/esp32c2/**/*" - "idf_component_examples/**"
- name: Set chunks - name: Set chunks
id: set-chunks id: set-chunks
@ -142,7 +145,7 @@ jobs:
- name: Upload sketches found - name: Upload sketches found
if: ${{ steps.set-chunks.outputs.build_all == 'false' && steps.set-chunks.outputs.build_libraries == 'true' }} if: ${{ steps.set-chunks.outputs.build_all == 'false' && steps.set-chunks.outputs.build_libraries == 'true' }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: sketches_found name: sketches_found
path: sketches_found.txt path: sketches_found.txt
@ -161,13 +164,13 @@ jobs:
chunk: ${{ fromJson(needs.gen-chunks.outputs.chunks) }} chunk: ${{ fromJson(needs.gen-chunks.outputs.chunks) }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@v5 - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
with: with:
python-version: "3.x" python-version: "3.x"
- name: Get libs cache - name: Get libs cache
uses: actions/cache@v4 uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with: with:
key: libs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package/package_esp32_index.template.json', 'tools/get.py') }} key: libs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package/package_esp32_index.template.json', 'tools/get.py') }}
path: | path: |
@ -195,7 +198,7 @@ jobs:
- name: Download sketches found - name: Download sketches found
if: ${{ needs.gen-chunks.outputs.build_all == 'false' && needs.gen-chunks.outputs.build_libraries == 'true' }} if: ${{ needs.gen-chunks.outputs.build_all == 'false' && needs.gen-chunks.outputs.build_libraries == 'true' }}
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with: with:
name: sketches_found name: sketches_found
@ -205,7 +208,7 @@ jobs:
#Upload cli compile json as artifact #Upload cli compile json as artifact
- name: Upload cli compile json - name: Upload cli compile json
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: pr_cli_compile_${{ matrix.chunk }} name: pr_cli_compile_${{ matrix.chunk }}
path: cli_compile_${{ matrix.chunk }}.json path: cli_compile_${{ matrix.chunk }}.json
@ -223,8 +226,8 @@ jobs:
os: [windows-latest, macOS-latest] os: [windows-latest, macOS-latest]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@v5 - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
with: with:
python-version: "3.x" python-version: "3.x"
- name: Build Sketches - name: Build Sketches
@ -237,7 +240,7 @@ jobs:
needs.gen-chunks.outputs.build_all == 'true' || needs.gen-chunks.outputs.build_all == 'true' ||
needs.gen-chunks.outputs.build_libraries == 'true' || needs.gen-chunks.outputs.build_libraries == 'true' ||
needs.gen-chunks.outputs.build_idf == 'true' needs.gen-chunks.outputs.build_idf == 'true'
runs-on: ubuntu-20.04 runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -245,7 +248,7 @@ jobs:
# See https://hub.docker.com/r/espressif/idf/tags and # See https://hub.docker.com/r/espressif/idf/tags and
# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html
# for details. # for details.
idf_ver: ["release-v5.3"] idf_ver: ["release-v5.3","release-v5.4","release-v5.5"]
idf_target: idf_target:
[ [
"esp32", "esp32",
@ -260,19 +263,28 @@ jobs:
container: espressif/idf:${{ matrix.idf_ver }} container: espressif/idf:${{ matrix.idf_ver }}
steps: steps:
- name: Check out arduino-esp32 as a component - name: Check out arduino-esp32 as a component
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
submodules: recursive submodules: recursive
path: components/arduino-esp32 path: components/arduino-esp32
- name: Setup jq
uses: dcarbone/install-jq-action@e397bd87438d72198f81efd21f876461183d383a # v3.0.1
- name: Build - name: Build
env: env:
IDF_TARGET: ${{ matrix.idf_target }} IDF_TARGET: ${{ matrix.idf_target }}
shell: bash shell: bash
run: | run: |
. ${IDF_PATH}/export.sh chmod a+x ./components/arduino-esp32/.github/scripts/*
idf.py create-project test ./components/arduino-esp32/.github/scripts/on-push-idf.sh
echo CONFIG_FREERTOS_HZ=1000 > test/sdkconfig.defaults
idf.py -C test -DEXTRA_COMPONENT_DIRS=$PWD/components build - name: Upload generated sdkconfig files for debugging
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
with:
name: sdkconfig-${{ matrix.idf_ver }}-${{ matrix.idf_target }}
path: ./components/arduino-esp32/idf_component_examples/**/sdkconfig
# Save artifacts to gh-pages # Save artifacts to gh-pages
save-master-artifacts: save-master-artifacts:
@ -283,7 +295,7 @@ jobs:
steps: steps:
# Check out repository # Check out repository
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
token: ${{secrets.GITHUB_TOKEN}} token: ${{secrets.GITHUB_TOKEN}}
fetch-depth: "0" fetch-depth: "0"
@ -292,7 +304,7 @@ jobs:
run: git checkout remotes/origin/gh-pages run: git checkout remotes/origin/gh-pages
- name: Download sketches reports artifact - name: Download sketches reports artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with: with:
pattern: pr_cli_compile_* pattern: pr_cli_compile_*
merge-multiple: true merge-multiple: true
@ -322,8 +334,9 @@ jobs:
env: env:
PR_NUM: ${{ github.event.number }} PR_NUM: ${{ github.event.number }}
run: echo $PR_NUM > pr_num.txt run: echo $PR_NUM > pr_num.txt
- name: Upload PR number - name: Upload PR number
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: pr_number name: pr_number
path: ./pr_num.txt path: ./pr_num.txt

View file

@ -10,14 +10,22 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-python@v5
- name: Set up Python
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
with: with:
python-version: "3.x" python-version: "3.x"
- run: pip install packaging
- run: pip install pyserial - name: Install packaging
run: pip install packaging
- name: Install pyserial
run: pip install pyserial
- name: Build Release - name: Build Release
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -43,7 +43,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Upload - name: Upload
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: event_file name: event_file
path: ${{ github.event_path }} path: ${{ github.event_path }}
@ -62,7 +62,7 @@ jobs:
PERFORMANCE_ENABLED: ${{ contains(github.event.pull_request.labels.*.name, 'perf_test') }} PERFORMANCE_ENABLED: ${{ contains(github.event.pull_request.labels.*.name, 'perf_test') }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
sparse-checkout: .github/scripts/tests_matrix.sh sparse-checkout: .github/scripts/tests_matrix.sh
@ -71,7 +71,7 @@ jobs:
run: bash .github/scripts/tests_matrix.sh run: bash .github/scripts/tests_matrix.sh
- name: Upload - name: Upload
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: matrix_info name: matrix_info
path: info/* path: info/*

View file

@ -22,14 +22,14 @@ jobs:
- name: Check if already built - name: Check if already built
id: cache-build-binaries id: cache-build-binaries
if: github.event.pull_request.number != null if: github.event.pull_request.number != null
uses: actions/cache/restore@v4 uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with: with:
key: tests-${{ env.id }}-bin key: tests-${{ env.id }}-bin
path: | path: |
~/.arduino/tests/**/build*.tmp/*.bin ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.bin
~/.arduino/tests/**/build*.tmp/*.elf ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.elf
~/.arduino/tests/**/build*.tmp/*.json ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.json
~/.arduino/tests/**/build*.tmp/sdkconfig ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/sdkconfig
- name: Evaluate if tests should be built - name: Evaluate if tests should be built
id: check-build id: check-build
@ -46,10 +46,10 @@ jobs:
- name: Checkout user repository - name: Checkout user repository
if: ${{ steps.check-build.outputs.enabled == 'true' }} if: ${{ steps.check-build.outputs.enabled == 'true' }}
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get libs cache - name: Get libs cache
uses: actions/cache@v4 uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
if: ${{ steps.check-build.outputs.enabled == 'true' }} if: ${{ steps.check-build.outputs.enabled == 'true' }}
with: with:
key: libs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package/package_esp32_index.template.json', 'tools/get.py') }} key: libs-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package/package_esp32_index.template.json', 'tools/get.py') }}
@ -68,23 +68,23 @@ jobs:
bash .github/scripts/tests_build.sh -c -type ${{ inputs.type }} -t ${{ inputs.chip }} bash .github/scripts/tests_build.sh -c -type ${{ inputs.type }} -t ${{ inputs.chip }}
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} binaries as cache - name: Upload ${{ inputs.chip }} ${{ inputs.type }} binaries as cache
uses: actions/cache/save@v4 uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
if: steps.check-build.outputs.enabled == 'true' && github.event.pull_request.number != null if: steps.check-build.outputs.enabled == 'true' && github.event.pull_request.number != null
with: with:
key: tests-${{ env.id }}-bin key: tests-${{ env.id }}-bin
path: | path: |
~/.arduino/tests/**/build*.tmp/*.bin ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.bin
~/.arduino/tests/**/build*.tmp/*.elf ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.elf
~/.arduino/tests/**/build*.tmp/*.json ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.json
~/.arduino/tests/**/build*.tmp/sdkconfig ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/sdkconfig
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} binaries as artifacts - name: Upload ${{ inputs.chip }} ${{ inputs.type }} binaries as artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: tests-bin-${{ inputs.chip }}-${{ inputs.type }} name: tests-bin-${{ inputs.chip }}-${{ inputs.type }}
overwrite: true overwrite: true
path: | path: |
~/.arduino/tests/**/build*.tmp/*.bin ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.bin
~/.arduino/tests/**/build*.tmp/*.elf ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.elf
~/.arduino/tests/**/build*.tmp/*.json ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.json
~/.arduino/tests/**/build*.tmp/sdkconfig ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/sdkconfig

View file

@ -22,17 +22,22 @@ defaults:
jobs: jobs:
hardware-test: hardware-test:
name: Hardware ${{ inputs.chip }} ${{ inputs.type }} tests name: Hardware ${{ inputs.chip }} ${{ inputs.type }} tests
runs-on: [arduino, "${{ inputs.chip }}"] runs-on: ["arduino", "${{ inputs.chip }}"]
env: env:
id: ${{ github.event.pull_request.number || github.ref }}-${{ github.event.pull_request.head.sha || github.sha }}-${{ inputs.chip }}-${{ inputs.type }} id: ${{ github.event.pull_request.number || github.ref }}-${{ github.event.pull_request.head.sha || github.sha }}-${{ inputs.chip }}-${{ inputs.type }}
container: container:
image: python:3.10.1-bullseye image: python:3.10.1-bullseye
options: --privileged options: --privileged --device-cgroup-rule="c 188:* rmw" --device-cgroup-rule="c 166:* rmw"
steps: steps:
- name: Clean workspace
run: |
rm -rf ./*
rm -rf ~/.arduino/tests
- name: Check if already passed - name: Check if already passed
id: cache-results id: cache-results
if: github.event.pull_request.number != null if: github.event.pull_request.number != null
uses: actions/cache/restore@v4 uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with: with:
key: tests-${{ env.id }}-results-hw key: tests-${{ env.id }}-results-hw
path: | path: |
@ -54,13 +59,13 @@ jobs:
- name: Checkout user repository - name: Checkout user repository
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
sparse-checkout: | sparse-checkout: |
* *
# setup-python currently only works on ubuntu images # setup-python currently only works on ubuntu images
# - uses: actions/setup-python@v5 # - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
# if: ${{ steps.check-tests.outputs.enabled == 'true' }} # if: ${{ steps.check-tests.outputs.enabled == 'true' }}
# with: # with:
# cache-dependency-path: tests/requirements.txt # cache-dependency-path: tests/requirements.txt
@ -77,11 +82,16 @@ jobs:
- name: Get binaries - name: Get binaries
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with: with:
name: tests-bin-${{ inputs.chip }}-${{ inputs.type }} name: tests-bin-${{ inputs.chip }}-${{ inputs.type }}
path: | path: |
~/.arduino/tests ~/.arduino/tests/${{ inputs.chip }}
- name: List binaries
if: ${{ steps.check-tests.outputs.enabled == 'true' }}
run: |
ls -laR ~/.arduino/tests
- name: Run Tests - name: Run Tests
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
@ -89,7 +99,7 @@ jobs:
bash .github/scripts/tests_run.sh -c -type ${{ inputs.type }} -t ${{ inputs.chip }} -i 0 -m 1 -e bash .github/scripts/tests_run.sh -c -type ${{ inputs.type }} -t ${{ inputs.chip }} -i 0 -m 1 -e
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} hardware results as cache - name: Upload ${{ inputs.chip }} ${{ inputs.type }} hardware results as cache
uses: actions/cache/save@v4 uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
if: steps.check-tests.outputs.enabled == 'true' && github.event.pull_request.number != null if: steps.check-tests.outputs.enabled == 'true' && github.event.pull_request.number != null
with: with:
key: tests-${{ env.id }}-results-hw key: tests-${{ env.id }}-results-hw
@ -98,7 +108,7 @@ jobs:
tests/**/result_*.json tests/**/result_*.json
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} hardware results as artifacts - name: Upload ${{ inputs.chip }} ${{ inputs.type }} hardware results as artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always() if: always()
with: with:
name: tests-results-hw-${{ inputs.chip }}-${{ inputs.type }} name: tests-results-hw-${{ inputs.chip }}-${{ inputs.type }}

View file

@ -21,7 +21,7 @@ jobs:
- name: Check if already passed - name: Check if already passed
id: get-cache-results id: get-cache-results
if: github.event.pull_request.number != null if: github.event.pull_request.number != null
uses: actions/cache/restore@v4 uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with: with:
key: tests-${{ env.id }}-results-qemu key: tests-${{ env.id }}-results-qemu
path: | path: |
@ -43,7 +43,7 @@ jobs:
- name: Checkout user repository - name: Checkout user repository
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ github.event.pull_request.head.sha || github.sha }} ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false persist-credentials: false
@ -60,7 +60,7 @@ jobs:
cd .github cd .github
curl https://codeload.github.com/${{ github.repository }}/tar.gz/master | tar -xz --strip=2 arduino-esp32-master/.github curl https://codeload.github.com/${{ github.repository }}/tar.gz/master | tar -xz --strip=2 arduino-esp32-master/.github
- uses: actions/setup-python@v5 - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
with: with:
cache-dependency-path: tests/requirements.txt cache-dependency-path: tests/requirements.txt
@ -74,14 +74,14 @@ jobs:
pip install -r tests/requirements.txt --extra-index-url https://dl.espressif.com/pypi pip install -r tests/requirements.txt --extra-index-url https://dl.espressif.com/pypi
- name: Install APT dependencies - name: Install APT dependencies
uses: awalsh128/cache-apt-pkgs-action@v1.4.2 uses: awalsh128/cache-apt-pkgs-action@5902b33ae29014e6ca012c5d8025d4346556bd40 # v1.4.3
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
with: with:
packages: libpixman-1-0 libnuma1 libglib2.0-0 libslirp0 libsdl2-2.0-0 packages: libpixman-1-0 libnuma1 libglib2.0-0 libslirp0 libsdl2-2.0-0
version: 1.0 version: 1.0
- name: Get QEMU version - name: Get QEMU version
uses: pozetroninc/github-action-get-latest-release@v0.7.0 uses: pozetroninc/github-action-get-latest-release@2a61c339ea7ef0a336d1daa35ef0cb1418e7676c # v0.8.0
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
id: get-qemu-version id: get-qemu-version
with: with:
@ -92,7 +92,7 @@ jobs:
- name: Cache QEMU - name: Cache QEMU
id: cache-qemu id: cache-qemu
uses: actions/cache@v4 uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
with: with:
path: | path: |
@ -113,18 +113,18 @@ jobs:
- name: Get binaries - name: Get binaries
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with: with:
name: tests-bin-${{ inputs.chip }}-${{ inputs.type }} name: tests-bin-${{ inputs.chip }}-${{ inputs.type }}
path: | path: |
~/.arduino/tests ~/.arduino/tests/${{ inputs.chip }}
- name: Run Tests - name: Run Tests
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
run: QEMU_PATH="${{ env.QEMU_INSTALL_PATH }}" bash .github/scripts/tests_run.sh -c -type ${{inputs.type}} -t ${{inputs.chip}} -i 0 -m 1 -Q run: QEMU_PATH="${{ env.QEMU_INSTALL_PATH }}" bash .github/scripts/tests_run.sh -c -type ${{inputs.type}} -t ${{inputs.chip}} -i 0 -m 1 -Q
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} QEMU results as cache - name: Upload ${{ inputs.chip }} ${{ inputs.type }} QEMU results as cache
uses: actions/cache/save@v4 uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
if: steps.check-tests.outputs.enabled == 'true' && github.event.pull_request.number != null if: steps.check-tests.outputs.enabled == 'true' && github.event.pull_request.number != null
with: with:
key: tests-${{ env.id }}-results-qemu key: tests-${{ env.id }}-results-qemu
@ -133,7 +133,7 @@ jobs:
tests/**/result_*.json tests/**/result_*.json
- name: Upload ${{ inputs.chip }} ${{ inputs.type }} QEMU results as artifacts - name: Upload ${{ inputs.chip }} ${{ inputs.type }} QEMU results as artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always() if: always()
with: with:
name: tests-results-qemu-${{ inputs.chip }}-${{ inputs.type }} name: tests-results-qemu-${{ inputs.chip }}-${{ inputs.type }}

View file

@ -24,12 +24,12 @@ jobs:
pull-requests: write pull-requests: write
contents: write contents: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: gh-pages ref: gh-pages
- name: Download and Extract Artifacts - name: Download and Extract Artifacts
uses: dawidd6/action-download-artifact@v6 uses: dawidd6/action-download-artifact@07ab29fd4a977ae4d2b275087cf67563dfdf0295 # v9
with: with:
run_id: ${{ github.event.workflow_run.id }} run_id: ${{ github.event.workflow_run.id }}
path: ./artifacts path: ./artifacts
@ -41,6 +41,7 @@ jobs:
original_sha=$(cat ./artifacts/parent-artifacts/sha.txt) original_sha=$(cat ./artifacts/parent-artifacts/sha.txt)
original_ref=$(cat ./artifacts/parent-artifacts/ref.txt) original_ref=$(cat ./artifacts/parent-artifacts/ref.txt)
original_conclusion=$(cat ./artifacts/parent-artifacts/conclusion.txt) original_conclusion=$(cat ./artifacts/parent-artifacts/conclusion.txt)
original_run_id=$(cat ./artifacts/parent-artifacts/run_id.txt)
# Sanitize the values to avoid security issues # Sanitize the values to avoid security issues
@ -59,20 +60,30 @@ jobs:
# Conclusion: Allow alphabetical characters and underscores # Conclusion: Allow alphabetical characters and underscores
original_conclusion=$(echo "$original_conclusion" | tr -cd '[:alpha:]_') original_conclusion=$(echo "$original_conclusion" | tr -cd '[:alpha:]_')
# Run ID: Allow numeric characters
original_run_id=$(echo "$original_run_id" | tr -cd '[:digit:]')
echo "original_event=$original_event" >> $GITHUB_ENV echo "original_event=$original_event" >> $GITHUB_ENV
echo "original_action=$original_action" >> $GITHUB_ENV echo "original_action=$original_action" >> $GITHUB_ENV
echo "original_sha=$original_sha" >> $GITHUB_ENV echo "original_sha=$original_sha" >> $GITHUB_ENV
echo "original_ref=$original_ref" >> $GITHUB_ENV echo "original_ref=$original_ref" >> $GITHUB_ENV
echo "original_conclusion=$original_conclusion" >> $GITHUB_ENV echo "original_conclusion=$original_conclusion" >> $GITHUB_ENV
echo "original_run_id=$original_run_id" >> $GITHUB_ENV
echo "original_event = $original_event" echo "original_event = $original_event"
echo "original_action = $original_action" echo "original_action = $original_action"
echo "original_sha = $original_sha" echo "original_sha = $original_sha"
echo "original_ref = $original_ref" echo "original_ref = $original_ref"
echo "original_conclusion = $original_conclusion" echo "original_conclusion = $original_conclusion"
echo "original_run_id = $original_run_id"
- name: Print links to other runs
run: |
echo "Build, Hardware and QEMU tests: https://github.com/${{ github.repository }}/actions/runs/${{ env.original_run_id }}"
echo "Wokwi tests: https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}"
- name: Publish Unit Test Results - name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v2 uses: EnricoMi/publish-unit-test-result-action@170bf24d20d201b842d7a52403b73ed297e6645b # v2.18.0
with: with:
commit: ${{ env.original_sha }} commit: ${{ env.original_sha }}
event_file: ./artifacts/parent-artifacts/event_file/event.json event_file: ./artifacts/parent-artifacts/event_file/event.json
@ -80,6 +91,17 @@ jobs:
files: ./artifacts/**/*.xml files: ./artifacts/**/*.xml
action_fail: true action_fail: true
compare_to_earlier_commit: false compare_to_earlier_commit: false
json_file: ./unity_results.json
json_suite_details: true
- name: Upload JSON
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: ${{ always() }}
with:
name: unity_results
overwrite: true
path: |
./unity_results.json
- name: Fail if tests failed - name: Fail if tests failed
if: ${{ env.original_conclusion == 'failure' || env.original_conclusion == 'timed_out' || github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'timed_out' }} if: ${{ env.original_conclusion == 'failure' || env.original_conclusion == 'timed_out' || github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'timed_out' }}
@ -87,7 +109,7 @@ jobs:
- name: Clean up caches - name: Clean up caches
if: always() if: always()
uses: actions/github-script@v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
script: | script: |
const ref = process.env.original_ref; const ref = process.env.original_ref;
@ -117,7 +139,7 @@ jobs:
}); });
- name: Report conclusion - name: Report conclusion
uses: actions/github-script@v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: always() if: always()
with: with:
script: | script: |
@ -138,15 +160,22 @@ jobs:
})).data; })).data;
core.info(`${name} is ${state}`); core.info(`${name} is ${state}`);
- name: Create output folder - name: Generate report
if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled
env:
REPORT_FILE: ./runtime-tests-results/RUNTIME_TESTS_REPORT.md
WOKWI_RUN_ID: ${{ github.event.workflow_run.id }}
BUILD_RUN_ID: ${{ env.original_run_id }}
IS_FAILING: ${{ env.original_conclusion == 'failure' || env.original_conclusion == 'timed_out' || github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'timed_out' || job.status == 'failure' }}
run: | run: |
rm -rf artifacts rm -rf artifacts $REPORT_FILE
mkdir -p runtime-tests-results mv -f ./unity_results.json ./runtime-tests-results/unity_results.json
touch $REPORT_FILE
python3 ./runtime-tests-results/table_generator.py ./runtime-tests-results/unity_results.json >> $REPORT_FILE
- name: Generate badge - name: Generate badge
if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled
uses: jaywcjlove/generated-badges@v1.0.13 uses: jaywcjlove/generated-badges@0e078ae4d4bab3777ea4f137de496ab44688f5ad # v1.0.13
with: with:
label: Runtime Tests label: Runtime Tests
status: ${{ job.status == 'success' && 'passing' || 'failing' }} status: ${{ job.status == 'success' && 'passing' || 'failing' }}
@ -161,6 +190,6 @@ jobs:
git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if [[ `git status --porcelain` ]]; then if [[ `git status --porcelain` ]]; then
git add --all git add --all
git commit -m "Updated runtime tests badge" git commit -m "Updated runtime tests report"
git push origin HEAD:gh-pages git push origin HEAD:gh-pages
fi fi

View file

@ -27,7 +27,7 @@ jobs:
types: ${{ steps.set-ref.outputs.types }} types: ${{ steps.set-ref.outputs.types }}
steps: steps:
- name: Report pending - name: Report pending
uses: actions/github-script@v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
script: | script: |
const owner = '${{ github.repository_owner }}'; const owner = '${{ github.repository_owner }}';
@ -47,7 +47,7 @@ jobs:
core.info(`${name} is ${state}`); core.info(`${name} is ${state}`);
- name: Download and extract event file - name: Download and extract event file
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }} run-id: ${{ github.event.workflow_run.id }}
@ -55,7 +55,7 @@ jobs:
path: artifacts/event_file path: artifacts/event_file
- name: Download and extract matrix info - name: Download and extract matrix info
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }} run-id: ${{ github.event.workflow_run.id }}
@ -109,6 +109,10 @@ jobs:
printf "\nAction = " printf "\nAction = "
cat artifacts/action.txt cat artifacts/action.txt
printf "${{ github.event.workflow_run.id }}" >> artifacts/run_id.txt
printf "\nRun ID = "
cat artifacts/run_id.txt
if [ -z "$ref" ] || [ "$ref" == "null" ]; then if [ -z "$ref" ] || [ "$ref" == "null" ]; then
echo "Failed to get PR number or ref" echo "Failed to get PR number or ref"
exit 1 exit 1
@ -126,7 +130,7 @@ jobs:
echo "ref=$ref" >> $GITHUB_OUTPUT echo "ref=$ref" >> $GITHUB_OUTPUT
- name: Download and extract parent hardware results - name: Download and extract parent hardware results
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
continue-on-error: true continue-on-error: true
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
@ -136,7 +140,7 @@ jobs:
path: artifacts/results/hw path: artifacts/results/hw
- name: Download and extract parent QEMU results - name: Download and extract parent QEMU results
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
continue-on-error: true continue-on-error: true
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
@ -146,14 +150,14 @@ jobs:
path: artifacts/results/qemu path: artifacts/results/qemu
- name: Upload parent artifacts - name: Upload parent artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: parent-artifacts name: parent-artifacts
path: artifacts path: artifacts
if-no-files-found: error if-no-files-found: error
- name: Report conclusion - name: Report conclusion
uses: actions/github-script@v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: always() if: always()
with: with:
script: | script: |
@ -193,7 +197,7 @@ jobs:
chip: ${{ fromJson(needs.get-artifacts.outputs.targets) }} chip: ${{ fromJson(needs.get-artifacts.outputs.targets) }}
steps: steps:
- name: Report pending - name: Report pending
uses: actions/github-script@v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
script: | script: |
const owner = '${{ github.repository_owner }}'; const owner = '${{ github.repository_owner }}';
@ -215,7 +219,7 @@ jobs:
- name: Check if already passed - name: Check if already passed
id: get-cache-results id: get-cache-results
if: needs.get-artifacts.outputs.pr_num if: needs.get-artifacts.outputs.pr_num
uses: actions/cache/restore@v4 uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with: with:
key: tests-${{ env.id }}-results-wokwi key: tests-${{ env.id }}-results-wokwi
path: | path: |
@ -239,11 +243,11 @@ jobs:
# DO NOT CHECKOUT THE USER'S REPOSITORY IN THIS WORKFLOW. IT HAS HIGH SECURITY RISKS. # DO NOT CHECKOUT THE USER'S REPOSITORY IN THIS WORKFLOW. IT HAS HIGH SECURITY RISKS.
- name: Checkout repository - name: Checkout repository
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/checkout@v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ needs.get-artifacts.outputs.base || github.ref }} ref: ${{ needs.get-artifacts.outputs.base || github.ref }}
- uses: actions/setup-python@v5 - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.0.4
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
with: with:
cache-dependency-path: tests/requirements.txt cache-dependency-path: tests/requirements.txt
@ -262,17 +266,17 @@ jobs:
- name: Wokwi CI Server - name: Wokwi CI Server
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: wokwi/wokwi-ci-server-action@v1 uses: wokwi/wokwi-ci-server-action@a6fabb5a49e080158c7a1d121ea5b789536a82c3 # v1
- name: Get binaries - name: Get binaries
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
uses: actions/download-artifact@v4 uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }} run-id: ${{ github.event.workflow_run.id }}
name: tests-bin-${{ matrix.chip }}-${{ matrix.type }} name: tests-bin-${{ matrix.chip }}-${{ matrix.type }}
path: | path: |
~/.arduino/tests ~/.arduino/tests/${{ matrix.chip }}
- name: Run Tests - name: Run Tests
if: ${{ steps.check-tests.outputs.enabled == 'true' }} if: ${{ steps.check-tests.outputs.enabled == 'true' }}
@ -282,7 +286,7 @@ jobs:
bash .github/scripts/tests_run.sh -c -type ${{ matrix.type }} -t ${{ matrix.chip }} -i 0 -m 1 -W ${{ env.WOKWI_TIMEOUT }} bash .github/scripts/tests_run.sh -c -type ${{ matrix.type }} -t ${{ matrix.chip }} -i 0 -m 1 -W ${{ env.WOKWI_TIMEOUT }}
- name: Upload ${{ matrix.chip }} ${{ matrix.type }} Wokwi results as cache - name: Upload ${{ matrix.chip }} ${{ matrix.type }} Wokwi results as cache
uses: actions/cache/save@v4 uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
if: steps.check-tests.outputs.enabled == 'true' && needs.get-artifacts.outputs.pr_num if: steps.check-tests.outputs.enabled == 'true' && needs.get-artifacts.outputs.pr_num
with: with:
key: tests-${{ env.id }}-results-wokwi key: tests-${{ env.id }}-results-wokwi
@ -291,7 +295,7 @@ jobs:
tests/**/result_*.json tests/**/result_*.json
- name: Upload ${{ matrix.chip }} ${{ matrix.type }} Wokwi results as artifacts - name: Upload ${{ matrix.chip }} ${{ matrix.type }} Wokwi results as artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always() if: always()
with: with:
name: tests-results-wokwi-${{ matrix.chip }}-${{ matrix.type }} name: tests-results-wokwi-${{ matrix.chip }}-${{ matrix.type }}
@ -301,7 +305,7 @@ jobs:
tests/**/result_*.json tests/**/result_*.json
- name: Report conclusion - name: Report conclusion
uses: actions/github-script@v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: always() if: always()
with: with:
script: | script: |

View file

@ -45,13 +45,13 @@ jobs:
echo "Tag: $tag" echo "Tag: $tag"
echo "RELEASE_TAG=$tag" >> $GITHUB_ENV echo "RELEASE_TAG=$tag" >> $GITHUB_ENV
- uses: actions/checkout@v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ inputs.git_ref || env.RELEASE_TAG }} ref: ${{ inputs.git_ref || env.RELEASE_TAG }}
submodules: "recursive" submodules: "recursive"
- name: Upload components to the component registry - name: Upload components to the component registry
uses: espressif/upload-components-ci-action@v1 uses: espressif/upload-components-ci-action@b78a19fa5424714997596d3ecffa634aef8ae20b # v1.0.5
with: with:
name: arduino-esp32 name: arduino-esp32
version: ${{ env.RELEASE_TAG }} version: ${{ env.RELEASE_TAG }}

25
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,25 @@
workflow:
rules:
# Disable those non-protected push triggered pipelines
- if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^\d+\.\d+(\.\d+)?($|-)/ && $CI_PIPELINE_SOURCE == "push"'
when: never
# when running merged result pipelines, CI_COMMIT_SHA represents the temp commit it created.
# Please use PIPELINE_COMMIT_SHA at all places that require a commit sha of the original commit.
- if: $CI_OPEN_MERGE_REQUESTS != null
variables:
PIPELINE_COMMIT_SHA: $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA
IS_MR_PIPELINE: 1
- if: $CI_OPEN_MERGE_REQUESTS == null
variables:
PIPELINE_COMMIT_SHA: $CI_COMMIT_SHA
IS_MR_PIPELINE: 0
- if: '$CI_PIPELINE_SOURCE == "schedule"'
variables:
IS_SCHEDULED_RUN: "true"
- when: always
# Place the default settings in `.gitlab/workflows/common.yml` instead
include:
- ".gitlab/workflows/common.yml"
- ".gitlab/workflows/sample.yml"

View file

@ -0,0 +1,26 @@
#####################
# Default Variables #
#####################
stages:
- pre_check
- build
- test
- result
variables:
ESP_IDF_VERSION: "5.5"
ESP_ARDUINO_VERSION: "3.3.0"
#############
# `default` #
#############
default:
retry:
max: 2
when:
# In case of a runner failure we could hop to another one, or a network error could go away.
- runner_system_failure
# Job execution timeout may be caused by a network issue.
- job_execution_timeout

View file

@ -0,0 +1,6 @@
hello-world:
stage: test
script:
- echo "Hello, World from GitLab CI!"
rules:
- if: $CI_PIPELINE_SOURCE == "push"

View file

@ -12,7 +12,7 @@ default_language_version:
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: "v5.0.0" rev: "cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b" # v5.0.0
hooks: hooks:
# Generic checks # Generic checks
- id: check-case-conflict - id: check-case-conflict
@ -39,15 +39,8 @@ repos:
^package\/.*$ ^package\/.*$
) )
- repo: https://github.com/codespell-project/codespell
rev: "v2.3.0"
hooks:
# Spell checking
- id: codespell
exclude: ^.*\.(svd|SVD)$
- repo: https://github.com/pre-commit/mirrors-clang-format - repo: https://github.com/pre-commit/mirrors-clang-format
rev: "v18.1.3" rev: "f6446549e5e97ec9665b9b03e75b87b445857f9a" # v18.1.3
hooks: hooks:
# C/C++ formatting # C/C++ formatting
- id: clang-format - id: clang-format
@ -55,7 +48,7 @@ repos:
exclude: ^.*\/build_opt\.h$ exclude: ^.*\/build_opt\.h$
- repo: https://github.com/psf/black-pre-commit-mirror - repo: https://github.com/psf/black-pre-commit-mirror
rev: "24.10.0" rev: "a4920527036bb9a3f3e6055d595849d67d0da066" # 25.1.0
hooks: hooks:
# Python formatting # Python formatting
- id: black - id: black
@ -63,7 +56,7 @@ repos:
args: [--line-length=120] #From the arduino code style. Add as argument rather than creating a new config file. args: [--line-length=120] #From the arduino code style. Add as argument rather than creating a new config file.
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: "7.1.1" rev: "16f5f28a384f0781bebb37a08aa45e65b9526c50" # 7.2.0
hooks: hooks:
# Python linting # Python linting
- id: flake8 - id: flake8
@ -74,21 +67,28 @@ repos:
- flake8-simplify - flake8-simplify
- repo: https://github.com/pre-commit/mirrors-prettier - repo: https://github.com/pre-commit/mirrors-prettier
rev: "v3.1.0" rev: "ffb6a759a979008c0e6dff86e39f4745a2d9eac4" # v3.1.0
hooks: hooks:
# YAML formatting # YAML formatting
- id: prettier - id: prettier
types_or: [yaml] types_or: [yaml]
- repo: https://github.com/codespell-project/codespell
rev: "63c8f8312b7559622c0d82815639671ae42132ac" # v2.4.1
hooks:
# Spell checking
- id: codespell
exclude: ^.*\.(svd|SVD)$
- repo: https://github.com/shellcheck-py/shellcheck-py - repo: https://github.com/shellcheck-py/shellcheck-py
rev: "v0.10.0.1" rev: "a23f6b85d0fdd5bb9d564e2579e678033debbdff" # v0.10.0.1
hooks: hooks:
# Bash linting # Bash linting
- id: shellcheck - id: shellcheck
types: [shell] types: [shell]
- repo: https://github.com/openstack/bashate - repo: https://github.com/openstack/bashate
rev: "2.1.1" rev: "fbd7c2534c2701351c603ff700ddf08202430a31" # 2.1.1
hooks: hooks:
# Bash formatting # Bash formatting
- id: bashate - id: bashate
@ -96,15 +96,15 @@ repos:
args: ["-i", "E006"] # Ignore E006: Line too long args: ["-i", "E006"] # Ignore E006: Line too long
- repo: https://github.com/errata-ai/vale - repo: https://github.com/errata-ai/vale
rev: "v3.9.1" rev: "dc4c47923788a413fb5677de6e3370d514aecb78" # v3.11.2
hooks: hooks:
# Sync vale styles and lint markdown and reStructuredText # Sync vale styles and lint markdown and reStructuredText
- id: vale - id: vale
name: vale-sync name: vale-sync
language_version: "1.21.6" language_version: "1.23.2"
pass_filenames: false pass_filenames: false
args: [sync] args: [sync]
types_or: [markdown, rst] types_or: [markdown, rst]
- id: vale - id: vale
language_version: "1.21.6" language_version: "1.23.2"
types_or: [markdown, rst] types_or: [markdown, rst]

View file

@ -6,7 +6,7 @@
# idf.py build # idf.py build
set(min_supported_idf_version "5.3.0") set(min_supported_idf_version "5.3.0")
set(max_supported_idf_version "5.3.99") set(max_supported_idf_version "5.5.99")
set(idf_version "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}") set(idf_version "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}")
if ("${idf_version}" AND NOT "$ENV{ARDUINO_SKIP_IDF_VERSION_CHECK}") if ("${idf_version}" AND NOT "$ENV{ARDUINO_SKIP_IDF_VERSION_CHECK}")
@ -33,6 +33,7 @@ set(CORE_SRCS
cores/esp32/esp32-hal-dac.c cores/esp32/esp32-hal-dac.c
cores/esp32/esp32-hal-gpio.c cores/esp32/esp32-hal-gpio.c
cores/esp32/esp32-hal-i2c.c cores/esp32/esp32-hal-i2c.c
cores/esp32/esp32-hal-i2c-ng.c
cores/esp32/esp32-hal-i2c-slave.c cores/esp32/esp32-hal-i2c-slave.c
cores/esp32/esp32-hal-ledc.c cores/esp32/esp32-hal-ledc.c
cores/esp32/esp32-hal-matrix.c cores/esp32/esp32-hal-matrix.c
@ -164,6 +165,7 @@ set(ARDUINO_LIBRARY_LittleFS_SRCS libraries/LittleFS/src/LittleFS.cpp)
set(ARDUINO_LIBRARY_NetBIOS_SRCS libraries/NetBIOS/src/NetBIOS.cpp) set(ARDUINO_LIBRARY_NetBIOS_SRCS libraries/NetBIOS/src/NetBIOS.cpp)
set(ARDUINO_LIBRARY_OpenThread_SRCS set(ARDUINO_LIBRARY_OpenThread_SRCS
libraries/OpenThread/src/OThread.cpp
libraries/OpenThread/src/OThreadCLI.cpp libraries/OpenThread/src/OThreadCLI.cpp
libraries/OpenThread/src/OThreadCLI_Util.cpp) libraries/OpenThread/src/OThreadCLI_Util.cpp)
@ -182,7 +184,8 @@ set(ARDUINO_LIBRARY_Matter_SRCS
libraries/Matter/src/MatterEndpoints/MatterOccupancySensor.cpp libraries/Matter/src/MatterEndpoints/MatterOccupancySensor.cpp
libraries/Matter/src/MatterEndpoints/MatterOnOffPlugin.cpp libraries/Matter/src/MatterEndpoints/MatterOnOffPlugin.cpp
libraries/Matter/src/MatterEndpoints/MatterThermostat.cpp libraries/Matter/src/MatterEndpoints/MatterThermostat.cpp
libraries/Matter/src/Matter.cpp) libraries/Matter/src/Matter.cpp
libraries/Matter/src/MatterEndPoint.cpp)
set(ARDUINO_LIBRARY_PPP_SRCS set(ARDUINO_LIBRARY_PPP_SRCS
libraries/PPP/src/PPP.cpp libraries/PPP/src/PPP.cpp
@ -294,6 +297,16 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS
libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp
libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp
libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp
libraries/Zigbee/src/ep/ZigbeeAnalog.cpp
libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp
libraries/Zigbee/src/ep/ZigbeeGateway.cpp
libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp
libraries/Zigbee/src/ep/ZigbeeIlluminanceSensor.cpp
libraries/Zigbee/src/ep/ZigbeePM25Sensor.cpp
libraries/Zigbee/src/ep/ZigbeeElectricalMeasurement.cpp
libraries/Zigbee/src/ep/ZigbeeBinary.cpp
libraries/Zigbee/src/ep/ZigbeePowerOutlet.cpp
libraries/Zigbee/src/ep/ZigbeeFanControl.cpp
) )
set(ARDUINO_LIBRARY_BLE_SRCS set(ARDUINO_LIBRARY_BLE_SRCS
@ -349,13 +362,13 @@ endforeach()
set(includedirs variants/${CONFIG_ARDUINO_VARIANT}/ cores/esp32/ ${ARDUINO_LIBRARIES_INCLUDEDIRS}) set(includedirs variants/${CONFIG_ARDUINO_VARIANT}/ cores/esp32/ ${ARDUINO_LIBRARIES_INCLUDEDIRS})
set(srcs ${CORE_SRCS} ${ARDUINO_LIBRARIES_SRCS}) set(srcs ${CORE_SRCS} ${ARDUINO_LIBRARIES_SRCS})
set(priv_includes cores/esp32/libb64) set(priv_includes cores/esp32/libb64)
set(requires spi_flash esp_partition mbedtls wpa_supplicant esp_adc esp_eth http_parser esp_ringbuf esp_driver_gptimer esp_driver_usb_serial_jtag driver) set(requires spi_flash esp_partition mbedtls wpa_supplicant esp_adc esp_eth http_parser esp_ringbuf esp_driver_gptimer esp_driver_usb_serial_jtag driver esp_http_client esp_https_ota)
set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support bt esp_hid usb esp_psram ${ARDUINO_LIBRARIES_REQUIRES}) set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support bt esp_hid usb esp_psram ${ARDUINO_LIBRARIES_REQUIRES})
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_OpenThread) if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_OpenThread)
#if(CONFIG_SOC_IEEE802154_SUPPORTED) # Does not work! #if(CONFIG_SOC_IEEE802154_SUPPORTED) # Does not work!
#if(CONFIG_OPENTHREAD_ENABLED) # Does not work! #if(CONFIG_OPENTHREAD_ENABLED) # Does not work!
if(IDF_TARGET STREQUAL "esp32c6" OR IDF_TARGET STREQUAL "esp32h2") # Sadly only this works if(IDF_TARGET STREQUAL "esp32c6" OR IDF_TARGET STREQUAL "esp32h2" OR IDF_TARGET STREQUAL "esp32c5") # Sadly only this works
list(APPEND requires openthread) list(APPEND requires openthread)
endif() endif()
endif() endif()

View file

@ -1,9 +1,9 @@
# Arduino core for the ESP32, ESP32-P4, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6 and ESP32-H2 # Arduino core for the ESP32, ESP32-C3, ESP32-C6, ESP32-H2, ESP32-P4, ESP32-S2 and ESP32-S3.
[![Build Status](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/push.yml?branch=master&event=push&label=Compilation%20Tests)](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml?query=branch%3Amaster+event%3Apush) [![Build Status](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/push.yml?branch=master&event=push&label=Compilation%20Tests)](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml?query=branch%3Amaster+event%3Apush)
[![Verbose Build Status](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/push.yml?branch=master&event=schedule&label=Compilation%20Tests%20(Verbose))](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml?query=branch%3Amaster+event%3Aschedule) [![Verbose Build Status](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/push.yml?branch=master&event=schedule&label=Compilation%20Tests%20(Verbose))](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml?query=branch%3Amaster+event%3Aschedule)
[![External Libraries Test](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/lib.yml?branch=master&event=schedule&label=External%20Libraries%20Test)](https://github.com/espressif/arduino-esp32/blob/gh-pages/LIBRARIES_TEST.md) [![External Libraries Test](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/lib.yml?branch=master&event=schedule&label=External%20Libraries%20Test)](https://github.com/espressif/arduino-esp32/blob/gh-pages/LIBRARIES_TEST.md)
[![Runtime Tests](https://github.com/espressif/arduino-esp32/blob/gh-pages/runtime-tests-results/badge.svg)](https://github.com/espressif/arduino-esp32/actions/workflows/tests_results.yml) [![Runtime Tests](https://github.com/espressif/arduino-esp32/blob/gh-pages/runtime-tests-results/badge.svg)](https://github.com/espressif/arduino-esp32/blob/gh-pages/runtime-tests-results/RUNTIME_TESTS_REPORT.md)
### Need help or have a question? Join the chat at [Discord](https://discord.gg/8xY6e9crwv) or [open a new Discussion](https://github.com/espressif/arduino-esp32/discussions) ### Need help or have a question? Join the chat at [Discord](https://discord.gg/8xY6e9crwv) or [open a new Discussion](https://github.com/espressif/arduino-esp32/discussions)
@ -67,16 +67,17 @@ Here are the ESP32 series supported by the Arduino-ESP32 project:
| **SoC** | **Stable** | **Development** | **Datasheet** | | **SoC** | **Stable** | **Development** | **Datasheet** |
|----------|:----------:|:---------------:|:-------------------------------------------------------------------------------------------------:| |----------|:----------:|:---------------:|:-------------------------------------------------------------------------------------------------:|
| ESP32 | Yes | Yes | [ESP32](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) | | ESP32 | Yes | Yes | [ESP32](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) |
| ESP32-S2 | Yes | Yes | [ESP32-S2](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) |
| ESP32-C3 | Yes | Yes | [ESP32-C3](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) | | ESP32-C3 | Yes | Yes | [ESP32-C3](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) |
| ESP32-S3 | Yes | Yes | [ESP32-S3](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) |
| ESP32-C6 | Yes | Yes | [ESP32-C6](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) | | ESP32-C6 | Yes | Yes | [ESP32-C6](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) |
| ESP32-H2 | Yes | Yes | [ESP32-H2](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) | | ESP32-H2 | Yes | Yes | [ESP32-H2](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) |
| ESP32-P4 | Yes | Yes | [ESP32-P4](https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf) | | ESP32-P4 | Yes | Yes | [ESP32-P4](https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf) |
| ESP32-S2 | Yes | Yes | [ESP32-S2](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) |
| ESP32-S3 | Yes | Yes | [ESP32-S3](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) |
> [!NOTE] > [!NOTE]
> ESP32-C2 is also supported by Arduino-ESP32 but requires rebuilding the static libraries. This is not trivial and requires a good understanding of the ESP-IDF > ESP32-C2 is also supported by Arduino-ESP32 but requires using Arduino as an ESP-IDF component or rebuilding the static libraries.
> build system. For more information, see the [Lib Builder documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/lib_builder.html). > For more information, see the [Arduino as an ESP-IDF component documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html) or the
> [Lib Builder documentation](https://docs.espressif.com/projects/arduino-esp32/en/latest/lib_builder.html), respectively.
For more details visit the [supported chips](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html#supported-soc-s) documentation page. For more details visit the [supported chips](https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html#supported-soc-s) documentation page.

3256
boards.txt

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,6 @@
#include "extra_attr.h" #include "extra_attr.h"
#include "pins_arduino.h" #include "pins_arduino.h"
#include "io_pin_remap.h"
#include "esp32-hal.h" #include "esp32-hal.h"
#define PI 3.1415926535897932384626433832795 #define PI 3.1415926535897932384626433832795
@ -251,4 +250,8 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin); void noTone(uint8_t _pin);
#endif /* __cplusplus */ #endif /* __cplusplus */
// must be applied last as it overrides some of the above
#include "io_pin_remap.h"
#endif /* _ESP32_CORE_ARDUINO_H_ */ #endif /* _ESP32_CORE_ARDUINO_H_ */

View file

@ -119,10 +119,10 @@ espHsvColor_t espRgbColorToHsvColor(espRgbColor_t rgb) {
} }
espRgbColor_t espXYColorToRgbColor(uint8_t Level, espXyColor_t xy) { espRgbColor_t espXYColorToRgbColor(uint8_t Level, espXyColor_t xy) {
return espXYToRgbColor(Level, xy.x, xy.y); return espXYToRgbColor(Level, xy.x, xy.y, true);
} }
espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y) { espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y, bool addXYZScaling) {
// convert xyY color space to RGB // convert xyY color space to RGB
// https://www.easyrgb.com/en/math.php // https://www.easyrgb.com/en/math.php
@ -156,9 +156,11 @@ espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t curren
// X, Y and Z input refer to a D65/2° standard illuminant. // X, Y and Z input refer to a D65/2° standard illuminant.
// sR, sG and sB (standard RGB) output range = 0 ÷ 255 // sR, sG and sB (standard RGB) output range = 0 ÷ 255
// convert XYZ to RGB - CIE XYZ to sRGB // convert XYZ to RGB - CIE XYZ to sRGB
if (addXYZScaling) {
X = X / 100.0f; X = X / 100.0f;
Y = Y / 100.0f; Y = Y / 100.0f;
Z = Z / 100.0f; Z = Z / 100.0f;
}
r = (X * 3.2406f) - (Y * 1.5372f) - (Z * 0.4986f); r = (X * 3.2406f) - (Y * 1.5372f) - (Z * 0.4986f);
g = -(X * 0.9689f) + (Y * 1.8758f) + (Z * 0.0415f); g = -(X * 0.9689f) + (Y * 1.8758f) + (Z * 0.0415f);

View file

@ -19,6 +19,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -49,7 +50,7 @@ typedef struct HsvColor_t espHsvColor_t;
typedef struct XyColor_t espXyColor_t; typedef struct XyColor_t espXyColor_t;
typedef struct CtColor_t espCtColor_t; typedef struct CtColor_t espCtColor_t;
espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y); espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y, bool addXYZScaling);
espRgbColor_t espXYColorToRgb(uint8_t Level, espXyColor_t xy); espRgbColor_t espXYColorToRgb(uint8_t Level, espXyColor_t xy);
espXyColor_t espRgbColorToXYColor(espRgbColor_t rgb); espXyColor_t espRgbColorToXYColor(espRgbColor_t rgb);
espXyColor_t espRgbToXYColor(uint8_t r, uint8_t g, uint8_t b); espXyColor_t espRgbToXYColor(uint8_t r, uint8_t g, uint8_t b);

View file

@ -21,6 +21,7 @@
#include "Esp.h" #include "Esp.h"
#include "esp_sleep.h" #include "esp_sleep.h"
#include "spi_flash_mmap.h" #include "spi_flash_mmap.h"
#include "esp_idf_version.h"
#include <memory> #include <memory>
#include <soc/soc.h> #include <soc/soc.h>
#include <esp_partition.h> #include <esp_partition.h>
@ -63,6 +64,9 @@ extern "C" {
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/spi_flash.h" #include "esp32p4/rom/spi_flash.h"
#define ESP_FLASH_IMAGE_BASE 0x2000 // Esp32p4 is located at 0x2000 #define ESP_FLASH_IMAGE_BASE 0x2000 // Esp32p4 is located at 0x2000
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/spi_flash.h"
#define ESP_FLASH_IMAGE_BASE 0x2000 // Esp32c5 is located at 0x2000
#else #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif
@ -301,6 +305,11 @@ const char *EspClass::getChipModel(void) {
case CHIP_ESP32C6: return "ESP32-C6"; case CHIP_ESP32C6: return "ESP32-C6";
case CHIP_ESP32H2: return "ESP32-H2"; case CHIP_ESP32H2: return "ESP32-H2";
case CHIP_ESP32P4: return "ESP32-P4"; case CHIP_ESP32P4: return "ESP32-P4";
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
case CHIP_ESP32C5: return "ESP32-C5";
case CHIP_ESP32C61: return "ESP32-C61";
case CHIP_ESP32H21: return "ESP32-H21";
#endif
default: return "UNKNOWN"; default: return "UNKNOWN";
} }
#endif #endif

View file

@ -603,6 +603,7 @@ void HWCDC::setDebugOutput(bool en) {
} else { } else {
ets_install_putc2(NULL); ets_install_putc2(NULL);
} }
ets_install_putc1(NULL); // closes UART log output
} }
#if ARDUINO_USB_MODE && ARDUINO_USB_CDC_ON_BOOT // Hardware JTAG CDC selected #if ARDUINO_USB_MODE && ARDUINO_USB_CDC_ON_BOOT // Hardware JTAG CDC selected

View file

@ -20,6 +20,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "Stream.h" #include "Stream.h"
#include <functional>
class HardwareI2C : public Stream { class HardwareI2C : public Stream {
public: public:
@ -36,6 +37,7 @@ public:
virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit) = 0; virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit) = 0;
virtual size_t requestFrom(uint8_t address, size_t len) = 0; virtual size_t requestFrom(uint8_t address, size_t len) = 0;
virtual void onReceive(void (*)(int)) = 0; // Update base class to use std::function
virtual void onRequest(void (*)(void)) = 0; virtual void onReceive(const std::function<void(int)> &) = 0;
virtual void onRequest(const std::function<void()> &) = 0;
}; };

View file

@ -11,52 +11,52 @@
#include "driver/uart.h" #include "driver/uart.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#ifndef ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE #if (SOC_UART_LP_NUM >= 1)
#define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE 2048 #define UART_HW_FIFO_LEN(uart_num) ((uart_num < SOC_UART_HP_NUM) ? SOC_UART_FIFO_LEN : SOC_LP_UART_FIFO_LEN)
#endif #else
#define UART_HW_FIFO_LEN(uart_num) SOC_UART_FIFO_LEN
#ifndef ARDUINO_SERIAL_EVENT_TASK_PRIORITY
#define ARDUINO_SERIAL_EVENT_TASK_PRIORITY (configMAX_PRIORITIES - 1)
#endif
#ifndef ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
#define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -1
#endif #endif
void serialEvent(void) __attribute__((weak)); void serialEvent(void) __attribute__((weak));
#if SOC_UART_HP_NUM > 1 #if SOC_UART_NUM > 1
void serialEvent1(void) __attribute__((weak)); void serialEvent1(void) __attribute__((weak));
#endif /* SOC_UART_HP_NUM > 1 */ #endif /* SOC_UART_NUM > 1 */
#if SOC_UART_HP_NUM > 2 #if SOC_UART_NUM > 2
void serialEvent2(void) __attribute__((weak)); void serialEvent2(void) __attribute__((weak));
#endif /* SOC_UART_HP_NUM > 2 */ #endif /* SOC_UART_NUM > 2 */
#if SOC_UART_HP_NUM > 3 #if SOC_UART_NUM > 3
void serialEvent3(void) __attribute__((weak)); void serialEvent3(void) __attribute__((weak));
#endif /* SOC_UART_HP_NUM > 3 */ #endif /* SOC_UART_NUM > 3 */
#if SOC_UART_HP_NUM > 4 #if SOC_UART_NUM > 4
void serialEvent4(void) __attribute__((weak)); void serialEvent4(void) __attribute__((weak));
#endif /* SOC_UART_HP_NUM > 4 */ #endif /* SOC_UART_NUM > 4 */
#if SOC_UART_NUM > 5
void serialEvent5(void) __attribute__((weak));
#endif /* SOC_UART_NUM > 5 */
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
// There is always Seria0 for UART0 // There is always Seria0 for UART0
HardwareSerial Serial0(0); HardwareSerial Serial0(0);
#if SOC_UART_HP_NUM > 1 #if SOC_UART_NUM > 1
HardwareSerial Serial1(1); HardwareSerial Serial1(1);
#endif #endif
#if SOC_UART_HP_NUM > 2 #if SOC_UART_NUM > 2
HardwareSerial Serial2(2); HardwareSerial Serial2(2);
#endif #endif
#if SOC_UART_HP_NUM > 3 #if SOC_UART_NUM > 3
HardwareSerial Serial3(3); HardwareSerial Serial3(3);
#endif #endif
#if SOC_UART_HP_NUM > 4 #if SOC_UART_NUM > 4
HardwareSerial Serial4(4); HardwareSerial Serial4(4);
#endif #endif
#if (SOC_UART_NUM > 5)
HardwareSerial Serial5(5);
#endif
#if HWCDC_SERIAL_IS_DEFINED == 1 // Hardware JTAG CDC Event #if HWCDC_SERIAL_IS_DEFINED == 1 // Hardware JTAG CDC Event
extern void HWCDCSerialEvent(void) __attribute__((weak)); extern void HWCDCSerialEvent(void) __attribute__((weak));
#endif #endif
@ -81,26 +81,31 @@ void serialEventRun(void) {
if (serialEvent && Serial0.available()) { if (serialEvent && Serial0.available()) {
serialEvent(); serialEvent();
} }
#if SOC_UART_HP_NUM > 1 #if SOC_UART_NUM > 1
if (serialEvent1 && Serial1.available()) { if (serialEvent1 && Serial1.available()) {
serialEvent1(); serialEvent1();
} }
#endif #endif
#if SOC_UART_HP_NUM > 2 #if SOC_UART_NUM > 2
if (serialEvent2 && Serial2.available()) { if (serialEvent2 && Serial2.available()) {
serialEvent2(); serialEvent2();
} }
#endif #endif
#if SOC_UART_HP_NUM > 3 #if SOC_UART_NUM > 3
if (serialEvent3 && Serial3.available()) { if (serialEvent3 && Serial3.available()) {
serialEvent3(); serialEvent3();
} }
#endif #endif
#if SOC_UART_HP_NUM > 4 #if SOC_UART_NUM > 4
if (serialEvent4 && Serial4.available()) { if (serialEvent4 && Serial4.available()) {
serialEvent4(); serialEvent4();
} }
#endif #endif
#if SOC_UART_NUM > 5
if (serialEvent5 && Serial5.available()) {
serialEvent5();
}
#endif
} }
#endif #endif
@ -185,7 +190,8 @@ void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout) {
// in case that onReceive() shall work only with RX Timeout, FIFO shall be high // in case that onReceive() shall work only with RX Timeout, FIFO shall be high
// this is a work around for an IDF issue with events and low FIFO Full value (< 3) // this is a work around for an IDF issue with events and low FIFO Full value (< 3)
if (_onReceiveTimeout) { // Not valid for the LP UART
if (_onReceiveTimeout && _uart_nr < SOC_UART_HP_NUM) {
uartSetRxFIFOFull(_uart, 120); uartSetRxFIFOFull(_uart, 120);
log_w("OnReceive is set to Timeout only, thus FIFO Full is now 120 bytes."); log_w("OnReceive is set to Timeout only, thus FIFO Full is now 120 bytes.");
} }
@ -207,12 +213,13 @@ bool HardwareSerial::setRxFIFOFull(uint8_t fifoBytes) {
HSERIAL_MUTEX_LOCK(); HSERIAL_MUTEX_LOCK();
// in case that onReceive() shall work only with RX Timeout, FIFO shall be high // in case that onReceive() shall work only with RX Timeout, FIFO shall be high
// this is a work around for an IDF issue with events and low FIFO Full value (< 3) // this is a work around for an IDF issue with events and low FIFO Full value (< 3)
if (_onReceiveCB != NULL && _onReceiveTimeout) { // Not valid for the LP UART
if (_onReceiveCB != NULL && _onReceiveTimeout && _uart_nr < SOC_UART_HP_NUM) {
fifoBytes = 120; fifoBytes = 120;
log_w("OnReceive is set to Timeout only, thus FIFO Full is now 120 bytes."); log_w("OnReceive is set to Timeout only, thus FIFO Full is now 120 bytes.");
} }
bool retCode = uartSetRxFIFOFull(_uart, fifoBytes); // Set new timeout bool retCode = uartSetRxFIFOFull(_uart, fifoBytes); // Set new timeout
if (fifoBytes > 0 && fifoBytes < SOC_UART_FIFO_LEN - 1) { if (fifoBytes > 0 && fifoBytes < UART_HW_FIFO_LEN(_uart_nr) - 1) {
_rxFIFOFull = fifoBytes; _rxFIFOFull = fifoBytes;
} }
HSERIAL_MUTEX_UNLOCK(); HSERIAL_MUTEX_UNLOCK();
@ -298,8 +305,8 @@ void HardwareSerial::_uartEventTask(void *args) {
} }
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd) { void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd) {
if (_uart_nr >= SOC_UART_HP_NUM) { if (_uart_nr >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_HP_NUM - 1); log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_NUM - 1);
return; return;
} }
@ -333,7 +340,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
txPin = _txPin < 0 ? (int8_t)SOC_TX0 : _txPin; txPin = _txPin < 0 ? (int8_t)SOC_TX0 : _txPin;
} }
break; break;
#if SOC_UART_HP_NUM > 1 // may save some flash bytes... #if SOC_UART_HP_NUM > 1
case UART_NUM_1: case UART_NUM_1:
if (rxPin < 0 && txPin < 0) { if (rxPin < 0 && txPin < 0) {
// do not change RX1/TX1 if it has already been set before // do not change RX1/TX1 if it has already been set before
@ -341,8 +348,8 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
txPin = _txPin < 0 ? (int8_t)TX1 : _txPin; txPin = _txPin < 0 ? (int8_t)TX1 : _txPin;
} }
break; break;
#endif #endif // UART_NUM_1
#if SOC_UART_HP_NUM > 2 // may save some flash bytes... #if SOC_UART_HP_NUM > 2
case UART_NUM_2: case UART_NUM_2:
if (rxPin < 0 && txPin < 0) { if (rxPin < 0 && txPin < 0) {
// do not change RX2/TX2 if it has already been set before // do not change RX2/TX2 if it has already been set before
@ -354,11 +361,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
#endif #endif
} }
break; break;
#endif #endif // UART_NUM_2
#if SOC_UART_HP_NUM > 3 // may save some flash bytes... #if SOC_UART_HP_NUM > 3
case UART_NUM_3: case UART_NUM_3:
if (rxPin < 0 && txPin < 0) { if (rxPin < 0 && txPin < 0) {
// do not change RX2/TX2 if it has already been set before // do not change RX3/TX3 if it has already been set before
#ifdef RX3 #ifdef RX3
rxPin = _rxPin < 0 ? (int8_t)RX3 : _rxPin; rxPin = _rxPin < 0 ? (int8_t)RX3 : _rxPin;
#endif #endif
@ -367,11 +374,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
#endif #endif
} }
break; break;
#endif #endif // UART_NUM_3
#if SOC_UART_HP_NUM > 4 // may save some flash bytes... #if SOC_UART_HP_NUM > 4
case UART_NUM_4: case UART_NUM_4:
if (rxPin < 0 && txPin < 0) { if (rxPin < 0 && txPin < 0) {
// do not change RX2/TX2 if it has already been set before // do not change RX4/TX4 if it has already been set before
#ifdef RX4 #ifdef RX4
rxPin = _rxPin < 0 ? (int8_t)RX4 : _rxPin; rxPin = _rxPin < 0 ? (int8_t)RX4 : _rxPin;
#endif #endif
@ -380,7 +387,20 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
#endif #endif
} }
break; break;
#endif // UART_NUM_4
#if (SOC_UART_LP_NUM >= 1)
case LP_UART_NUM_0:
if (rxPin < 0 && txPin < 0) {
// do not change RX0_LP/TX0_LP if it has already been set before
#ifdef LP_RX0
rxPin = _rxPin < 0 ? (int8_t)LP_RX0 : _rxPin;
#endif #endif
#ifdef LP_TX0
txPin = _txPin < 0 ? (int8_t)LP_TX0 : _txPin;
#endif
}
break;
#endif // LP_UART_NUM_0
} }
} }
@ -445,7 +465,8 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
if (!_rxFIFOFull) { // it has not being changed before calling begin() if (!_rxFIFOFull) { // it has not being changed before calling begin()
// set a default FIFO Full value for the IDF driver // set a default FIFO Full value for the IDF driver
uint8_t fifoFull = 1; uint8_t fifoFull = 1;
if (baud > 57600 || (_onReceiveCB != NULL && _onReceiveTimeout)) { // if baud rate is higher than 57600 or onReceive() is set, it will set FIFO Full to 120 bytes, except for LP UART
if (_uart_nr < SOC_UART_HP_NUM && (baud > 57600 || (_onReceiveCB != NULL && _onReceiveTimeout))) {
fifoFull = 120; fifoFull = 120;
} }
uartSetRxFIFOFull(_uart, fifoFull); uartSetRxFIFOFull(_uart, fifoFull);
@ -477,6 +498,12 @@ void HardwareSerial::setDebugOutput(bool en) {
if (_uart == 0) { if (_uart == 0) {
return; return;
} }
#if (SOC_UART_LP_NUM >= 1)
if (_uart_nr >= SOC_UART_HP_NUM) {
log_e("LP UART does not support Debug Output.");
return;
}
#endif
if (en) { if (en) {
uartSetDebug(_uart); uartSetDebug(_uart);
} else { } else {
@ -580,35 +607,56 @@ bool HardwareSerial::setMode(SerialMode mode) {
return uartSetMode(_uart, mode); return uartSetMode(_uart, mode);
} }
// Sets the UART Clock Source based on the compatible SoC options
// This method must be called before starting UART using begin(), otherwise it won't have any effect.
// Clock Source Options are:
// UART_CLK_SRC_DEFAULT :: any SoC - it will set whatever IDF defines as the default UART Clock Source
// UART_CLK_SRC_APB :: ESP32, ESP32-S2, ESP32-C3 and ESP32-S3
// UART_CLK_SRC_PLL :: ESP32-C2, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2 and ESP32-P4
// UART_CLK_SRC_XTAL :: ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-S3 and ESP32-P4
// UART_CLK_SRC_RTC :: ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-S3 and ESP32-P4
// UART_CLK_SRC_REF_TICK :: ESP32 and ESP32-S2
// Note: CLK_SRC_PLL Freq depends on the SoC - ESP32-C2 has 40MHz, ESP32-H2 has 48MHz and ESP32-C5, C6, C61 and P4 has 80MHz
// Note: ESP32-C6, C61, ESP32-P4 and ESP32-C5 have LP UART that will use only RTC_FAST or XTAL/2 as Clock Source
bool HardwareSerial::setClockSource(SerialClkSrc clkSrc) {
if (_uart) {
log_e("No Clock Source change was done. This function must be called before beginning UART%d.", _uart_nr);
return false;
}
return uartSetClockSource(_uart_nr, (uart_sclk_t)clkSrc);
}
// minimum total RX Buffer size is the UART FIFO space (128 bytes for most SoC) + 1. IDF imposition. // minimum total RX Buffer size is the UART FIFO space (128 bytes for most SoC) + 1. IDF imposition.
// LP UART has FIFO of 16 bytes
size_t HardwareSerial::setRxBufferSize(size_t new_size) { size_t HardwareSerial::setRxBufferSize(size_t new_size) {
if (_uart) { if (_uart) {
log_e("RX Buffer can't be resized when Serial is already running. Set it before calling begin()."); log_e("RX Buffer can't be resized when Serial is already running. Set it before calling begin().");
return 0; return 0;
} }
uint8_t FIFOLen = UART_HW_FIFO_LEN(_uart_nr);
if (new_size <= SOC_UART_FIFO_LEN) { // Valid value is higher than the FIFO length
log_w("RX Buffer set to minimum value: %d.", SOC_UART_FIFO_LEN + 1); // ESP32, S2, S3 and C3 means higher than 128 if (new_size <= FIFOLen) {
new_size = SOC_UART_FIFO_LEN + 1; new_size = FIFOLen + 1;
log_w("RX Buffer set to minimum value: %d.", new_size);
} }
_rxBufferSize = new_size; _rxBufferSize = new_size;
return _rxBufferSize; return _rxBufferSize;
} }
// minimum total TX Buffer size is the UART FIFO space (128 bytes for most SoC). // minimum total TX Buffer size is the UART FIFO space (128 bytes for most SoC) + 1.
// LP UART has FIFO of 16 bytes
size_t HardwareSerial::setTxBufferSize(size_t new_size) { size_t HardwareSerial::setTxBufferSize(size_t new_size) {
if (_uart) { if (_uart) {
log_e("TX Buffer can't be resized when Serial is already running. Set it before calling begin()."); log_e("TX Buffer can't be resized when Serial is already running. Set it before calling begin().");
return 0; return 0;
} }
uint8_t FIFOLen = UART_HW_FIFO_LEN(_uart_nr);
if (new_size <= SOC_UART_FIFO_LEN) { // Valid values are zero or higher than the FIFO length
log_w("TX Buffer set to minimum value: %d.", SOC_UART_FIFO_LEN); // ESP32, S2, S3 and C3 means higher than 128 if (new_size > 0 && new_size <= FIFOLen) {
_txBufferSize = 0; // it will use just UART FIFO with SOC_UART_FIFO_LEN bytes (128 for most SoC) new_size = FIFOLen + 1;
return SOC_UART_FIFO_LEN; log_w("TX Buffer set to minimum value: %d.", new_size);
} }
// if new_size is higher than SOC_UART_FIFO_LEN, TX Ringbuffer will be active and it will be used to report back "availableToWrite()" // if new_size is higher than SOC_UART_FIFO_LEN, TX Ringbuffer will be active and it will be used to report back "availableToWrite()"
_txBufferSize = new_size; _txBufferSize = new_size;

View file

@ -96,16 +96,51 @@ typedef enum {
UART_PARITY_ERROR UART_PARITY_ERROR
} hardwareSerial_error_t; } hardwareSerial_error_t;
typedef enum {
UART_CLK_SRC_DEFAULT = UART_SCLK_DEFAULT,
#if SOC_UART_SUPPORT_APB_CLK
UART_CLK_SRC_APB = UART_SCLK_APB,
#endif
#if SOC_UART_SUPPORT_PLL_F40M_CLK
UART_CLK_SRC_PLL = UART_SCLK_PLL_F40M,
#elif SOC_UART_SUPPORT_PLL_F80M_CLK
UART_CLK_SRC_PLL = UART_SCLK_PLL_F80M,
#elif CONFIG_IDF_TARGET_ESP32H2
UART_CLK_SRC_PLL = UART_SCLK_PLL_F48M,
#endif
#if SOC_UART_SUPPORT_XTAL_CLK
UART_CLK_SRC_XTAL = UART_SCLK_XTAL,
#endif
#if SOC_UART_SUPPORT_RTC_CLK
UART_CLK_SRC_RTC = UART_SCLK_RTC,
#endif
#if SOC_UART_SUPPORT_REF_TICK
UART_CLK_SRC_REF_TICK = UART_SCLK_REF_TICK,
#endif
} SerialClkSrc;
#ifndef ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE #ifndef ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE
#ifndef CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE
#define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE 2048 #define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE 2048
#else
#define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE
#endif
#endif #endif
#ifndef ARDUINO_SERIAL_EVENT_TASK_PRIORITY #ifndef ARDUINO_SERIAL_EVENT_TASK_PRIORITY
#ifndef CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY
#define ARDUINO_SERIAL_EVENT_TASK_PRIORITY (configMAX_PRIORITIES - 1) #define ARDUINO_SERIAL_EVENT_TASK_PRIORITY (configMAX_PRIORITIES - 1)
#else
#define ARDUINO_SERIAL_EVENT_TASK_PRIORITY CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY
#endif
#endif #endif
#ifndef ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE #ifndef ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
#ifndef CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
#define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -1 #define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -1
#else
#define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
#endif
#endif #endif
// UART0 pins are defined by default by the bootloader. // UART0 pins are defined by default by the bootloader.
@ -127,6 +162,8 @@ typedef enum {
#define SOC_RX0 (gpio_num_t)23 #define SOC_RX0 (gpio_num_t)23
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#define SOC_RX0 (gpio_num_t)38 #define SOC_RX0 (gpio_num_t)38
#elif CONFIG_IDF_TARGET_ESP32C5
#define SOC_RX0 (gpio_num_t)12
#endif #endif
#endif #endif
@ -145,6 +182,8 @@ typedef enum {
#define SOC_TX0 (gpio_num_t)24 #define SOC_TX0 (gpio_num_t)24
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#define SOC_TX0 (gpio_num_t)37 #define SOC_TX0 (gpio_num_t)37
#elif CONFIG_IDF_TARGET_ESP32C5
#define SOC_TX0 (gpio_num_t)11
#endif #endif
#endif #endif
@ -168,6 +207,8 @@ typedef enum {
#define RX1 (gpio_num_t)0 #define RX1 (gpio_num_t)0
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#define RX1 (gpio_num_t)11 #define RX1 (gpio_num_t)11
#elif CONFIG_IDF_TARGET_ESP32C5
#define RX1 (gpio_num_t)4
#endif #endif
#endif #endif
@ -188,6 +229,8 @@ typedef enum {
#define TX1 (gpio_num_t)1 #define TX1 (gpio_num_t)1
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#define TX1 (gpio_num_t)10 #define TX1 (gpio_num_t)10
#elif CONFIG_IDF_TARGET_ESP32C5
#define TX1 (gpio_num_t)5
#endif #endif
#endif #endif
#endif /* SOC_UART_HP_NUM > 1 */ #endif /* SOC_UART_HP_NUM > 1 */
@ -212,6 +255,16 @@ typedef enum {
#endif #endif
#endif /* SOC_UART_HP_NUM > 2 */ #endif /* SOC_UART_HP_NUM > 2 */
#if SOC_UART_LP_NUM >= 1
#ifndef LP_RX0
#define LP_RX0 (gpio_num_t) LP_U0RXD_GPIO_NUM
#endif
#ifndef LP_TX0
#define LP_TX0 (gpio_num_t) LP_U0TXD_GPIO_NUM
#endif
#endif /* SOC_UART_LP_NUM >= 1 */
typedef std::function<void(void)> OnReceiveCb; typedef std::function<void(void)> OnReceiveCb;
typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb; typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb;
@ -259,7 +312,7 @@ public:
// rxfifo_full_thrhd if the UART Flow Control Threshold in the UART FIFO (max 127) // rxfifo_full_thrhd if the UART Flow Control Threshold in the UART FIFO (max 127)
void begin( 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, 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 uint8_t rxfifo_full_thrhd = 120
); );
void end(void); void end(void);
void updateBaudRate(unsigned long baud); void updateBaudRate(unsigned long baud);
@ -322,6 +375,17 @@ public:
// UART_MODE_RS485_COLLISION_DETECT = 0x03 mode: RS485 collision detection UART mode (used for test purposes) // UART_MODE_RS485_COLLISION_DETECT = 0x03 mode: RS485 collision detection UART mode (used for test purposes)
// UART_MODE_RS485_APP_CTRL = 0x04 mode: application control RS485 UART mode (used for test purposes) // UART_MODE_RS485_APP_CTRL = 0x04 mode: application control RS485 UART mode (used for test purposes)
bool setMode(SerialMode mode); bool setMode(SerialMode mode);
// Used to set the UART clock source mode. It must be set before calling begin(), otherwise it won't have any effect.
// Not all clock source are available to every SoC. The compatible option are listed here:
// UART_CLK_SRC_DEFAULT :: any SoC - it will set whatever IDF defines as the default UART Clock Source
// UART_CLK_SRC_APB :: ESP32, ESP32-S2, ESP32-C3 and ESP32-S3
// UART_CLK_SRC_PLL :: ESP32-C2, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2 and ESP32-P4
// UART_CLK_SRC_XTAL :: ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-S3 and ESP32-P4
// UART_CLK_SRC_RTC :: ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-S3 and ESP32-P4
// UART_CLK_SRC_REF_TICK :: ESP32 and ESP32-S2
// Note: CLK_SRC_PLL Freq depends on the SoC - ESP32-C2 has 40MHz, ESP32-H2 has 48MHz and ESP32-C5, C6, C61 and P4 has 80MHz
// Note: ESP32-C6, C61, ESP32-P4 and ESP32-C5 have LP UART that will use only RTC_FAST or XTAL/2 as Clock Source
bool setClockSource(SerialClkSrc clkSrc);
size_t setRxBufferSize(size_t new_size); size_t setRxBufferSize(size_t new_size);
size_t setTxBufferSize(size_t new_size); size_t setTxBufferSize(size_t new_size);
@ -365,18 +429,21 @@ extern void serialEventRun(void) __attribute__((weak));
#endif // ARDUINO_USB_CDC_ON_BOOT #endif // ARDUINO_USB_CDC_ON_BOOT
// There is always Seria0 for UART0 // There is always Seria0 for UART0
extern HardwareSerial Serial0; extern HardwareSerial Serial0;
#if SOC_UART_HP_NUM > 1 #if SOC_UART_NUM > 1
extern HardwareSerial Serial1; extern HardwareSerial Serial1;
#endif #endif
#if SOC_UART_HP_NUM > 2 #if SOC_UART_NUM > 2
extern HardwareSerial Serial2; extern HardwareSerial Serial2;
#endif #endif
#if SOC_UART_HP_NUM > 3 #if SOC_UART_NUM > 3
extern HardwareSerial Serial3; extern HardwareSerial Serial3;
#endif #endif
#if SOC_UART_HP_NUM > 4 #if SOC_UART_NUM > 4
extern HardwareSerial Serial4; extern HardwareSerial Serial4;
#endif #endif
#if SOC_UART_NUM > 5
extern HardwareSerial Serial5;
#endif
#endif //!defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) #endif //!defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
#endif // HardwareSerial_h #endif // HardwareSerial_h

View file

@ -100,6 +100,7 @@ static bool tinyusb_device_suspended = false;
void tud_mount_cb(void) { void tud_mount_cb(void) {
tinyusb_device_mounted = true; tinyusb_device_mounted = true;
arduino_usb_event_data_t p; arduino_usb_event_data_t p;
p.suspend.remote_wakeup_en = 0;
arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_STARTED_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY); arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_STARTED_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY);
} }
@ -107,6 +108,7 @@ void tud_mount_cb(void) {
void tud_umount_cb(void) { void tud_umount_cb(void) {
tinyusb_device_mounted = false; tinyusb_device_mounted = false;
arduino_usb_event_data_t p; arduino_usb_event_data_t p;
p.suspend.remote_wakeup_en = 0;
arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY); arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY);
} }
@ -123,6 +125,7 @@ void tud_suspend_cb(bool remote_wakeup_en) {
void tud_resume_cb(void) { void tud_resume_cb(void) {
tinyusb_device_suspended = false; tinyusb_device_suspended = false;
arduino_usb_event_data_t p; arduino_usb_event_data_t p;
p.suspend.remote_wakeup_en = 0;
arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_RESUME_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY); arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_RESUME_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY);
} }

View file

@ -455,6 +455,7 @@ void USBCDC::setDebugOutput(bool en) {
} else { } else {
ets_install_putc2(NULL); ets_install_putc2(NULL);
} }
ets_install_putc1(NULL); // closes UART log output
} }
USBCDC::operator bool() const { USBCDC::operator bool() const {

View file

@ -180,7 +180,7 @@ bool String::changeBuffer(unsigned int maxStrLen) {
if (maxStrLen < sizeof(sso.buff) - 1) { if (maxStrLen < sizeof(sso.buff) - 1) {
if (isSSO() || !buffer()) { if (isSSO() || !buffer()) {
// Already using SSO, nothing to do // Already using SSO, nothing to do
uint16_t oldLen = len(); size_t oldLen = len();
setSSO(true); setSSO(true);
setLen(oldLen); setLen(oldLen);
} else { // if bufptr && !isSSO() } else { // if bufptr && !isSSO()
@ -188,7 +188,7 @@ bool String::changeBuffer(unsigned int maxStrLen) {
char temp[sizeof(sso.buff)]; char temp[sizeof(sso.buff)];
memcpy(temp, buffer(), maxStrLen); memcpy(temp, buffer(), maxStrLen);
free(wbuffer()); free(wbuffer());
uint16_t oldLen = len(); size_t oldLen = len();
setSSO(true); setSSO(true);
memcpy(wbuffer(), temp, maxStrLen); memcpy(wbuffer(), temp, maxStrLen);
setLen(oldLen); setLen(oldLen);
@ -201,7 +201,7 @@ bool String::changeBuffer(unsigned int maxStrLen) {
if (newSize > CAPACITY_MAX) { if (newSize > CAPACITY_MAX) {
return false; return false;
} }
uint16_t oldLen = len(); size_t oldLen = len();
char *newbuffer = (char *)realloc(isSSO() ? nullptr : wbuffer(), newSize); char *newbuffer = (char *)realloc(isSSO() ? nullptr : wbuffer(), newSize);
if (newbuffer) { if (newbuffer) {
size_t oldSize = capacity() + 1; // include NULL. size_t oldSize = capacity() + 1; // include NULL.

View file

@ -67,6 +67,10 @@ static void printPkgVersion(void) {
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_MAC_SYS_2_REG, EFUSE_PKG_VERSION); uint32_t pkg_ver = REG_GET_FIELD(EFUSE_RD_MAC_SYS_2_REG, EFUSE_PKG_VERSION);
chip_report_printf("%lu", pkg_ver); chip_report_printf("%lu", pkg_ver);
#elif CONFIG_IDF_TARGET_ESP32C5
// ToDo: Update this line when EFUSE_PKG_VERSION is available again for ESP32-C5
uint32_t pkg_ver = 0; //REG_GET_FIELD(EFUSE_RD_MAC_SYS2_REG, EFUSE_PKG_VERSION);
chip_report_printf("%lu", pkg_ver);
#else #else
chip_report_printf("Unknown"); chip_report_printf("Unknown");
#endif #endif
@ -88,6 +92,11 @@ static void printChipInfo(void) {
case CHIP_ESP32C6: chip_report_printf("ESP32-C6\n"); break; case CHIP_ESP32C6: chip_report_printf("ESP32-C6\n"); break;
case CHIP_ESP32H2: chip_report_printf("ESP32-H2\n"); break; case CHIP_ESP32H2: chip_report_printf("ESP32-H2\n"); break;
case CHIP_ESP32P4: chip_report_printf("ESP32-P4\n"); break; case CHIP_ESP32P4: chip_report_printf("ESP32-P4\n"); break;
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
case CHIP_ESP32C5: chip_report_printf("ESP32-C5\n"); break;
case CHIP_ESP32C61: chip_report_printf("ESP32-C61\n"); break;
case CHIP_ESP32H21: chip_report_printf("ESP32-H21\n"); break;
#endif
default: chip_report_printf("Unknown %d\n", info.model); break; default: chip_report_printf("Unknown %d\n", info.model); break;
} }
printPkgVersion(); printPkgVersion();

View file

@ -15,7 +15,7 @@
#include "esp32-hal-bt.h" #include "esp32-hal-bt.h"
#if SOC_BT_SUPPORTED #if SOC_BT_SUPPORTED
#ifdef CONFIG_BT_ENABLED #if (defined(CONFIG_BLUEDROID_ENABLED) || defined(CONFIG_NIMBLE_ENABLED)) && __has_include("esp_bt.h")
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
bool btInUse() { bool btInUse() {
@ -116,7 +116,7 @@ bool btStop() {
return false; return false;
} }
#else // CONFIG_BT_ENABLED #else // !__has_include("esp_bt.h") || !(defined(CONFIG_BLUEDROID_ENABLED) || defined(CONFIG_NIMBLE_ENABLED))
bool btStarted() { bool btStarted() {
return false; return false;
} }
@ -129,6 +129,6 @@ bool btStop() {
return false; return false;
} }
#endif /* CONFIG_BT_ENABLED */ #endif /* !__has_include("esp_bt.h") || !(defined(CONFIG_BLUEDROID_ENABLED) || defined(CONFIG_NIMBLE_ENABLED)) */
#endif /* SOC_BT_SUPPORTED */ #endif /* SOC_BT_SUPPORTED */

View file

@ -19,13 +19,16 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_log.h" #include "esp_log.h"
#include "soc/rtc.h" #include "soc/rtc.h"
#if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4) #if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4) \
&& !defined(CONFIG_IDF_TARGET_ESP32C5)
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#endif #endif
#include "soc/efuse_reg.h" #include "soc/efuse_reg.h"
#include "esp32-hal.h" #include "esp32-hal.h"
#include "esp32-hal-cpu.h" #include "esp32-hal-cpu.h"
#include "hal/timer_ll.h"
#include "esp_private/systimer.h"
#include "esp_system.h" #include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ #ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
@ -48,6 +51,8 @@
#include "esp32h2/rom/rtc.h" #include "esp32h2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/rtc.h" #include "esp32p4/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/rtc.h"
#else #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif
@ -173,13 +178,15 @@ static uint32_t calculateApb(rtc_cpu_freq_config_t *conf) {
#endif #endif
} }
#if defined(CONFIG_IDF_TARGET_ESP32) && !defined(LACT_MODULE) && !defined(LACT_TICKS_PER_US)
void esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us); //private in IDF void esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us); //private in IDF
#endif
bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) { bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
rtc_cpu_freq_config_t conf, cconf; rtc_cpu_freq_config_t conf, cconf;
uint32_t capb, apb; uint32_t capb, apb;
//Get XTAL Frequency and calculate min CPU MHz //Get XTAL Frequency and calculate min CPU MHz
#if (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4)) #if (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4) && !defined(CONFIG_IDF_TARGET_ESP32C5))
rtc_xtal_freq_t xtal = rtc_clk_xtal_freq_get(); rtc_xtal_freq_t xtal = rtc_clk_xtal_freq_get();
#endif #endif
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
@ -195,7 +202,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
} }
} }
#endif #endif
#if (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4)) #if (!defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4) && !defined(CONFIG_IDF_TARGET_ESP32C5))
if (cpu_freq_mhz > xtal && cpu_freq_mhz != 240 && cpu_freq_mhz != 160 && cpu_freq_mhz != 120 && cpu_freq_mhz != 80) { if (cpu_freq_mhz > xtal && cpu_freq_mhz != 240 && cpu_freq_mhz != 160 && cpu_freq_mhz != 120 && cpu_freq_mhz != 80) {
if (xtal >= RTC_XTAL_FREQ_40M) { if (xtal >= RTC_XTAL_FREQ_40M) {
log_e("Bad frequency: %u MHz! Options are: 240, 160, 120, 80, %u, %u and %u MHz", cpu_freq_mhz, xtal, xtal / 2, xtal / 4); log_e("Bad frequency: %u MHz! Options are: 240, 160, 120, 80, %u, %u and %u MHz", cpu_freq_mhz, xtal, xtal / 2, xtal / 4);
@ -246,7 +253,13 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
//Update APB Freq REG //Update APB Freq REG
rtc_clk_apb_freq_update(apb); rtc_clk_apb_freq_update(apb);
//Update esp_timer divisor //Update esp_timer divisor
#if CONFIG_IDF_TARGET_ESP32
#if defined(LACT_MODULE) && defined(LACT_TICKS_PER_US)
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), apb / MHZ / LACT_TICKS_PER_US);
#else
esp_timer_impl_update_apb_freq(apb / MHZ); esp_timer_impl_update_apb_freq(apb / MHZ);
#endif
#endif
} }
#endif #endif
//Update FreeRTOS Tick Divisor //Update FreeRTOS Tick Divisor
@ -265,6 +278,12 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz) {
(conf.source == SOC_CPU_CLK_SRC_PLL) ? "PLL" : ((conf.source == SOC_CPU_CLK_SRC_APLL) ? "APLL" : ((conf.source == SOC_CPU_CLK_SRC_XTAL) ? "XTAL" : "8M")), (conf.source == SOC_CPU_CLK_SRC_PLL) ? "PLL" : ((conf.source == SOC_CPU_CLK_SRC_APLL) ? "APLL" : ((conf.source == SOC_CPU_CLK_SRC_XTAL) ? "XTAL" : "8M")),
conf.source_freq_mhz, conf.div, conf.freq_mhz, apb conf.source_freq_mhz, conf.div, conf.freq_mhz, apb
); );
#elif defined(CONFIG_IDF_TARGET_ESP32C5)
log_d(
"%s: %u / %u = %u Mhz, APB: %u Hz",
(conf.source == SOC_CPU_CLK_SRC_PLL_F240M || conf.source == SOC_CPU_CLK_SRC_PLL_F160M) ? "PLL" : ((conf.source == SOC_CPU_CLK_SRC_XTAL) ? "XTAL" : "8M"),
conf.source_freq_mhz, conf.div, conf.freq_mhz, apb
);
#else #else
log_d( log_d(
"%s: %u / %u = %u Mhz, APB: %u Hz", (conf.source == SOC_CPU_CLK_SRC_PLL) ? "PLL" : ((conf.source == SOC_CPU_CLK_SRC_XTAL) ? "XTAL" : "17.5M"), "%s: %u / %u = %u Mhz, APB: %u Hz", (conf.source == SOC_CPU_CLK_SRC_PLL) ? "PLL" : ((conf.source == SOC_CPU_CLK_SRC_XTAL) ? "XTAL" : "17.5M"),

View file

@ -173,7 +173,7 @@ extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL) { if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL) {
gpio_set_level((gpio_num_t)pin, val); gpio_set_level((gpio_num_t)pin, val);
} else { } else {
log_e("IO %i is not set as GPIO.", pin); log_e("IO %i is not set as GPIO. Execute digitalMode(%i, OUTPUT) first.", pin, pin);
} }
} }
@ -182,14 +182,12 @@ extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin) {
if (pin == RGB_BUILTIN) { if (pin == RGB_BUILTIN) {
return RGB_BUILTIN_storage; return RGB_BUILTIN_storage;
} }
#endif #endif // RGB_BUILTIN
// This work when the pin is set as GPIO and in INPUT mode. For all other pin functions, it may return inconsistent response
if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL) { if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) == NULL) {
return gpio_get_level((gpio_num_t)pin); log_w("IO %i is not set as GPIO. digitalRead() may return an inconsistent value.", pin);
} else {
log_e("IO %i is not set as GPIO.", pin);
return 0;
} }
return gpio_get_level((gpio_num_t)pin);
} }
static void ARDUINO_ISR_ATTR __onPinInterrupt(void *arg) { static void ARDUINO_ISR_ATTR __onPinInterrupt(void *arg) {

View file

@ -0,0 +1,452 @@
// Copyright 2015-2025 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp32-hal-i2c.h"
#if SOC_I2C_SUPPORTED
#include "esp_idf_version.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0)
#include "esp32-hal.h"
#if !CONFIG_DISABLE_HAL_LOCKS
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#endif
#include "esp_attr.h"
#include "esp_system.h"
#include "soc/soc_caps.h"
#include "driver/i2c_master.h"
#include "esp32-hal-periman.h"
typedef volatile struct {
bool initialized;
uint32_t frequency;
#if !CONFIG_DISABLE_HAL_LOCKS
SemaphoreHandle_t lock;
#endif
int8_t scl;
int8_t sda;
i2c_master_bus_handle_t bus_handle;
i2c_master_dev_handle_t dev_handles[128];
} i2c_bus_t;
static i2c_bus_t bus[SOC_I2C_NUM];
static bool i2cDetachBus(void *bus_i2c_num) {
uint8_t i2c_num = (int)bus_i2c_num - 1;
if (!bus[i2c_num].initialized) {
return true;
}
esp_err_t err = i2cDeinit(i2c_num);
if (err != ESP_OK) {
log_e("i2cDeinit failed with error: %d", err);
return false;
}
return true;
}
void *i2cBusHandle(uint8_t i2c_num) {
if (i2c_num >= SOC_I2C_NUM) {
return NULL;
}
return bus[i2c_num].bus_handle;
}
bool i2cIsInit(uint8_t i2c_num) {
if (i2c_num >= SOC_I2C_NUM) {
return false;
}
return bus[i2c_num].initialized;
}
esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) {
esp_err_t ret = ESP_OK;
if (i2c_num >= SOC_I2C_NUM) {
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_DISABLE_HAL_LOCKS
if (bus[i2c_num].lock == NULL) {
bus[i2c_num].lock = xSemaphoreCreateMutex();
if (bus[i2c_num].lock == NULL) {
log_e("xSemaphoreCreateMutex failed");
return ESP_ERR_NO_MEM;
}
}
//acquire lock
if (xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) {
log_e("could not acquire lock");
return ESP_FAIL;
}
#endif
if (bus[i2c_num].initialized) {
log_e("bus is already initialized");
ret = ESP_FAIL;
goto init_fail;
}
if (!frequency) {
frequency = 100000UL;
} else if (frequency > 1000000UL) {
frequency = 1000000UL;
}
perimanSetBusDeinit(ESP32_BUS_TYPE_I2C_MASTER_SDA, i2cDetachBus);
perimanSetBusDeinit(ESP32_BUS_TYPE_I2C_MASTER_SCL, i2cDetachBus);
if (!perimanClearPinBus(sda) || !perimanClearPinBus(scl)) {
ret = ESP_FAIL;
goto init_fail;
}
log_i("Initializing I2C Master: num=%u sda=%d scl=%d freq=%lu", i2c_num, sda, scl, frequency);
i2c_master_bus_handle_t bus_handle = NULL;
i2c_master_bus_config_t bus_config;
memset(&bus_config, 0, sizeof(i2c_master_bus_config_t));
bus_config.i2c_port = (i2c_port_num_t)i2c_num;
bus_config.sda_io_num = (gpio_num_t)sda;
bus_config.scl_io_num = (gpio_num_t)scl;
#if SOC_LP_I2C_SUPPORTED
if (i2c_num >= SOC_HP_I2C_NUM) {
bus_config.lp_source_clk = LP_I2C_SCLK_DEFAULT;
} else
#endif
{
bus_config.clk_source = I2C_CLK_SRC_DEFAULT;
}
bus_config.glitch_ignore_cnt = 7;
bus_config.intr_priority = 0; // auto
bus_config.trans_queue_depth = 0; // only valid in asynchronous transaction, which Arduino does not use
bus_config.flags.enable_internal_pullup = 1;
#if SOC_I2C_SUPPORT_SLEEP_RETENTION
bus_config.flags.allow_pd = 1; // backup/restore the I2C registers before/after entering/exist sleep mode
#endif
ret = i2c_new_master_bus(&bus_config, &bus_handle);
if (ret != ESP_OK) {
log_e("i2c_new_master_bus failed: [%d] %s", ret, esp_err_to_name(ret));
} else {
bus[i2c_num].initialized = true;
bus[i2c_num].frequency = frequency;
bus[i2c_num].scl = scl;
bus[i2c_num].sda = sda;
bus[i2c_num].bus_handle = bus_handle;
for (uint8_t i = 0; i < 128; i++) {
bus[i2c_num].dev_handles[i] = NULL;
}
if (!perimanSetPinBus(sda, ESP32_BUS_TYPE_I2C_MASTER_SDA, (void *)(i2c_num + 1), i2c_num, -1)
|| !perimanSetPinBus(scl, ESP32_BUS_TYPE_I2C_MASTER_SCL, (void *)(i2c_num + 1), i2c_num, -1)) {
#if !CONFIG_DISABLE_HAL_LOCKS
//release lock so that i2cDetachBus can execute i2cDeinit
xSemaphoreGive(bus[i2c_num].lock);
#endif
i2cDetachBus((void *)(i2c_num + 1));
return ESP_FAIL;
}
}
init_fail:
#if !CONFIG_DISABLE_HAL_LOCKS
//release lock
xSemaphoreGive(bus[i2c_num].lock);
#endif
return ret;
}
esp_err_t i2cDeinit(uint8_t i2c_num) {
esp_err_t err = ESP_FAIL;
if (i2c_num >= SOC_I2C_NUM) {
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_DISABLE_HAL_LOCKS
//acquire lock
if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) {
log_e("could not acquire lock");
return err;
}
#endif
if (!bus[i2c_num].initialized) {
log_e("bus is not initialized");
} else {
// remove devices from the bus
for (uint8_t i = 0; i < 128; i++) {
if (bus[i2c_num].dev_handles[i] != NULL) {
err = i2c_master_bus_rm_device(bus[i2c_num].dev_handles[i]);
bus[i2c_num].dev_handles[i] = NULL;
if (err != ESP_OK) {
log_e("i2c_master_bus_rm_device failed: [%d] %s", err, esp_err_to_name(err));
}
}
}
err = i2c_del_master_bus(bus[i2c_num].bus_handle);
if (err != ESP_OK) {
log_e("i2c_del_master_bus failed: [%d] %s", err, esp_err_to_name(err));
} else {
bus[i2c_num].initialized = false;
perimanClearPinBus(bus[i2c_num].scl);
perimanClearPinBus(bus[i2c_num].sda);
bus[i2c_num].scl = -1;
bus[i2c_num].sda = -1;
bus[i2c_num].bus_handle = NULL;
}
}
#if !CONFIG_DISABLE_HAL_LOCKS
//release lock
xSemaphoreGive(bus[i2c_num].lock);
#endif
return err;
}
static esp_err_t i2cAddDeviceIfNeeded(uint8_t i2c_num, uint16_t address) {
esp_err_t ret = ESP_OK;
if (bus[i2c_num].dev_handles[address] == NULL) {
i2c_master_dev_handle_t dev_handle = NULL;
i2c_device_config_t dev_config;
memset(&dev_config, 0, sizeof(i2c_device_config_t));
dev_config.dev_addr_length = I2C_ADDR_BIT_LEN_7; // Arduino supports only 7bit addresses
dev_config.device_address = address;
dev_config.scl_speed_hz = bus[i2c_num].frequency;
dev_config.scl_wait_us = 0;
dev_config.flags.disable_ack_check = 0;
ret = i2c_master_bus_add_device(bus[i2c_num].bus_handle, &dev_config, &dev_handle);
if (ret != ESP_OK) {
log_e("i2c_master_bus_add_device failed: [%d] %s", ret, esp_err_to_name(ret));
} else {
bus[i2c_num].dev_handles[address] = dev_handle;
log_v("added device: bus=%u addr=0x%x handle=0x%08x", i2c_num, address, dev_handle);
}
}
return ret;
}
esp_err_t i2cWrite(uint8_t i2c_num, uint16_t address, const uint8_t *buff, size_t size, uint32_t timeOutMillis) {
esp_err_t ret = ESP_FAIL;
// i2c_cmd_handle_t cmd = NULL;
if (i2c_num >= SOC_I2C_NUM) {
return ESP_ERR_INVALID_ARG;
}
if (address >= 128) {
log_e("Only 7bit I2C addresses are supported");
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_DISABLE_HAL_LOCKS
//acquire lock
if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) {
log_e("could not acquire lock");
return ret;
}
#endif
if (!bus[i2c_num].initialized) {
log_e("bus is not initialized");
goto end;
}
if (size == 0) {
// Probe device
ret = i2c_master_probe(bus[i2c_num].bus_handle, address, timeOutMillis);
if (ret != ESP_OK) {
log_v("i2c_master_probe failed: [%d] %s", ret, esp_err_to_name(ret));
}
} else {
// writing data to device
ret = i2cAddDeviceIfNeeded(i2c_num, address);
if (ret != ESP_OK) {
goto end;
}
log_v("i2c_master_transmit: bus=%u addr=0x%x handle=0x%08x size=%u", i2c_num, address, bus[i2c_num].dev_handles[address], size);
ret = i2c_master_transmit(bus[i2c_num].dev_handles[address], buff, size, timeOutMillis);
if (ret != ESP_OK) {
log_e("i2c_master_transmit failed: [%d] %s", ret, esp_err_to_name(ret));
goto end;
}
// wait for transactions to finish (is it needed with sync transactions?)
// ret = i2c_master_bus_wait_all_done(bus[i2c_num].bus_handle, timeOutMillis);
// if (ret != ESP_OK) {
// log_e("i2c_master_bus_wait_all_done failed: [%d] %s", ret, esp_err_to_name(ret));
// goto end;
// }
}
end:
#if !CONFIG_DISABLE_HAL_LOCKS
//release lock
xSemaphoreGive(bus[i2c_num].lock);
#endif
return ret;
}
esp_err_t i2cRead(uint8_t i2c_num, uint16_t address, uint8_t *buff, size_t size, uint32_t timeOutMillis, size_t *readCount) {
esp_err_t ret = ESP_FAIL;
*readCount = 0;
if (i2c_num >= SOC_I2C_NUM) {
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_DISABLE_HAL_LOCKS
//acquire lock
if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) {
log_e("could not acquire lock");
return ret;
}
#endif
if (!bus[i2c_num].initialized) {
log_e("bus is not initialized");
goto end;
}
ret = i2cAddDeviceIfNeeded(i2c_num, address);
if (ret != ESP_OK) {
goto end;
}
log_v("i2c_master_receive: bus=%u addr=0x%x handle=0x%08x size=%u", i2c_num, address, bus[i2c_num].dev_handles[address], size);
ret = i2c_master_receive(bus[i2c_num].dev_handles[address], buff, size, timeOutMillis);
if (ret != ESP_OK) {
log_e("i2c_master_receive failed: [%d] %s", ret, esp_err_to_name(ret));
goto end;
}
// wait for transactions to finish (is it needed with sync transactions?)
// ret = i2c_master_bus_wait_all_done(bus[i2c_num].bus_handle, timeOutMillis);
// if (ret != ESP_OK) {
// log_e("i2c_master_bus_wait_all_done failed: [%d] %s", ret, esp_err_to_name(ret));
// goto end;
// }
*readCount = size;
end:
#if !CONFIG_DISABLE_HAL_LOCKS
//release lock
xSemaphoreGive(bus[i2c_num].lock);
#endif
return ret;
}
esp_err_t i2cWriteReadNonStop(
uint8_t i2c_num, uint16_t address, const uint8_t *wbuff, size_t wsize, uint8_t *rbuff, size_t rsize, uint32_t timeOutMillis, size_t *readCount
) {
esp_err_t ret = ESP_FAIL;
*readCount = 0;
if (i2c_num >= SOC_I2C_NUM) {
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_DISABLE_HAL_LOCKS
//acquire lock
if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) {
log_e("could not acquire lock");
return ret;
}
#endif
if (!bus[i2c_num].initialized) {
log_e("bus is not initialized");
goto end;
}
ret = i2cAddDeviceIfNeeded(i2c_num, address);
if (ret != ESP_OK) {
goto end;
}
log_v("i2c_master_transmit_receive: bus=%u addr=0x%x handle=0x%08x write=%u read=%u", i2c_num, address, bus[i2c_num].dev_handles[address], wsize, rsize);
ret = i2c_master_transmit_receive(bus[i2c_num].dev_handles[address], wbuff, wsize, rbuff, rsize, timeOutMillis);
if (ret != ESP_OK) {
log_e("i2c_master_transmit_receive failed: [%d] %s", ret, esp_err_to_name(ret));
goto end;
}
// wait for transactions to finish (is it needed with sync transactions?)
// ret = i2c_master_bus_wait_all_done(bus[i2c_num].bus_handle, timeOutMillis);
// if (ret != ESP_OK) {
// log_e("i2c_master_bus_wait_all_done failed: [%d] %s", ret, esp_err_to_name(ret));
// goto end;
// }
*readCount = rsize;
end:
#if !CONFIG_DISABLE_HAL_LOCKS
//release lock
xSemaphoreGive(bus[i2c_num].lock);
#endif
return ret;
}
esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency) {
esp_err_t ret = ESP_FAIL;
if (i2c_num >= SOC_I2C_NUM) {
return ESP_ERR_INVALID_ARG;
}
#if !CONFIG_DISABLE_HAL_LOCKS
//acquire lock
if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) {
log_e("could not acquire lock");
return ret;
}
#endif
if (!bus[i2c_num].initialized) {
log_e("bus is not initialized");
goto end;
}
if (bus[i2c_num].frequency == frequency) {
ret = ESP_OK;
goto end;
}
if (!frequency) {
frequency = 100000UL;
} else if (frequency > 1000000UL) {
frequency = 1000000UL;
}
bus[i2c_num].frequency = frequency;
// loop through devices, remove them and then re-add them with the new frequency
for (uint8_t i = 0; i < 128; i++) {
if (bus[i2c_num].dev_handles[i] != NULL) {
ret = i2c_master_bus_rm_device(bus[i2c_num].dev_handles[i]);
if (ret != ESP_OK) {
log_e("i2c_master_bus_rm_device failed: [%d] %s", ret, esp_err_to_name(ret));
goto end;
} else {
bus[i2c_num].dev_handles[i] = NULL;
ret = i2cAddDeviceIfNeeded(i2c_num, i);
if (ret != ESP_OK) {
goto end;
}
}
}
}
end:
#if !CONFIG_DISABLE_HAL_LOCKS
//release lock
xSemaphoreGive(bus[i2c_num].lock);
#endif
return ret;
}
esp_err_t i2cGetClock(uint8_t i2c_num, uint32_t *frequency) {
if (i2c_num >= SOC_I2C_NUM) {
return ESP_ERR_INVALID_ARG;
}
if (!bus[i2c_num].initialized) {
log_e("bus is not initialized");
return ESP_FAIL;
}
*frequency = bus[i2c_num].frequency;
return ESP_OK;
}
#endif /* ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) */
#endif /* SOC_I2C_SUPPORTED */

View file

@ -43,7 +43,10 @@
#include "soc/i2c_struct.h" #include "soc/i2c_struct.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "hal/i2c_ll.h" #include "hal/i2c_ll.h"
#include "hal/i2c_types.h"
#ifndef CONFIG_IDF_TARGET_ESP32C5
#include "hal/clk_gate_ll.h" #include "hal/clk_gate_ll.h"
#endif
#include "esp32-hal-log.h" #include "esp32-hal-log.h"
#include "esp32-hal-i2c-slave.h" #include "esp32-hal-i2c-slave.h"
#include "esp32-hal-periman.h" #include "esp32-hal-periman.h"
@ -325,7 +328,7 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
frequency = 100000L; frequency = 100000L;
} }
frequency = (frequency * 5) / 4; frequency = (frequency * 5) / 4;
#if !defined(CONFIG_IDF_TARGET_ESP32P4) #if !defined(CONFIG_IDF_TARGET_ESP32P4) && !defined(CONFIG_IDF_TARGET_ESP32C5)
if (i2c->num == 0) { if (i2c->num == 0) {
periph_ll_enable_clk_clear_rst(PERIPH_I2C0_MODULE); periph_ll_enable_clk_clear_rst(PERIPH_I2C0_MODULE);
#if SOC_HP_I2C_NUM > 1 #if SOC_HP_I2C_NUM > 1
@ -335,8 +338,19 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
} }
#endif // !defined(CONFIG_IDF_TARGET_ESP32P4) #endif // !defined(CONFIG_IDF_TARGET_ESP32P4)
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)) || (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0)) \
|| (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 3) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 0))
i2c_ll_set_mode(i2c->dev, I2C_BUS_MODE_SLAVE);
i2c_ll_enable_pins_open_drain(i2c->dev, true);
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
i2c_ll_enable_fifo_mode(i2c->dev, true);
#else
i2c_ll_slave_set_fifo_mode(i2c->dev, true);
#endif
#else
i2c_ll_slave_init(i2c->dev); i2c_ll_slave_init(i2c->dev);
i2c_ll_slave_set_fifo_mode(i2c->dev, true); i2c_ll_slave_set_fifo_mode(i2c->dev, true);
#endif
i2c_ll_set_slave_addr(i2c->dev, slaveID, false); i2c_ll_set_slave_addr(i2c->dev, slaveID, false);
i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT); i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT);
i2c_slave_set_frequency(i2c, frequency); i2c_slave_set_frequency(i2c, frequency);
@ -357,7 +371,11 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
i2c_ll_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK); i2c_ll_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK);
i2c_ll_clear_intr_mask(i2c->dev, I2C_LL_INTR_MASK); i2c_ll_clear_intr_mask(i2c->dev, I2C_LL_INTR_MASK);
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 2)
i2c_ll_enable_fifo_mode(i2c->dev, true);
#else
i2c_ll_slave_set_fifo_mode(i2c->dev, true); i2c_ll_slave_set_fifo_mode(i2c->dev, true);
#endif
if (!i2c->intr_handle) { if (!i2c->intr_handle) {
uint32_t flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED; uint32_t flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED;
@ -548,6 +566,9 @@ static bool i2c_slave_set_frequency(i2c_slave_struct_t *i2c, uint32_t clk_speed)
i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_APB); /*!< I2C source clock from APB, 80M*/ i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_APB); /*!< I2C source clock from APB, 80M*/
} }
#elif SOC_I2C_SUPPORT_XTAL #elif SOC_I2C_SUPPORT_XTAL
#ifndef XTAL_CLK_FREQ
#define XTAL_CLK_FREQ APB_CLK_FREQ
#endif
i2c_ll_master_cal_bus_clk(XTAL_CLK_FREQ, clk_speed, &clk_cal); i2c_ll_master_cal_bus_clk(XTAL_CLK_FREQ, clk_speed, &clk_cal);
I2C_CLOCK_SRC_ATOMIC() { I2C_CLOCK_SRC_ATOMIC() {
i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_XTAL); /*!< I2C source clock from XTAL, 40M */ i2c_ll_set_source_clk(i2c->dev, SOC_MOD_CLK_XTAL); /*!< I2C source clock from XTAL, 40M */

View file

@ -15,6 +15,8 @@
#include "esp32-hal-i2c.h" #include "esp32-hal-i2c.h"
#if SOC_I2C_SUPPORTED #if SOC_I2C_SUPPORTED
#include "esp_idf_version.h"
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 0)
#include "esp32-hal.h" #include "esp32-hal.h"
#if !CONFIG_DISABLE_HAL_LOCKS #if !CONFIG_DISABLE_HAL_LOCKS
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
@ -429,4 +431,5 @@ esp_err_t i2cGetClock(uint8_t i2c_num, uint32_t *frequency) {
return ESP_OK; return ESP_OK;
} }
#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 0) */
#endif /* SOC_I2C_SUPPORTED */ #endif /* SOC_I2C_SUPPORTED */

View file

@ -19,6 +19,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#if SOC_I2C_SUPPORTED #if SOC_I2C_SUPPORTED
#include "esp_idf_version.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -39,6 +40,10 @@ esp_err_t i2cWriteReadNonStop(
); );
bool i2cIsInit(uint8_t i2c_num); bool i2cIsInit(uint8_t i2c_num);
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0)
void *i2cBusHandle(uint8_t i2c_num);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -22,6 +22,9 @@
#include "soc/gpio_sig_map.h" #include "soc/gpio_sig_map.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "hal/ledc_ll.h" #include "hal/ledc_ll.h"
#if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
#include <math.h>
#endif
#ifdef SOC_LEDC_SUPPORT_HS_MODE #ifdef SOC_LEDC_SUPPORT_HS_MODE
#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM << 1) #define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM << 1)
@ -45,6 +48,96 @@ typedef struct {
ledc_periph_t ledc_handle = {0}; ledc_periph_t ledc_handle = {0};
// Helper function to find a timer with matching frequency and resolution
static bool find_matching_timer(uint8_t speed_mode, uint32_t freq, uint8_t resolution, uint8_t *timer_num) {
log_d("Searching for timer with freq=%u, resolution=%u", freq, resolution);
// Check all channels to find one with matching frequency and resolution
for (uint8_t i = 0; i < SOC_GPIO_PIN_COUNT; i++) {
if (!perimanPinIsValid(i)) {
continue;
}
peripheral_bus_type_t type = perimanGetPinBusType(i);
if (type == ESP32_BUS_TYPE_LEDC) {
ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(i, ESP32_BUS_TYPE_LEDC);
if (bus != NULL && (bus->channel / SOC_LEDC_CHANNEL_NUM) == speed_mode && bus->freq_hz == freq && bus->channel_resolution == resolution) {
log_d("Found matching timer %u for freq=%u, resolution=%u", bus->timer_num, freq, resolution);
*timer_num = bus->timer_num;
return true;
}
}
}
log_d("No matching timer found for freq=%u, resolution=%u", freq, resolution);
return false;
}
// Helper function to find an unused timer
static bool find_free_timer(uint8_t speed_mode, uint8_t *timer_num) {
// Check which timers are in use
uint8_t used_timers = 0;
for (uint8_t i = 0; i < SOC_GPIO_PIN_COUNT; i++) {
if (!perimanPinIsValid(i)) {
continue;
}
peripheral_bus_type_t type = perimanGetPinBusType(i);
if (type == ESP32_BUS_TYPE_LEDC) {
ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(i, ESP32_BUS_TYPE_LEDC);
if (bus != NULL && (bus->channel / SOC_LEDC_CHANNEL_NUM) == speed_mode) {
log_d("Timer %u is in use by channel %u", bus->timer_num, bus->channel);
used_timers |= (1 << bus->timer_num);
}
}
}
#ifndef SOC_LEDC_TIMER_NUM
#define SOC_LEDC_TIMER_NUM 4
#endif
// Find first unused timer
for (uint8_t i = 0; i < SOC_LEDC_TIMER_NUM; i++) {
if (!(used_timers & (1 << i))) {
log_d("Found free timer %u", i);
*timer_num = i;
return true;
}
}
log_e("No free timers available");
return false;
}
// Helper function to remove a channel from a timer and clear timer if no channels are using it
static void remove_channel_from_timer(uint8_t speed_mode, uint8_t timer_num, uint8_t channel) {
log_d("Removing channel %u from timer %u in speed_mode %u", channel, timer_num, speed_mode);
// Check if any other channels are using this timer
bool timer_in_use = false;
for (uint8_t i = 0; i < SOC_GPIO_PIN_COUNT; i++) {
if (!perimanPinIsValid(i)) {
continue;
}
peripheral_bus_type_t type = perimanGetPinBusType(i);
if (type == ESP32_BUS_TYPE_LEDC) {
ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(i, ESP32_BUS_TYPE_LEDC);
if (bus != NULL && (bus->channel / SOC_LEDC_CHANNEL_NUM) == speed_mode && bus->timer_num == timer_num && bus->channel != channel) {
log_d("Timer %u is still in use by channel %u", timer_num, bus->channel);
timer_in_use = true;
break;
}
}
}
if (!timer_in_use) {
log_d("No other channels using timer %u, deconfiguring timer", timer_num);
// Stop the timer
ledc_timer_pause(speed_mode, timer_num);
// Deconfigure the timer
ledc_timer_config_t ledc_timer;
memset((void *)&ledc_timer, 0, sizeof(ledc_timer_config_t));
ledc_timer.speed_mode = speed_mode;
ledc_timer.timer_num = timer_num;
ledc_timer.deconfigure = true;
ledc_timer_config(&ledc_timer);
}
}
static bool fade_initialized = false; static bool fade_initialized = false;
static ledc_clk_cfg_t clock_source = LEDC_DEFAULT_CLK; static ledc_clk_cfg_t clock_source = LEDC_DEFAULT_CLK;
@ -81,6 +174,8 @@ static bool ledcDetachBus(void *bus) {
} }
pinMatrixOutDetach(handle->pin, false, false); pinMatrixOutDetach(handle->pin, false, false);
if (!channel_found) { if (!channel_found) {
uint8_t group = (handle->channel / SOC_LEDC_CHANNEL_NUM);
remove_channel_from_timer(group, handle->timer_num, handle->channel % SOC_LEDC_CHANNEL_NUM);
ledc_handle.used_channels &= ~(1UL << handle->channel); ledc_handle.used_channels &= ~(1UL << handle->channel);
} }
free(handle); free(handle);
@ -117,32 +212,59 @@ bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t c
return false; return false;
} }
uint8_t group = (channel / 8), timer = ((channel / 2) % 4); uint8_t group = (channel / SOC_LEDC_CHANNEL_NUM);
uint8_t timer = 0;
bool channel_used = ledc_handle.used_channels & (1UL << channel); bool channel_used = ledc_handle.used_channels & (1UL << channel);
if (channel_used) { if (channel_used) {
log_i("Channel %u is already set up, given frequency and resolution will be ignored", channel); log_i("Channel %u is already set up, given frequency and resolution will be ignored", channel);
if (ledc_set_pin(pin, group, channel % 8) != ESP_OK) { if (ledc_set_pin(pin, group, channel % SOC_LEDC_CHANNEL_NUM) != ESP_OK) {
log_e("Attaching pin to already used channel failed!"); log_e("Attaching pin to already used channel failed!");
return false; return false;
} }
} else { } else {
ledc_timer_config_t ledc_timer = {.speed_mode = group, .timer_num = timer, .duty_resolution = resolution, .freq_hz = freq, .clk_cfg = clock_source}; // Find a timer with matching frequency and resolution, or a free timer
if (!find_matching_timer(group, freq, resolution, &timer)) {
if (!find_free_timer(group, &timer)) {
log_w("No free timers available for speed mode %u", group);
return false;
}
// Configure the timer if we're using a new one
ledc_timer_config_t ledc_timer;
memset((void *)&ledc_timer, 0, sizeof(ledc_timer_config_t));
ledc_timer.speed_mode = group;
ledc_timer.timer_num = timer;
ledc_timer.duty_resolution = resolution;
ledc_timer.freq_hz = freq;
ledc_timer.clk_cfg = clock_source;
if (ledc_timer_config(&ledc_timer) != ESP_OK) { if (ledc_timer_config(&ledc_timer) != ESP_OK) {
log_e("ledc setup failed!"); log_e("ledc setup failed!");
return false; return false;
} }
}
uint32_t duty = ledc_get_duty(group, (channel % 8)); uint32_t duty = ledc_get_duty(group, (channel % SOC_LEDC_CHANNEL_NUM));
ledc_channel_config_t ledc_channel;
memset((void *)&ledc_channel, 0, sizeof(ledc_channel_config_t));
ledc_channel.speed_mode = group;
ledc_channel.channel = (channel % SOC_LEDC_CHANNEL_NUM);
ledc_channel.timer_sel = timer;
ledc_channel.intr_type = LEDC_INTR_DISABLE;
ledc_channel.gpio_num = pin;
ledc_channel.duty = duty;
ledc_channel.hpoint = 0;
ledc_channel_config_t ledc_channel = {
.speed_mode = group, .channel = (channel % 8), .timer_sel = timer, .intr_type = LEDC_INTR_DISABLE, .gpio_num = pin, .duty = duty, .hpoint = 0
};
ledc_channel_config(&ledc_channel); ledc_channel_config(&ledc_channel);
} }
ledc_channel_handle_t *handle = (ledc_channel_handle_t *)malloc(sizeof(ledc_channel_handle_t)); ledc_channel_handle_t *handle = (ledc_channel_handle_t *)malloc(sizeof(ledc_channel_handle_t));
handle->pin = pin; handle->pin = pin;
handle->channel = channel; handle->channel = channel;
handle->timer_num = timer;
handle->freq_hz = freq;
#ifndef SOC_LEDC_SUPPORT_FADE_STOP #ifndef SOC_LEDC_SUPPORT_FADE_STOP
handle->lock = NULL; handle->lock = NULL;
#endif #endif
@ -158,7 +280,7 @@ bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t c
ledc_handle.used_channels |= 1UL << channel; ledc_handle.used_channels |= 1UL << channel;
} }
if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_LEDC, (void *)handle, group, channel)) { if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_LEDC, (void *)handle, channel, timer)) {
ledcDetachBus((void *)handle); ledcDetachBus((void *)handle);
return false; return false;
} }
@ -175,14 +297,40 @@ bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) {
} }
uint8_t channel = __builtin_ctz(free_channel); // Convert the free_channel bit to channel number uint8_t channel = __builtin_ctz(free_channel); // Convert the free_channel bit to channel number
return ledcAttachChannel(pin, freq, resolution, channel); // Try the first available channel
if (ledcAttachChannel(pin, freq, resolution, channel)) {
return true;
}
#ifdef SOC_LEDC_SUPPORT_HS_MODE
// If first attempt failed and HS mode is supported, try to find a free channel in group 1
if ((channel / SOC_LEDC_CHANNEL_NUM) == 0) { // First attempt was in group 0
log_d("LEDC: Group 0 channel %u failed, trying to find a free channel in group 1", channel);
// Find free channels specifically in group 1
uint32_t group1_mask = ((1UL << SOC_LEDC_CHANNEL_NUM) - 1) << SOC_LEDC_CHANNEL_NUM;
int group1_free_channel = (~ledc_handle.used_channels) & group1_mask;
if (group1_free_channel != 0) {
uint8_t group1_channel = __builtin_ctz(group1_free_channel);
if (ledcAttachChannel(pin, freq, resolution, group1_channel)) {
return true;
}
}
}
#endif
log_e(
"No free timers available for freq=%u, resolution=%u. To attach a new channel, use the same frequency and resolution as an already attached channel to "
"share its timer.",
freq, resolution
);
return false;
} }
bool ledcWrite(uint8_t pin, uint32_t duty) { bool ledcWrite(uint8_t pin, uint32_t duty) {
ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC);
if (bus != NULL) { if (bus != NULL) {
uint8_t group = (bus->channel / 8), channel = (bus->channel % 8); uint8_t group = (bus->channel / SOC_LEDC_CHANNEL_NUM), channel = (bus->channel % SOC_LEDC_CHANNEL_NUM);
//Fixing if all bits in resolution is set = LEDC FULL ON //Fixing if all bits in resolution is set = LEDC FULL ON
uint32_t max_duty = (1 << bus->channel_resolution) - 1; uint32_t max_duty = (1 << bus->channel_resolution) - 1;
@ -191,8 +339,14 @@ bool ledcWrite(uint8_t pin, uint32_t duty) {
duty = max_duty + 1; duty = max_duty + 1;
} }
ledc_set_duty(group, channel, duty); if (ledc_set_duty(group, channel, duty) != ESP_OK) {
ledc_update_duty(group, channel); log_e("ledc_set_duty failed");
return false;
}
if (ledc_update_duty(group, channel) != ESP_OK) {
log_e("ledc_update_duty failed");
return false;
}
return true; return true;
} }
@ -205,7 +359,11 @@ bool ledcWriteChannel(uint8_t channel, uint32_t duty) {
log_e("Channel %u is not available (maximum %u) or not used!", channel, LEDC_CHANNELS); log_e("Channel %u is not available (maximum %u) or not used!", channel, LEDC_CHANNELS);
return false; return false;
} }
uint8_t group = (channel / 8), timer = ((channel / 2) % 4); uint8_t group = (channel / SOC_LEDC_CHANNEL_NUM);
ledc_timer_t timer;
// Get the actual timer being used by this channel
ledc_ll_get_channel_timer(LEDC_LL_GET_HW(), group, (channel % SOC_LEDC_CHANNEL_NUM), &timer);
//Fixing if all bits in resolution is set = LEDC FULL ON //Fixing if all bits in resolution is set = LEDC FULL ON
uint32_t resolution = 0; uint32_t resolution = 0;
@ -217,8 +375,14 @@ bool ledcWriteChannel(uint8_t channel, uint32_t duty) {
duty = max_duty + 1; duty = max_duty + 1;
} }
ledc_set_duty(group, channel, duty); if (ledc_set_duty(group, channel, duty) != ESP_OK) {
ledc_update_duty(group, channel); log_e("ledc_set_duty failed");
return false;
}
if (ledc_update_duty(group, channel) != ESP_OK) {
log_e("ledc_update_duty failed");
return false;
}
return true; return true;
} }
@ -227,7 +391,7 @@ uint32_t ledcRead(uint8_t pin) {
ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC);
if (bus != NULL) { if (bus != NULL) {
uint8_t group = (bus->channel / 8), channel = (bus->channel % 8); uint8_t group = (bus->channel / SOC_LEDC_CHANNEL_NUM), channel = (bus->channel % SOC_LEDC_CHANNEL_NUM);
return ledc_get_duty(group, channel); return ledc_get_duty(group, channel);
} }
return 0; return 0;
@ -239,8 +403,8 @@ uint32_t ledcReadFreq(uint8_t pin) {
if (!ledcRead(pin)) { if (!ledcRead(pin)) {
return 0; return 0;
} }
uint8_t group = (bus->channel / 8), timer = ((bus->channel / 2) % 4); uint8_t group = (bus->channel / SOC_LEDC_CHANNEL_NUM);
return ledc_get_freq(group, timer); return ledc_get_freq(group, bus->timer_num);
} }
return 0; return 0;
} }
@ -254,9 +418,15 @@ uint32_t ledcWriteTone(uint8_t pin, uint32_t freq) {
return 0; return 0;
} }
uint8_t group = (bus->channel / 8), timer = ((bus->channel / 2) % 4); uint8_t group = (bus->channel / SOC_LEDC_CHANNEL_NUM);
ledc_timer_config_t ledc_timer = {.speed_mode = group, .timer_num = timer, .duty_resolution = 10, .freq_hz = freq, .clk_cfg = clock_source}; ledc_timer_config_t ledc_timer;
memset((void *)&ledc_timer, 0, sizeof(ledc_timer_config_t));
ledc_timer.speed_mode = group;
ledc_timer.timer_num = bus->timer_num;
ledc_timer.duty_resolution = 10;
ledc_timer.freq_hz = freq;
ledc_timer.clk_cfg = clock_source;
if (ledc_timer_config(&ledc_timer) != ESP_OK) { if (ledc_timer_config(&ledc_timer) != ESP_OK) {
log_e("ledcWriteTone configuration failed!"); log_e("ledcWriteTone configuration failed!");
@ -264,7 +434,7 @@ uint32_t ledcWriteTone(uint8_t pin, uint32_t freq) {
} }
bus->channel_resolution = 10; bus->channel_resolution = 10;
uint32_t res_freq = ledc_get_freq(group, timer); uint32_t res_freq = ledc_get_freq(group, bus->timer_num);
ledcWrite(pin, 0x1FF); ledcWrite(pin, 0x1FF);
return res_freq; return res_freq;
} }
@ -305,16 +475,22 @@ uint32_t ledcChangeFrequency(uint8_t pin, uint32_t freq, uint8_t resolution) {
log_e("LEDC pin %u - resolution is zero or it is too big (maximum %u)", pin, LEDC_MAX_BIT_WIDTH); log_e("LEDC pin %u - resolution is zero or it is too big (maximum %u)", pin, LEDC_MAX_BIT_WIDTH);
return 0; return 0;
} }
uint8_t group = (bus->channel / 8), timer = ((bus->channel / 2) % 4); uint8_t group = (bus->channel / SOC_LEDC_CHANNEL_NUM);
ledc_timer_config_t ledc_timer = {.speed_mode = group, .timer_num = timer, .duty_resolution = resolution, .freq_hz = freq, .clk_cfg = clock_source}; ledc_timer_config_t ledc_timer;
memset((void *)&ledc_timer, 0, sizeof(ledc_timer_config_t));
ledc_timer.speed_mode = group;
ledc_timer.timer_num = bus->timer_num;
ledc_timer.duty_resolution = resolution;
ledc_timer.freq_hz = freq;
ledc_timer.clk_cfg = clock_source;
if (ledc_timer_config(&ledc_timer) != ESP_OK) { if (ledc_timer_config(&ledc_timer) != ESP_OK) {
log_e("ledcChangeFrequency failed!"); log_e("ledcChangeFrequency failed!");
return 0; return 0;
} }
bus->channel_resolution = resolution; bus->channel_resolution = resolution;
return ledc_get_freq(group, timer); return ledc_get_freq(group, bus->timer_num);
} }
return 0; return 0;
} }
@ -325,12 +501,14 @@ bool ledcOutputInvert(uint8_t pin, bool out_invert) {
gpio_set_level(pin, out_invert); gpio_set_level(pin, out_invert);
#ifdef CONFIG_IDF_TARGET_ESP32P4 #ifdef CONFIG_IDF_TARGET_ESP32P4
esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT_PAD_OUT0_IDX + ((bus->channel) % 8), out_invert, 0); esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT_PAD_OUT0_IDX + ((bus->channel) % SOC_LEDC_CHANNEL_NUM), out_invert, 0);
#else #else
#ifdef SOC_LEDC_SUPPORT_HS_MODE #ifdef SOC_LEDC_SUPPORT_HS_MODE
esp_rom_gpio_connect_out_signal(pin, ((bus->channel / 8 == 0) ? LEDC_HS_SIG_OUT0_IDX : LEDC_LS_SIG_OUT0_IDX) + ((bus->channel) % 8), out_invert, 0); esp_rom_gpio_connect_out_signal(
pin, ((bus->channel / SOC_LEDC_CHANNEL_NUM == 0) ? LEDC_HS_SIG_OUT0_IDX : LEDC_LS_SIG_OUT0_IDX) + ((bus->channel) % SOC_LEDC_CHANNEL_NUM), out_invert, 0
);
#else #else
esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT0_IDX + ((bus->channel) % 8), out_invert, 0); esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT0_IDX + ((bus->channel) % SOC_LEDC_CHANNEL_NUM), out_invert, 0);
#endif #endif
#endif // ifdef CONFIG_IDF_TARGET_ESP32P4 #endif // ifdef CONFIG_IDF_TARGET_ESP32P4
return true; return true;
@ -377,7 +555,7 @@ static bool ledcFadeConfig(uint8_t pin, uint32_t start_duty, uint32_t target_dut
} }
#endif #endif
#endif #endif
uint8_t group = (bus->channel / 8), channel = (bus->channel % 8); uint8_t group = (bus->channel / SOC_LEDC_CHANNEL_NUM), channel = (bus->channel % SOC_LEDC_CHANNEL_NUM);
// Initialize fade service. // Initialize fade service.
if (!fade_initialized) { if (!fade_initialized) {
@ -434,6 +612,161 @@ bool ledcFadeWithInterruptArg(uint8_t pin, uint32_t start_duty, uint32_t target_
return ledcFadeConfig(pin, start_duty, target_duty, max_fade_time_ms, userFunc, arg); return ledcFadeConfig(pin, start_duty, target_duty, max_fade_time_ms, userFunc, arg);
} }
#ifdef SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
// Default gamma factor for gamma correction (common value for LEDs)
static float ledcGammaFactor = 2.8;
// Gamma correction LUT support
static const float *ledcGammaLUT = NULL;
static uint16_t ledcGammaLUTSize = 0;
// Global variable to store current resolution for gamma callback
static uint8_t ledcGammaResolution = 13;
bool ledcSetGammaTable(const float *gamma_table, uint16_t size) {
if (gamma_table == NULL || size == 0) {
log_e("Invalid gamma table or size");
return false;
}
ledcGammaLUT = gamma_table;
ledcGammaLUTSize = size;
log_i("Custom gamma LUT set with %u entries", size);
return true;
}
void ledcClearGammaTable(void) {
ledcGammaLUT = NULL;
ledcGammaLUTSize = 0;
log_i("Gamma LUT cleared, using mathematical calculation");
}
void ledcSetGammaFactor(float factor) {
ledcGammaFactor = factor;
}
// Gamma correction calculator function
static uint32_t ledcGammaCorrection(uint32_t duty) {
if (duty == 0) {
return 0;
}
uint32_t max_duty = (1U << ledcGammaResolution) - 1;
if (duty >= (1U << ledcGammaResolution)) {
return max_duty;
}
// Use LUT if provided, otherwise use mathematical calculation
if (ledcGammaLUT != NULL && ledcGammaLUTSize > 0) {
// LUT-based gamma correction
uint32_t lut_index = (duty * (ledcGammaLUTSize - 1)) / max_duty;
if (lut_index >= ledcGammaLUTSize) {
lut_index = ledcGammaLUTSize - 1;
}
float corrected_normalized = ledcGammaLUT[lut_index];
return (uint32_t)(corrected_normalized * max_duty);
} else {
// Mathematical gamma correction
double normalized = (double)duty / (1U << ledcGammaResolution);
double corrected = pow(normalized, ledcGammaFactor);
return (uint32_t)(corrected * (1U << ledcGammaResolution));
}
}
static bool ledcFadeGammaConfig(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, void (*userFunc)(void *), void *arg) {
ledc_channel_handle_t *bus = (ledc_channel_handle_t *)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC);
if (bus != NULL) {
#ifndef SOC_LEDC_SUPPORT_FADE_STOP
#if !CONFIG_DISABLE_HAL_LOCKS
if (bus->lock == NULL) {
bus->lock = xSemaphoreCreateBinary();
if (bus->lock == NULL) {
log_e("xSemaphoreCreateBinary failed");
return false;
}
xSemaphoreGive(bus->lock);
}
//acquire lock
if (xSemaphoreTake(bus->lock, 0) != pdTRUE) {
log_e("LEDC Fade is still running on pin %u! SoC does not support stopping fade.", pin);
return false;
}
#endif
#endif
uint8_t group = (bus->channel / SOC_LEDC_CHANNEL_NUM), channel = (bus->channel % SOC_LEDC_CHANNEL_NUM);
// Initialize fade service.
if (!fade_initialized) {
ledc_fade_func_install(0);
fade_initialized = true;
}
bus->fn = (voidFuncPtr)userFunc;
bus->arg = arg;
ledc_cbs_t callbacks = {.fade_cb = ledcFnWrapper};
ledc_cb_register(group, channel, &callbacks, (void *)bus);
// Prepare gamma curve fade parameters
ledc_fade_param_config_t fade_params[SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX];
uint32_t actual_fade_ranges = 0;
// Use a moderate number of linear segments for smooth gamma curve
const uint32_t linear_fade_segments = 12;
// Set the global resolution for gamma correction
ledcGammaResolution = bus->channel_resolution;
// Fill multi-fade parameter list using ESP-IDF API
esp_err_t err = ledc_fill_multi_fade_param_list(
group, channel, start_duty, target_duty, linear_fade_segments, max_fade_time_ms, ledcGammaCorrection, SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX, fade_params,
&actual_fade_ranges
);
if (err != ESP_OK) {
log_e("ledc_fill_multi_fade_param_list failed: %s", esp_err_to_name(err));
return false;
}
// Apply the gamma-corrected start duty
uint32_t gamma_start_duty = ledcGammaCorrection(start_duty);
// Set multi-fade parameters
err = ledc_set_multi_fade(group, channel, gamma_start_duty, fade_params, actual_fade_ranges);
if (err != ESP_OK) {
log_e("ledc_set_multi_fade failed: %s", esp_err_to_name(err));
return false;
}
// Start the gamma curve fade
err = ledc_fade_start(group, channel, LEDC_FADE_NO_WAIT);
if (err != ESP_OK) {
log_e("ledc_fade_start failed: %s", esp_err_to_name(err));
return false;
}
log_d("Gamma curve fade started on pin %u: %u -> %u over %dms", pin, start_duty, target_duty, max_fade_time_ms);
} else {
log_e("Pin %u is not attached to LEDC. Call ledcAttach first!", pin);
return false;
}
return true;
}
bool ledcFadeGamma(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms) {
return ledcFadeGammaConfig(pin, start_duty, target_duty, max_fade_time_ms, NULL, NULL);
}
bool ledcFadeGammaWithInterrupt(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, voidFuncPtr userFunc) {
return ledcFadeGammaConfig(pin, start_duty, target_duty, max_fade_time_ms, (voidFuncPtrArg)userFunc, NULL);
}
bool ledcFadeGammaWithInterruptArg(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, void (*userFunc)(void *), void *arg) {
return ledcFadeGammaConfig(pin, start_duty, target_duty, max_fade_time_ms, userFunc, arg);
}
#endif /* SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED */
static uint8_t analog_resolution = 8; static uint8_t analog_resolution = 8;
static int analog_frequency = 1000; static int analog_frequency = 1000;
void analogWrite(uint8_t pin, int value) { void analogWrite(uint8_t pin, int value) {

View file

@ -51,6 +51,8 @@ typedef struct {
uint8_t pin; // Pin assigned to channel uint8_t pin; // Pin assigned to channel
uint8_t channel; // Channel number uint8_t channel; // Channel number
uint8_t channel_resolution; // Resolution of channel uint8_t channel_resolution; // Resolution of channel
uint8_t timer_num; // Timer number used by this channel
uint32_t freq_hz; // Frequency configured for this channel
voidFuncPtr fn; voidFuncPtr fn;
void *arg; void *arg;
#ifndef SOC_LEDC_SUPPORT_FADE_STOP #ifndef SOC_LEDC_SUPPORT_FADE_STOP
@ -230,6 +232,85 @@ bool ledcFadeWithInterrupt(uint8_t pin, uint32_t start_duty, uint32_t target_dut
*/ */
bool ledcFadeWithInterruptArg(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, void (*userFunc)(void *), void *arg); bool ledcFadeWithInterruptArg(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, void (*userFunc)(void *), void *arg);
//Gamma Curve Fade functions - only available on supported chips
#ifdef SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
/**
* @brief Set a custom gamma correction lookup table for gamma curve fading.
* The LUT should contain normalized values (0.0 to 1.0) representing
* the gamma-corrected brightness curve.
*
* @param gamma_table Pointer to array of float values (0.0 to 1.0)
* @param size Number of entries in the lookup table
*
* @return true if gamma table was successfully set, false otherwise.
*
* @note The LUT array must remain valid for as long as gamma fading is used.
* Larger tables provide smoother transitions but use more memory.
*/
bool ledcSetGammaTable(const float *gamma_table, uint16_t size);
/**
* @brief Clear the current gamma correction lookup table.
* After calling this, gamma correction will use mathematical
* calculation with the default gamma factor (2.8).
*/
void ledcClearGammaTable(void);
/**
* @brief Set the gamma factor for gamma correction.
*
* @param factor Gamma factor to use for gamma correction.
*/
void ledcSetGammaFactor(float factor);
/**
* @brief Setup and start a gamma curve fade on a given LEDC pin.
* Gamma correction makes LED brightness changes appear more gradual to human eyes.
*
* @param pin GPIO pin
* @param start_duty initial duty cycle of the fade
* @param target_duty target duty cycle of the fade
* @param max_fade_time_ms maximum fade time in milliseconds
*
* @return true if gamma fade was successfully set and started, false otherwise.
*
* @note This function is only available on ESP32 variants that support gamma curve fading.
*/
bool ledcFadeGamma(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms);
/**
* @brief Setup and start a gamma curve fade on a given LEDC pin with a callback function.
*
* @param pin GPIO pin
* @param start_duty initial duty cycle of the fade
* @param target_duty target duty cycle of the fade
* @param max_fade_time_ms maximum fade time in milliseconds
* @param userFunc callback function to be called after fade is finished
*
* @return true if gamma fade was successfully set and started, false otherwise.
*
* @note This function is only available on ESP32 variants that support gamma curve fading.
*/
bool ledcFadeGammaWithInterrupt(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, void (*userFunc)(void));
/**
* @brief Setup and start a gamma curve fade on a given LEDC pin with a callback function and argument.
*
* @param pin GPIO pin
* @param start_duty initial duty cycle of the fade
* @param target_duty target duty cycle of the fade
* @param max_fade_time_ms maximum fade time in milliseconds
* @param userFunc callback function to be called after fade is finished
* @param arg argument to be passed to the callback function
*
* @return true if gamma fade was successfully set and started, false otherwise.
*
* @note This function is only available on ESP32 variants that support gamma curve fading.
*/
bool ledcFadeGammaWithInterruptArg(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, void (*userFunc)(void *), void *arg);
#endif // SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -34,6 +34,8 @@
#include "esp32h2/rom/gpio.h" #include "esp32h2/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/gpio.h" #include "esp32p4/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/gpio.h"
#else #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif

View file

@ -25,12 +25,13 @@
#include "esp_ota_ops.h" #include "esp_ota_ops.h"
#endif //CONFIG_APP_ROLLBACK_ENABLE #endif //CONFIG_APP_ROLLBACK_ENABLE
#include "esp_private/startup_internal.h" #include "esp_private/startup_internal.h"
#ifdef CONFIG_BT_ENABLED #if (defined(CONFIG_BLUEDROID_ENABLED) || defined(CONFIG_NIMBLE_ENABLED)) && SOC_BT_SUPPORTED && __has_include("esp_bt.h")
#include "esp_bt.h" #include "esp_bt.h"
#endif //CONFIG_BT_ENABLED #endif
#include <sys/time.h> #include <sys/time.h>
#include "soc/rtc.h" #include "soc/rtc.h"
#if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4) #if !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32H2) && !defined(CONFIG_IDF_TARGET_ESP32P4) \
&& !defined(CONFIG_IDF_TARGET_ESP32C5)
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#endif #endif
@ -56,6 +57,8 @@
#include "esp32h2/rom/rtc.h" #include "esp32h2/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/rtc.h" #include "esp32p4/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/rtc.h"
#else #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
@ -243,7 +246,7 @@ bool verifyRollbackLater() {
} }
#endif #endif
#ifdef CONFIG_BT_ENABLED #if defined(CONFIG_BLUEDROID_ENABLED) || defined(CONFIG_NIMBLE_ENABLED)
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
//overwritten in esp32-hal-bt.c //overwritten in esp32-hal-bt.c
bool btInUse() __attribute__((weak)); bool btInUse() __attribute__((weak));
@ -305,7 +308,7 @@ void initArduino() {
if (err) { if (err) {
log_e("Failed to initialize NVS! Error: %u", err); log_e("Failed to initialize NVS! Error: %u", err);
} }
#ifdef CONFIG_BT_ENABLED #if (defined(CONFIG_BLUEDROID_ENABLED) || defined(CONFIG_NIMBLE_ENABLED)) && SOC_BT_SUPPORTED
if (!btInUse()) { if (!btInUse()) {
esp_bt_controller_mem_release(ESP_BT_MODE_BTDM); esp_bt_controller_mem_release(ESP_BT_MODE_BTDM);
} }

View file

@ -29,6 +29,8 @@
#include "esp32s3/rom/cache.h" #include "esp32s3/rom/cache.h"
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/cache.h" #include "esp32p4/rom/cache.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/cache.h"
#else #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif

View file

@ -206,7 +206,8 @@ bool rmtSetCarrier(int pin, bool carrier_en, bool carrier_level, uint32_t freque
log_w("GPIO %d - RMT Carrier must be a float percentage from 0 to 1. Setting to 50%.", pin); log_w("GPIO %d - RMT Carrier must be a float percentage from 0 to 1. Setting to 50%.", pin);
duty_percent = 0.5; duty_percent = 0.5;
} }
rmt_carrier_config_t carrier_cfg = {0}; rmt_carrier_config_t carrier_cfg;
memset((void *)&carrier_cfg, 0, sizeof(rmt_carrier_config_t));
carrier_cfg.duty_cycle = duty_percent; // duty cycle carrier_cfg.duty_cycle = duty_percent; // duty cycle
carrier_cfg.frequency_hz = carrier_en ? frequency_Hz : 0; // carrier frequency in Hz carrier_cfg.frequency_hz = carrier_en ? frequency_Hz : 0; // carrier frequency in Hz
carrier_cfg.flags.polarity_active_low = carrier_level; // carrier modulation polarity level carrier_cfg.flags.polarity_active_low = carrier_level; // carrier modulation polarity level
@ -313,7 +314,8 @@ static bool _rmtWrite(int pin, rmt_data_t *data, size_t num_rmt_symbols, bool bl
return false; return false;
} }
rmt_transmit_config_t transmit_cfg = {0}; // loop mode disabled rmt_transmit_config_t transmit_cfg; // loop mode disabled
memset((void *)&transmit_cfg, 0, sizeof(rmt_transmit_config_t));
bool retCode = true; bool retCode = true;
RMT_MUTEX_LOCK(bus); RMT_MUTEX_LOCK(bus);
@ -380,6 +382,7 @@ static bool _rmtRead(int pin, rmt_data_t *data, size_t *num_rmt_symbols, bool wa
// request reading RMT Channel Data // request reading RMT Channel Data
rmt_receive_config_t receive_config; rmt_receive_config_t receive_config;
memset((void *)&receive_config, 0, sizeof(rmt_receive_config_t));
receive_config.signal_range_min_ns = bus->signal_range_min_ns; receive_config.signal_range_min_ns = bus->signal_range_min_ns;
receive_config.signal_range_max_ns = bus->signal_range_max_ns; receive_config.signal_range_max_ns = bus->signal_range_max_ns;
@ -530,6 +533,7 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_
if (channel_direction == RMT_TX_MODE) { if (channel_direction == RMT_TX_MODE) {
// TX Channel // TX Channel
rmt_tx_channel_config_t tx_cfg; rmt_tx_channel_config_t tx_cfg;
memset((void *)&tx_cfg, 0, sizeof(rmt_tx_channel_config_t));
tx_cfg.gpio_num = pin; tx_cfg.gpio_num = pin;
// CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F80M for C6 -- CLK_XTAL for H2 // CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F80M for C6 -- CLK_XTAL for H2
tx_cfg.clk_src = RMT_CLK_SRC_DEFAULT; tx_cfg.clk_src = RMT_CLK_SRC_DEFAULT;
@ -559,6 +563,7 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_
} else { } else {
// RX Channel // RX Channel
rmt_rx_channel_config_t rx_cfg; rmt_rx_channel_config_t rx_cfg;
memset((void *)&rx_cfg, 0, sizeof(rmt_rx_channel_config_t));
rx_cfg.gpio_num = pin; rx_cfg.gpio_num = pin;
// CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F80M for C6 -- CLK_XTAL for H2 // CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F80M for C6 -- CLK_XTAL for H2
rx_cfg.clk_src = RMT_CLK_SRC_DEFAULT; rx_cfg.clk_src = RMT_CLK_SRC_DEFAULT;
@ -585,7 +590,8 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_
} }
// allocate memory for the RMT Copy encoder // allocate memory for the RMT Copy encoder
rmt_copy_encoder_config_t copy_encoder_config = {}; rmt_copy_encoder_config_t copy_encoder_config;
memset((void *)&copy_encoder_config, 0, sizeof(rmt_copy_encoder_config_t));
if (rmt_new_copy_encoder(&copy_encoder_config, &bus->rmt_copy_encoder_h) != ESP_OK) { if (rmt_new_copy_encoder(&copy_encoder_config, &bus->rmt_copy_encoder_h) != ESP_OK) {
log_e("GPIO %d - RMT Encoder Memory Allocation error.", pin); log_e("GPIO %d - RMT Encoder Memory Allocation error.", pin);
goto Err; goto Err;

View file

@ -26,7 +26,9 @@
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
#include "soc/gpio_sig_map.h" #include "soc/gpio_sig_map.h"
#include "soc/rtc.h" #include "soc/rtc.h"
#ifndef CONFIG_IDF_TARGET_ESP32C5
#include "hal/clk_gate_ll.h" #include "hal/clk_gate_ll.h"
#endif
#include "esp32-hal-periman.h" #include "esp32-hal-periman.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
@ -60,6 +62,10 @@
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/ets_sys.h" #include "esp32p4/rom/ets_sys.h"
#include "esp32p4/rom/gpio.h" #include "esp32p4/rom/gpio.h"
#include "hal/spi_ll.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/ets_sys.h"
#include "esp32c5/rom/gpio.h"
#else #else
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif
@ -74,20 +80,20 @@ struct spi_struct_t {
int8_t miso; int8_t miso;
int8_t mosi; int8_t mosi;
int8_t ss; int8_t ss;
bool ss_invert;
}; };
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2
// ESP32S2 // ESP32S2
#define SPI_COUNT (3) #define SPI_COUNT (2)
#define SPI_CLK_IDX(p) ((p == 0) ? SPICLK_OUT_MUX_IDX : ((p == 1) ? FSPICLK_OUT_MUX_IDX : ((p == 2) ? SPI3_CLK_OUT_MUX_IDX : 0))) #define SPI_CLK_IDX(p) ((p == 0) ? FSPICLK_OUT_MUX_IDX : ((p == 1) ? SPI3_CLK_OUT_MUX_IDX : 0))
#define SPI_MISO_IDX(p) ((p == 0) ? SPIQ_OUT_IDX : ((p == 1) ? FSPIQ_OUT_IDX : ((p == 2) ? SPI3_Q_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) ? SPID_IN_IDX : ((p == 1) ? FSPID_IN_IDX : ((p == 2) ? SPI3_D_IN_IDX : 0))) #define SPI_MOSI_IDX(p) ((p == 0) ? FSPID_IN_IDX : ((p == 1) ? SPI3_D_IN_IDX : 0))
#define SPI_SPI_SS_IDX(n) ((n == 0) ? SPICS0_OUT_IDX : ((n == 1) ? SPICS1_OUT_IDX : 0)) #define SPI_HSPI_SS_IDX(n) ((n == 0) ? SPI3_CS0_OUT_IDX : ((n == 1) ? SPI3_CS1_OUT_IDX : ((n == 2) ? SPI3_CS2_OUT_IDX : 0)))
#define SPI_HSPI_SS_IDX(n) ((n == 0) ? SPI3_CS0_OUT_IDX : ((n == 1) ? SPI3_CS1_OUT_IDX : ((n == 2) ? SPI3_CS2_OUT_IDX : SPI3_CS0_OUT_IDX))) #define SPI_FSPI_SS_IDX(n) ((n == 0) ? FSPICS0_OUT_IDX : ((n == 1) ? FSPICS1_OUT_IDX : ((n == 2) ? FSPICS2_OUT_IDX : 0)))
#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_FSPI_SS_IDX(n) : ((p == 1) ? SPI_HSPI_SS_IDX(n) : 0))
#define SPI_SS_IDX(p, n) ((p == 0) ? SPI_SPI_SS_IDX(n) : ((p == 1) ? SPI_SPI_SS_IDX(n) : ((p == 2) ? SPI_HSPI_SS_IDX(n) : 0)))
#elif CONFIG_IDF_TARGET_ESP32S3 #elif CONFIG_IDF_TARGET_ESP32S3
// ESP32S3 // ESP32S3
@ -97,8 +103,8 @@ struct spi_struct_t {
#define SPI_MISO_IDX(p) ((p == 0) ? FSPIQ_OUT_IDX : ((p == 1) ? SPI3_Q_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_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_HSPI_SS_IDX(n) ((n == 0) ? SPI3_CS0_OUT_IDX : ((n == 1) ? SPI3_CS1_OUT_IDX : ((n == 2) ? SPI3_CS2_OUT_IDX : 0)))
#define SPI_FSPI_SS_IDX(n) ((n == 0) ? FSPICS0_OUT_IDX : ((n == 1) ? FSPICS1_OUT_IDX : 0)) #define SPI_FSPI_SS_IDX(n) ((n == 0) ? FSPICS0_OUT_IDX : ((n == 1) ? FSPICS1_OUT_IDX : ((n == 2) ? FSPICS2_OUT_IDX : 0)))
#define SPI_SS_IDX(p, n) ((p == 0) ? SPI_FSPI_SS_IDX(n) : ((p == 1) ? SPI_HSPI_SS_IDX(n) : 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_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
@ -119,7 +125,7 @@ struct spi_struct_t {
#define SPI_SS_IDX(p, n) ((p == 0) ? SPI_FSPI_SS_IDX(n) : ((p == 1) ? SPI_HSPI_SS_IDX(n) : 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_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 #elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5
// ESP32C3 // ESP32C3
#define SPI_COUNT (1) #define SPI_COUNT (1)
@ -150,24 +156,20 @@ struct spi_struct_t {
#define SPI_MUTEX_UNLOCK() #define SPI_MUTEX_UNLOCK()
// clang-format off // clang-format off
static spi_t _spi_bus_array[] = { static spi_t _spi_bus_array[] = {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2 ||CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1, false},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1, -1, -1, -1, -1, false}
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32C2 #elif CONFIG_IDF_TARGET_ESP32C2
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1} {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1, false}
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1} {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1, false}
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 #elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5
{(spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1} {(spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1, false}
#else #else
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0, -1, -1, -1, -1, false},
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1, -1, -1, -1, -1, false},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 2, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 2, -1, -1, -1, -1, false},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 3, -1, -1, -1, -1} {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 3, -1, -1, -1, -1, false}
#endif #endif
}; };
// clang-format on // clang-format on
@ -178,23 +180,19 @@ static spi_t _spi_bus_array[] = {
#define SPI_MUTEX_UNLOCK() xSemaphoreGive(spi->lock) #define SPI_MUTEX_UNLOCK() xSemaphoreGive(spi->lock)
static spi_t _spi_bus_array[] = { static spi_t _spi_bus_array[] = {
#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1, false}, {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 1, -1, -1, -1, -1, false}
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1, -1, -1, -1, -1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 1, -1, -1, -1, -1}
#elif CONFIG_IDF_TARGET_ESP32C2 #elif CONFIG_IDF_TARGET_ESP32C2
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1} {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1, false}
#elif CONFIG_IDF_TARGET_ESP32C3 #elif CONFIG_IDF_TARGET_ESP32C3
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1} {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1, false}
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 #elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5
{(spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1} {(spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1, false}
#else #else
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0, -1, -1, -1, -1, false},
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1, -1, -1, -1, -1, false},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 2, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 2, -1, -1, -1, -1, false},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 3, -1, -1, -1, -1} {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 3, -1, -1, -1, -1, false}
#endif #endif
}; };
#endif #endif
@ -365,7 +363,7 @@ bool spiAttachSS(spi_t *spi, uint8_t ss_num, int8_t ss) {
return false; return false;
} }
pinMode(ss, OUTPUT); pinMode(ss, OUTPUT);
pinMatrixOutAttach(ss, SPI_SS_IDX(spi->num, ss_num), false, false); pinMatrixOutAttach(ss, SPI_SS_IDX(spi->num, ss_num), spi->ss_invert, false);
spiEnableSSPins(spi, (1 << ss_num)); spiEnableSSPins(spi, (1 << ss_num));
spi->ss = ss; spi->ss = ss;
if (!perimanSetPinBus(ss, ESP32_BUS_TYPE_SPI_MASTER_SS, (void *)(spi->num + 1), spi->num, -1)) { if (!perimanSetPinBus(ss, ESP32_BUS_TYPE_SPI_MASTER_SS, (void *)(spi->num + 1), spi->num, -1)) {
@ -435,6 +433,12 @@ void spiSSDisable(spi_t *spi) {
SPI_MUTEX_UNLOCK(); SPI_MUTEX_UNLOCK();
} }
void spiSSInvert(spi_t *spi, bool invert) {
if (spi) {
spi->ss_invert = invert;
}
}
void spiSSSet(spi_t *spi) { void spiSSSet(spi_t *spi) {
if (!spi) { if (!spi) {
return; return;
@ -614,6 +618,7 @@ void spiStopBus(spi_t *spi) {
spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder) { spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder) {
if (spi_num >= SPI_COUNT) { if (spi_num >= SPI_COUNT) {
log_e("SPI bus index %d is out of range", spi_num);
return NULL; return NULL;
} }
@ -640,9 +645,6 @@ spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t
} else if (spi_num == HSPI) { } else if (spi_num == HSPI) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN); DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST); DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST);
} else {
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 #elif CONFIG_IDF_TARGET_ESP32S3
if (spi_num == FSPI) { if (spi_num == FSPI) {
@ -663,6 +665,31 @@ spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN); DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST); DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST);
} }
#elif CONFIG_IDF_TARGET_ESP32P4
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
if (spi_num == FSPI) {
PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_GPSPI2_MODULE, ref_count) {
if (ref_count == 0) {
PERIPH_RCC_ATOMIC() {
spi_ll_enable_bus_clock(SPI2_HOST, true);
spi_ll_reset_register(SPI2_HOST);
spi_ll_enable_clock(SPI2_HOST, true);
}
}
}
} else if (spi_num == HSPI) {
PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_GPSPI3_MODULE, ref_count) {
if (ref_count == 0) {
PERIPH_RCC_ATOMIC() {
spi_ll_enable_bus_clock(SPI3_HOST, true);
spi_ll_reset_register(SPI3_HOST);
spi_ll_enable_clock(SPI3_HOST, true);
}
}
}
}
#pragma GCC diagnostic pop
#elif defined(__PERIPH_CTRL_ALLOW_LEGACY_API) #elif defined(__PERIPH_CTRL_ALLOW_LEGACY_API)
periph_ll_reset(PERIPH_SPI2_MODULE); periph_ll_reset(PERIPH_SPI2_MODULE);
periph_ll_enable_clk_clear_rst(PERIPH_SPI2_MODULE); periph_ll_enable_clk_clear_rst(PERIPH_SPI2_MODULE);
@ -685,7 +712,7 @@ spi_t *spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t
spi->dev->user.doutdin = 1; spi->dev->user.doutdin = 1;
int i; int i;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = 0x00000000; spi->dev->data_buf[i].val = 0x00000000;
#else #else
spi->dev->data_buf[i] = 0x00000000; spi->dev->data_buf[i] = 0x00000000;
@ -733,7 +760,7 @@ void spiWrite(spi_t *spi, const uint32_t *data, uint8_t len) {
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = data[i]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
@ -760,7 +787,7 @@ void spiTransfer(spi_t *spi, uint32_t *data, uint8_t len) {
spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1; spi->dev->mosi_dlen.usr_mosi_dbitlen = (len * 32) - 1;
spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1; spi->dev->miso_dlen.usr_miso_dbitlen = (len * 32) - 1;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = data[i]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
@ -773,7 +800,7 @@ void spiTransfer(spi_t *spi, uint32_t *data, uint8_t len) {
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
data[i] = spi->dev->data_buf[i].val; data[i] = spi->dev->data_buf[i].val;
#else #else
data[i] = spi->dev->data_buf[i]; data[i] = spi->dev->data_buf[i];
@ -791,7 +818,7 @@ void spiWriteByte(spi_t *spi, uint8_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -813,7 +840,7 @@ uint8_t spiTransferByte(spi_t *spi, uint8_t data) {
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_dbitlen = 7; spi->dev->miso_dlen.usr_miso_dbitlen = 7;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -824,7 +851,7 @@ uint8_t spiTransferByte(spi_t *spi, uint8_t data) {
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
data = spi->dev->data_buf[0].val & 0xFF; data = spi->dev->data_buf[0].val & 0xFF;
#else #else
data = spi->dev->data_buf[0] & 0xFF; data = spi->dev->data_buf[0] & 0xFF;
@ -854,7 +881,7 @@ void spiWriteWord(spi_t *spi, uint16_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -878,7 +905,7 @@ uint16_t spiTransferWord(spi_t *spi, uint16_t data) {
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
spi->dev->miso_dlen.usr_miso_dbitlen = 15; spi->dev->miso_dlen.usr_miso_dbitlen = 15;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -889,7 +916,7 @@ uint16_t spiTransferWord(spi_t *spi, uint16_t data) {
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
data = spi->dev->data_buf[0].val; data = spi->dev->data_buf[0].val;
#else #else
data = spi->dev->data_buf[0]; data = spi->dev->data_buf[0];
@ -913,7 +940,7 @@ void spiWriteLong(spi_t *spi, uint32_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -937,7 +964,7 @@ uint32_t spiTransferLong(spi_t *spi, uint32_t data) {
SPI_MUTEX_LOCK(); SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
spi->dev->miso_dlen.usr_miso_dbitlen = 31; spi->dev->miso_dlen.usr_miso_dbitlen = 31;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -948,7 +975,7 @@ uint32_t spiTransferLong(spi_t *spi, uint32_t data) {
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
data = spi->dev->data_buf[0].val; data = spi->dev->data_buf[0].val;
#else #else
data = spi->dev->data_buf[0]; data = spi->dev->data_buf[0];
@ -987,7 +1014,7 @@ static void __spiTransferBytes(spi_t *spi, const uint8_t *data, uint8_t *out, ui
spi->dev->miso_dlen.usr_miso_dbitlen = ((bytes * 8) - 1); spi->dev->miso_dlen.usr_miso_dbitlen = ((bytes * 8) - 1);
for (i = 0; i < words; i++) { for (i = 0; i < words; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = wordsBuf[i]; //copy buffer to spi fifo spi->dev->data_buf[i].val = wordsBuf[i]; //copy buffer to spi fifo
#else #else
spi->dev->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo spi->dev->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo
@ -1004,7 +1031,7 @@ static void __spiTransferBytes(spi_t *spi, const uint8_t *data, uint8_t *out, ui
if (out) { if (out) {
for (i = 0; i < words; i++) { for (i = 0; i < words; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
wordsBuf[i] = spi->dev->data_buf[i].val; //copy spi fifo to buffer wordsBuf[i] = spi->dev->data_buf[i].val; //copy spi fifo to buffer
#else #else
wordsBuf[i] = spi->dev->data_buf[i]; //copy spi fifo to buffer wordsBuf[i] = spi->dev->data_buf[i]; //copy spi fifo to buffer
@ -1145,7 +1172,7 @@ void ARDUINO_ISR_ATTR spiWriteByteNL(spi_t *spi, uint8_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -1164,7 +1191,7 @@ uint8_t spiTransferByteNL(spi_t *spi, uint8_t data) {
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7; spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_dbitlen = 7; spi->dev->miso_dlen.usr_miso_dbitlen = 7;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -1175,7 +1202,7 @@ uint8_t spiTransferByteNL(spi_t *spi, uint8_t data) {
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
data = spi->dev->data_buf[0].val & 0xFF; data = spi->dev->data_buf[0].val & 0xFF;
#else #else
data = spi->dev->data_buf[0] & 0xFF; data = spi->dev->data_buf[0] & 0xFF;
@ -1194,7 +1221,7 @@ void ARDUINO_ISR_ATTR spiWriteShortNL(spi_t *spi, uint16_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -1216,7 +1243,7 @@ uint16_t spiTransferShortNL(spi_t *spi, uint16_t data) {
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 15; spi->dev->mosi_dlen.usr_mosi_dbitlen = 15;
spi->dev->miso_dlen.usr_miso_dbitlen = 15; spi->dev->miso_dlen.usr_miso_dbitlen = 15;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -1227,7 +1254,7 @@ uint16_t spiTransferShortNL(spi_t *spi, uint16_t data) {
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
data = spi->dev->data_buf[0].val & 0xFFFF; data = spi->dev->data_buf[0].val & 0xFFFF;
#else #else
data = spi->dev->data_buf[0] & 0xFFFF; data = spi->dev->data_buf[0] & 0xFFFF;
@ -1249,7 +1276,7 @@ void ARDUINO_ISR_ATTR spiWriteLongNL(spi_t *spi, uint32_t data) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -1271,7 +1298,7 @@ uint32_t spiTransferLongNL(spi_t *spi, uint32_t data) {
} }
spi->dev->mosi_dlen.usr_mosi_dbitlen = 31; spi->dev->mosi_dlen.usr_mosi_dbitlen = 31;
spi->dev->miso_dlen.usr_miso_dbitlen = 31; spi->dev->miso_dlen.usr_miso_dbitlen = 31;
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -1282,7 +1309,7 @@ uint32_t spiTransferLongNL(spi_t *spi, uint32_t data) {
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
data = spi->dev->data_buf[0].val; data = spi->dev->data_buf[0].val;
#else #else
data = spi->dev->data_buf[0]; data = spi->dev->data_buf[0];
@ -1313,7 +1340,7 @@ void spiWriteNL(spi_t *spi, const void *data_in, uint32_t len) {
spi->dev->miso_dlen.usr_miso_dbitlen = 0; spi->dev->miso_dlen.usr_miso_dbitlen = 0;
#endif #endif
for (size_t i = 0; i < c_longs; i++) { for (size_t i = 0; i < c_longs; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = data[i]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
@ -1352,7 +1379,7 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
spi->dev->miso_dlen.usr_miso_dbitlen = (c_len * 8) - 1; spi->dev->miso_dlen.usr_miso_dbitlen = (c_len * 8) - 1;
if (data) { if (data) {
for (size_t i = 0; i < c_longs; i++) { for (size_t i = 0; i < c_longs; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = data[i]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];
@ -1360,7 +1387,7 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
} }
} else { } else {
for (size_t i = 0; i < c_longs; i++) { for (size_t i = 0; i < c_longs; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = 0xFFFFFFFF; spi->dev->data_buf[i].val = 0xFFFFFFFF;
#else #else
spi->dev->data_buf[i] = 0xFFFFFFFF; spi->dev->data_buf[i] = 0xFFFFFFFF;
@ -1376,13 +1403,13 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
if (result) { if (result) {
if (c_len & 3) { if (c_len & 3) {
for (size_t i = 0; i < (c_longs - 1); i++) { for (size_t i = 0; i < (c_longs - 1); i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
result[i] = spi->dev->data_buf[i].val; result[i] = spi->dev->data_buf[i].val;
#else #else
result[i] = spi->dev->data_buf[i]; result[i] = spi->dev->data_buf[i];
#endif #endif
} }
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
uint32_t last_data = spi->dev->data_buf[c_longs - 1].val; uint32_t last_data = spi->dev->data_buf[c_longs - 1].val;
#else #else
uint32_t last_data = spi->dev->data_buf[c_longs - 1]; uint32_t last_data = spi->dev->data_buf[c_longs - 1];
@ -1394,7 +1421,7 @@ void spiTransferBytesNL(spi_t *spi, const void *data_in, uint8_t *data_out, uint
} }
} else { } else {
for (size_t i = 0; i < c_longs; i++) { for (size_t i = 0; i < c_longs; i++) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
result[i] = spi->dev->data_buf[i].val; result[i] = spi->dev->data_buf[i].val;
#else #else
result[i] = spi->dev->data_buf[i]; result[i] = spi->dev->data_buf[i];
@ -1436,7 +1463,7 @@ void spiTransferBitsNL(spi_t *spi, uint32_t data, uint32_t *out, uint8_t bits) {
spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1); spi->dev->mosi_dlen.usr_mosi_dbitlen = (bits - 1);
spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1); spi->dev->miso_dlen.usr_miso_dbitlen = (bits - 1);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[0].val = data; spi->dev->data_buf[0].val = data;
#else #else
spi->dev->data_buf[0] = data; spi->dev->data_buf[0] = data;
@ -1447,7 +1474,7 @@ void spiTransferBitsNL(spi_t *spi, uint32_t data, uint32_t *out, uint8_t bits) {
#endif #endif
spi->dev->cmd.usr = 1; spi->dev->cmd.usr = 1;
while (spi->dev->cmd.usr); while (spi->dev->cmd.usr);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
data = spi->dev->data_buf[0].val; data = spi->dev->data_buf[0].val;
#else #else
data = spi->dev->data_buf[0]; data = spi->dev->data_buf[0];
@ -1488,27 +1515,27 @@ void ARDUINO_ISR_ATTR spiWritePixelsNL(spi_t *spi, const void *data_in, uint32_t
if (msb) { if (msb) {
if (l_bytes && i == (c_longs - 1)) { if (l_bytes && i == (c_longs - 1)) {
if (l_bytes == 2) { if (l_bytes == 2) {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
MSB_16_SET(spi->dev->data_buf[i].val, data[i]); MSB_16_SET(spi->dev->data_buf[i].val, data[i]);
#else #else
MSB_16_SET(spi->dev->data_buf[i], data[i]); MSB_16_SET(spi->dev->data_buf[i], data[i]);
#endif #endif
} else { } else {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = data[i] & 0xFF; spi->dev->data_buf[i].val = data[i] & 0xFF;
#else #else
spi->dev->data_buf[i] = data[i] & 0xFF; spi->dev->data_buf[i] = data[i] & 0xFF;
#endif #endif
} }
} else { } else {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
MSB_PIX_SET(spi->dev->data_buf[i].val, data[i]); MSB_PIX_SET(spi->dev->data_buf[i].val, data[i]);
#else #else
MSB_PIX_SET(spi->dev->data_buf[i], data[i]); MSB_PIX_SET(spi->dev->data_buf[i], data[i]);
#endif #endif
} }
} else { } else {
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
spi->dev->data_buf[i].val = data[i]; spi->dev->data_buf[i].val = data[i];
#else #else
spi->dev->data_buf[i] = data[i]; spi->dev->data_buf[i] = data[i];

View file

@ -27,19 +27,13 @@ extern "C" {
#include <stdbool.h> #include <stdbool.h>
#define SPI_HAS_TRANSACTION #define SPI_HAS_TRANSACTION
#ifdef CONFIG_IDF_TARGET_ESP32
#ifdef CONFIG_IDF_TARGET_ESP32S2
#define FSPI 1 //SPI 1 bus. ESP32S2: for external memory only (can use the same data lines but different SS)
#define HSPI 2 //SPI 2 bus. ESP32S2: external memory or device - it can be matrixed to any pins
#define SPI2 2 // Another name for ESP32S2 SPI 2
#define SPI3 3 //SPI 3 bus. ESP32S2: device only - it can be matrixed to any pins
#elif CONFIG_IDF_TARGET_ESP32
#define FSPI 1 //SPI 1 bus attached to the flash (can use the same data lines but different SS) #define FSPI 1 //SPI 1 bus attached to the flash (can use the same data lines but different SS)
#define HSPI 2 //SPI 2 bus normally mapped to pins 12 - 15, but can be matrixed to any pins #define HSPI 2 //SPI 2 bus normally mapped to pins 12 - 15, but can be matrixed to any pins
#define VSPI 3 //SPI 3 bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins #define VSPI 3 //SPI 3 bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
#else #else
#define FSPI 0 #define FSPI 0 // ESP32C2, C3, C6, H2, S2, S3, P4 - SPI 2 bus
#define HSPI 1 #define HSPI 1 // ESP32S2, S3, P4 - SPI 3 bus
#endif #endif
// This defines are not representing the real Divider of the ESP32 // This defines are not representing the real Divider of the ESP32
@ -97,6 +91,8 @@ void spiSSSet(spi_t *spi);
void spiSSClear(spi_t *spi); void spiSSClear(spi_t *spi);
void spiWaitReady(spi_t *spi); void spiWaitReady(spi_t *spi);
//invert hardware SS
void spiSSInvert(spi_t *spi, bool invert);
uint32_t spiGetClockDiv(spi_t *spi); uint32_t spiGetClockDiv(spi_t *spi);
uint8_t spiGetDataMode(spi_t *spi); uint8_t spiGetDataMode(spi_t *spi);

View file

@ -22,6 +22,12 @@
#include "esp_clk_tree.h" #include "esp_clk_tree.h"
#endif #endif
#if CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
#define TIMER_IRAM IRAM_ATTR
#else
#define TIMER_IRAM
#endif
typedef void (*voidFuncPtr)(void); typedef void (*voidFuncPtr)(void);
typedef void (*voidFuncPtrArg)(void *); typedef void (*voidFuncPtrArg)(void *);
@ -36,9 +42,11 @@ struct timer_struct_t {
bool timer_started; bool timer_started;
}; };
inline uint64_t timerRead(hw_timer_t *timer) { inline TIMER_IRAM uint64_t timerRead(hw_timer_t *timer) {
if (timer == NULL) { if (timer == NULL) {
#ifndef CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
log_e("Timer handle is NULL"); log_e("Timer handle is NULL");
#endif
return 0; return 0;
} }
uint64_t value; uint64_t value;
@ -46,17 +54,21 @@ inline uint64_t timerRead(hw_timer_t *timer) {
return value; return value;
} }
void timerWrite(hw_timer_t *timer, uint64_t val) { void TIMER_IRAM timerWrite(hw_timer_t *timer, uint64_t val) {
if (timer == NULL) { if (timer == NULL) {
#ifndef CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
log_e("Timer handle is NULL"); log_e("Timer handle is NULL");
#endif
return; return;
} }
gptimer_set_raw_count(timer->timer_handle, val); gptimer_set_raw_count(timer->timer_handle, val);
} }
void timerAlarm(hw_timer_t *timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count) { void TIMER_IRAM timerAlarm(hw_timer_t *timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count) {
if (timer == NULL) { if (timer == NULL) {
#ifndef CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
log_e("Timer handle is NULL"); log_e("Timer handle is NULL");
#endif
return; return;
} }
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
@ -67,7 +79,9 @@ void timerAlarm(hw_timer_t *timer, uint64_t alarm_value, bool autoreload, uint64
}; };
err = gptimer_set_alarm_action(timer->timer_handle, &alarm_cfg); err = gptimer_set_alarm_action(timer->timer_handle, &alarm_cfg);
if (err != ESP_OK) { if (err != ESP_OK) {
#ifndef CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
log_e("Timer Alarm Write failed, error num=%d", err); log_e("Timer Alarm Write failed, error num=%d", err);
#endif
} }
} }
@ -80,27 +94,33 @@ uint32_t timerGetFrequency(hw_timer_t *timer) {
return frequency; return frequency;
} }
void timerStart(hw_timer_t *timer) { void TIMER_IRAM timerStart(hw_timer_t *timer) {
if (timer == NULL) { if (timer == NULL) {
#ifndef CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
log_e("Timer handle is NULL"); log_e("Timer handle is NULL");
#endif
return; return;
} }
gptimer_start(timer->timer_handle); gptimer_start(timer->timer_handle);
timer->timer_started = true; timer->timer_started = true;
} }
void timerStop(hw_timer_t *timer) { void TIMER_IRAM timerStop(hw_timer_t *timer) {
if (timer == NULL) { if (timer == NULL) {
#ifndef CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
log_e("Timer handle is NULL"); log_e("Timer handle is NULL");
#endif
return; return;
} }
gptimer_stop(timer->timer_handle); gptimer_stop(timer->timer_handle);
timer->timer_started = false; timer->timer_started = false;
} }
void timerRestart(hw_timer_t *timer) { void TIMER_IRAM timerRestart(hw_timer_t *timer) {
if (timer == NULL) { if (timer == NULL) {
#ifndef CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM
log_e("Timer handle is NULL"); log_e("Timer handle is NULL");
#endif
return; return;
} }
gptimer_set_raw_count(timer->timer_handle, 0); gptimer_set_raw_count(timer->timer_handle, 0);

View file

@ -466,9 +466,6 @@ __attribute__((weak)) int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint
__attribute__((weak)) int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) { __attribute__((weak)) int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) {
return -1; return -1;
} }
__attribute__((weak)) bool tud_msc_is_writable_cb(uint8_t lun) {
return false;
}
#endif #endif
#if CFG_TUD_NCM #if CFG_TUD_NCM
__attribute__((weak)) bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { __attribute__((weak)) bool tud_network_recv_cb(const uint8_t *src, uint16_t size) {

View file

@ -1,4 +1,4 @@
// Copyright 2015-2024 Espressif Systems (Shanghai) PTE LTD // Copyright 2015-2025 Espressif Systems (Shanghai) PTE LTD
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -32,6 +32,12 @@
#include "driver/gpio.h" #include "driver/gpio.h"
#include "hal/gpio_hal.h" #include "hal/gpio_hal.h"
#include "esp_rom_gpio.h" #include "esp_rom_gpio.h"
#include "esp_private/gpio.h"
#include "driver/rtc_io.h"
#include "driver/lp_io.h"
#include "soc/uart_pins.h"
#include "esp_private/uart_share_hw_ctrl.h"
static int s_uart_debug_nr = 0; // UART number for debug output static int s_uart_debug_nr = 0; // UART number for debug output
#define REF_TICK_BAUDRATE_LIMIT 250000 // this is maximum UART badrate using REF_TICK as clock #define REF_TICK_BAUDRATE_LIMIT 250000 // this is maximum UART badrate using REF_TICK as clock
@ -53,6 +59,7 @@ struct uart_struct_t {
uint16_t _rx_buffer_size, _tx_buffer_size; // UART RX and TX buffer sizes uint16_t _rx_buffer_size, _tx_buffer_size; // UART RX and TX buffer sizes
bool _inverted; // UART inverted signal bool _inverted; // UART inverted signal
uint8_t _rxfifo_full_thrhd; // UART RX FIFO full threshold uint8_t _rxfifo_full_thrhd; // UART RX FIFO full threshold
int8_t _uart_clock_source; // UART Clock Source used when it is started using uartBegin()
}; };
#if CONFIG_DISABLE_HAL_LOCKS #if CONFIG_DISABLE_HAL_LOCKS
@ -61,18 +68,21 @@ struct uart_struct_t {
#define UART_MUTEX_UNLOCK() #define UART_MUTEX_UNLOCK()
static uart_t _uart_bus_array[] = { static uart_t _uart_bus_array[] = {
{0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#if SOC_UART_HP_NUM > 1 #if SOC_UART_NUM > 1
{1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif #endif
#if SOC_UART_HP_NUM > 2 #if SOC_UART_NUM > 2
{2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif #endif
#if SOC_UART_HP_NUM > 3 #if SOC_UART_NUM > 3
{3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif #endif
#if SOC_UART_HP_NUM > 4 #if SOC_UART_NUM > 4
{4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 5
{5, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif #endif
}; };
@ -87,28 +97,130 @@ static uart_t _uart_bus_array[] = {
xSemaphoreGive(uart->lock) xSemaphoreGive(uart->lock)
static uart_t _uart_bus_array[] = { static uart_t _uart_bus_array[] = {
{NULL, 0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {NULL, 0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#if SOC_UART_HP_NUM > 1 #if SOC_UART_NUM > 1
{NULL, 1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {NULL, 1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif #endif
#if SOC_UART_HP_NUM > 2 #if SOC_UART_NUM > 2
{NULL, 2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {NULL, 2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif #endif
#if SOC_UART_HP_NUM > 3 #if SOC_UART_NUM > 3
{NULL, 3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {NULL, 3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif #endif
#if SOC_UART_HP_NUM > 4 #if SOC_UART_NUM > 4
{NULL, 4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, {NULL, 4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif
#if SOC_UART_NUM > 5
{NULL, 5, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0, -1},
#endif #endif
}; };
#endif #endif
#if SOC_UART_LP_NUM >= 1
// LP UART enable pins routine
static bool lp_uart_config_io(uint8_t uart_num, int8_t pin, rtc_gpio_mode_t direction, uint32_t idx) {
/* Skip configuration if the LP_IO is -1 */
if (pin < 0) {
return true;
}
// Initialize LP_IO
if (rtc_gpio_init(pin) != ESP_OK) {
log_e("Failed to initialize LP_IO %d", pin);
return false;
}
// Set LP_IO direction
if (rtc_gpio_set_direction(pin, direction) != ESP_OK) {
log_e("Failed to set LP_IO %d direction", pin);
return false;
}
// Connect pins
const uart_periph_sig_t *upin = &uart_periph_signal[uart_num].pins[idx];
#if !SOC_LP_GPIO_MATRIX_SUPPORTED // ESP32-C6/C61/C5
// When LP_IO Matrix is not support, LP_IO Mux must be connected to the pins
if (rtc_gpio_iomux_func_sel(pin, upin->iomux_func) != ESP_OK) {
log_e("Failed to set LP_IO pin %d into Mux function", pin);
return false;
}
#else // So far, only ESP32-P4
// If the configured pin is the default LP_IO Mux pin for LP UART, then set the LP_IO MUX function
if (upin->default_gpio == pin) {
if (rtc_gpio_iomux_func_sel(pin, upin->iomux_func) != ESP_OK) {
log_e("Failed to set LP_IO pin %d into Mux function", pin);
return false;
}
} else {
// Otherwise, set the LP_IO Matrix and select FUNC1
if (rtc_gpio_iomux_func_sel(pin, 1) != ESP_OK) {
log_e("Failed to set LP_IO pin %d into Mux function GPIO", pin);
return false;
}
// Connect the LP_IO to the LP UART peripheral signal
esp_err_t ret;
if (direction == RTC_GPIO_MODE_OUTPUT_ONLY) {
ret = lp_gpio_connect_out_signal(pin, UART_PERIPH_SIGNAL(uart_num, idx), 0, 0);
} else {
ret = lp_gpio_connect_in_signal(pin, UART_PERIPH_SIGNAL(uart_num, idx), 0);
}
if (ret != ESP_OK) {
log_e("Failed to connect LP_IO pin %d to UART%d signal", pin, uart_num);
return false;
}
}
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
return true;
}
// When LP UART needs the RTC IO MUX to set the pin, it will always have fixed pins for RX, TX, CTS and RTS
static bool lpuartCheckPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin, uint8_t uart_nr) {
// check if LP UART is being used and if the pins are valid
#if !SOC_LP_GPIO_MATRIX_SUPPORTED // ESP32-C6/C61/C5
uint16_t lp_uart_fixed_pin = uart_periph_signal[uart_nr].pins[SOC_UART_RX_PIN_IDX].default_gpio;
if (uart_nr >= SOC_UART_HP_NUM) { // it is a LP UART NUM
if (rxPin > 0 && rxPin != lp_uart_fixed_pin) {
log_e("UART%d LP UART requires RX pin to be set to %d.", uart_nr, lp_uart_fixed_pin);
return false;
}
lp_uart_fixed_pin = uart_periph_signal[uart_nr].pins[SOC_UART_TX_PIN_IDX].default_gpio;
if (txPin > 0 && txPin != lp_uart_fixed_pin) {
log_e("UART%d LP UART requires TX pin to be set to %d.", uart_nr, lp_uart_fixed_pin);
return false;
}
lp_uart_fixed_pin = uart_periph_signal[uart_nr].pins[SOC_UART_CTS_PIN_IDX].default_gpio;
if (ctsPin > 0 && ctsPin != lp_uart_fixed_pin) {
log_e("UART%d LP UART requires CTS pin to be set to %d.", uart_nr, lp_uart_fixed_pin);
return false;
}
lp_uart_fixed_pin = uart_periph_signal[uart_nr].pins[SOC_UART_RTS_PIN_IDX].default_gpio;
if (rtsPin > 0 && rtsPin != lp_uart_fixed_pin) {
log_e("UART%d LP UART requires RTS pin to be set to %d.", uart_nr, lp_uart_fixed_pin);
return false;
}
}
return true;
#else // ESP32-P4 can set any pin for LP UART
return true;
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
}
#endif // SOC_UART_LP_NUM >= 1
#ifndef GPIO_FUNC_IN_LOW
#define GPIO_FUNC_IN_LOW GPIO_MATRIX_CONST_ZERO_INPUT
#endif
#ifndef GPIO_FUNC_IN_HIGH
#define GPIO_FUNC_IN_HIGH GPIO_MATRIX_CONST_ONE_INPUT
#endif
// Negative Pin Number will keep it unmodified, thus this function can detach individual pins // Negative Pin Number will keep it unmodified, thus this function can detach individual pins
// This function will also unset the pins in the Peripheral Manager and set the pin to -1 after detaching // This function will also unset the pins in the Peripheral Manager and set the pin to -1 after detaching
static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
if (uart_num >= SOC_UART_HP_NUM) { if (uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
return false; return false;
} }
// get UART information // get UART information
@ -117,9 +229,10 @@ static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
//log_v("detaching UART%d pins: prev,pin RX(%d,%d) TX(%d,%d) CTS(%d,%d) RTS(%d,%d)", uart_num, //log_v("detaching UART%d pins: prev,pin RX(%d,%d) TX(%d,%d) CTS(%d,%d) RTS(%d,%d)", uart_num,
// uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10); // uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10);
// detaches pins and sets Peripheral Manager and UART information // detaches HP and LP pins and sets Peripheral Manager and UART information
if (rxPin >= 0 && uart->_rxPin == rxPin && perimanGetPinBusType(rxPin) == ESP32_BUS_TYPE_UART_RX) { if (rxPin >= 0 && uart->_rxPin == rxPin && perimanGetPinBusType(rxPin) == ESP32_BUS_TYPE_UART_RX) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rxPin], PIN_FUNC_GPIO); //gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rxPin], PIN_FUNC_GPIO);
esp_rom_gpio_pad_select_gpio(rxPin);
// avoids causing BREAK in the UART line // avoids causing BREAK in the UART line
if (uart->_inverted) { if (uart->_inverted) {
esp_rom_gpio_connect_in_signal(GPIO_FUNC_IN_LOW, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false); esp_rom_gpio_connect_in_signal(GPIO_FUNC_IN_LOW, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false);
@ -133,7 +246,8 @@ static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
} }
} }
if (txPin >= 0 && uart->_txPin == txPin && perimanGetPinBusType(txPin) == ESP32_BUS_TYPE_UART_TX) { if (txPin >= 0 && uart->_txPin == txPin && perimanGetPinBusType(txPin) == ESP32_BUS_TYPE_UART_TX) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[txPin], PIN_FUNC_GPIO); //gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[txPin], PIN_FUNC_GPIO);
esp_rom_gpio_pad_select_gpio(txPin);
esp_rom_gpio_connect_out_signal(txPin, SIG_GPIO_OUT_IDX, false, false); esp_rom_gpio_connect_out_signal(txPin, SIG_GPIO_OUT_IDX, false, false);
uart->_txPin = -1; // -1 means unassigned/detached uart->_txPin = -1; // -1 means unassigned/detached
if (!perimanClearPinBus(txPin)) { if (!perimanClearPinBus(txPin)) {
@ -142,7 +256,8 @@ static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
} }
} }
if (ctsPin >= 0 && uart->_ctsPin == ctsPin && perimanGetPinBusType(ctsPin) == ESP32_BUS_TYPE_UART_CTS) { if (ctsPin >= 0 && uart->_ctsPin == ctsPin && perimanGetPinBusType(ctsPin) == ESP32_BUS_TYPE_UART_CTS) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[ctsPin], PIN_FUNC_GPIO); //gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[ctsPin], PIN_FUNC_GPIO);
esp_rom_gpio_pad_select_gpio(ctsPin);
esp_rom_gpio_connect_in_signal(GPIO_FUNC_IN_LOW, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false); esp_rom_gpio_connect_in_signal(GPIO_FUNC_IN_LOW, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false);
uart->_ctsPin = -1; // -1 means unassigned/detached uart->_ctsPin = -1; // -1 means unassigned/detached
if (!perimanClearPinBus(ctsPin)) { if (!perimanClearPinBus(ctsPin)) {
@ -151,7 +266,8 @@ static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
} }
} }
if (rtsPin >= 0 && uart->_rtsPin == rtsPin && perimanGetPinBusType(rtsPin) == ESP32_BUS_TYPE_UART_RTS) { if (rtsPin >= 0 && uart->_rtsPin == rtsPin && perimanGetPinBusType(rtsPin) == ESP32_BUS_TYPE_UART_RTS) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rtsPin], PIN_FUNC_GPIO); //gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rtsPin], PIN_FUNC_GPIO);
esp_rom_gpio_pad_select_gpio(rtsPin);
esp_rom_gpio_connect_out_signal(rtsPin, SIG_GPIO_OUT_IDX, false, false); esp_rom_gpio_connect_out_signal(rtsPin, SIG_GPIO_OUT_IDX, false, false);
uart->_rtsPin = -1; // -1 means unassigned/detached uart->_rtsPin = -1; // -1 means unassigned/detached
if (!perimanClearPinBus(rtsPin)) { if (!perimanClearPinBus(rtsPin)) {
@ -191,11 +307,152 @@ static bool _uartDetachBus_RTS(void *busptr) {
return _uartDetachPins(bus->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, bus->_rtsPin); return _uartDetachPins(bus->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, bus->_rtsPin);
} }
static bool _uartTrySetIomuxPin(uart_port_t uart_num, int io_num, uint32_t idx) {
// Store a pointer to the default pin, to optimize access to its fields.
const uart_periph_sig_t *upin = &uart_periph_signal[uart_num].pins[idx];
// In theory, if default_gpio is -1, iomux_func should also be -1, but let's be safe and test both.
if (upin->iomux_func == -1 || upin->default_gpio == -1 || upin->default_gpio != io_num) {
return false;
}
// Assign the correct function to the GPIO.
if (upin->iomux_func == -1) {
log_e("IO#%d has bad IOMUX internal information. Switching to GPIO Matrix UART function.", io_num);
return false;
}
if (uart_num < SOC_UART_HP_NUM) {
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
if (upin->input) {
gpio_iomux_input(io_num, upin->iomux_func, upin->signal);
} else {
gpio_iomux_output(io_num, upin->iomux_func);
}
#else
gpio_iomux_out(io_num, upin->iomux_func, false);
// If the pin is input, we also have to redirect the signal, in order to bypass the GPIO matrix.
if (upin->input) {
gpio_iomux_in(io_num, upin->signal);
}
#endif
}
#if (SOC_UART_LP_NUM >= 1) && (SOC_RTCIO_PIN_COUNT >= 1)
else {
if (upin->input) {
rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_INPUT_ONLY);
} else {
rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_OUTPUT_ONLY);
}
rtc_gpio_init(io_num);
rtc_gpio_iomux_func_sel(io_num, upin->iomux_func);
}
#endif
return true;
}
static esp_err_t _uartInternalSetPin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) {
// Since an IO cannot route peripheral signals via IOMUX and GPIO matrix at the same time,
// if tx and rx share the same IO, both signals need to be routed to IOs through GPIO matrix
bool tx_rx_same_io = (tx_io_num == rx_io_num);
// In the following statements, if the io_num is negative, no need to configure anything.
if (tx_io_num >= 0) {
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
// But TX IO in isolate state could write garbled data to the other end
// Therefore, we should disable the switch of the TX pin to sleep configuration
gpio_sleep_sel_dis(tx_io_num);
#endif
if (tx_rx_same_io || !_uartTrySetIomuxPin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) {
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
// (output enabled too early may cause unnecessary level change at the pad)
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
else {
rtc_gpio_init(tx_io_num); // set as a LP_GPIO pin
lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
}
#endif
}
}
if (rx_io_num >= 0) {
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
// But RX IO in isolate state could receive garbled data into FIFO, which is not desired
// Therefore, we should disable the switch of the RX pin to sleep configuration
gpio_sleep_sel_dis(rx_io_num);
#endif
if (tx_rx_same_io || !_uartTrySetIomuxPin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) {
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0)
gpio_input_enable(rx_io_num);
#else
gpio_func_sel(rx_io_num, PIN_FUNC_GPIO);
gpio_ll_input_enable(&GPIO, rx_io_num);
#endif
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
else {
rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_set_direction(rx_io_num, mode);
if (!tx_rx_same_io) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
rtc_gpio_init(rx_io_num); // set as a LP_GPIO pin
}
lp_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
}
#endif
}
}
if (rts_io_num >= 0 && !_uartTrySetIomuxPin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) {
gpio_func_sel(rts_io_num, PIN_FUNC_GPIO);
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
else {
rtc_gpio_init(rts_io_num); // set as a LP_GPIO pin
lp_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
}
#endif
}
if (cts_io_num >= 0 && !_uartTrySetIomuxPin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) {
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0)
gpio_pullup_en(cts_io_num);
gpio_input_enable(cts_io_num);
#else
gpio_func_sel(cts_io_num, PIN_FUNC_GPIO);
gpio_set_pull_mode(cts_io_num, GPIO_PULLUP_ONLY);
gpio_set_direction(cts_io_num, GPIO_MODE_INPUT);
#endif
esp_rom_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0);
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
else {
rtc_gpio_set_direction(cts_io_num, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_init(cts_io_num); // set as a LP_GPIO pin
lp_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0);
}
#endif
}
return ESP_OK;
}
// Attach function for UART // Attach function for UART
// connects the IO Pad, set Paripheral Manager and internal UART structure data // connects the IO Pad, set Paripheral Manager and internal UART structure data
static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
if (uart_num >= SOC_UART_HP_NUM) { if (uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
return false; return false;
} }
// get UART information // get UART information
@ -203,6 +460,8 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
//log_v("attaching UART%d pins: prev,new RX(%d,%d) TX(%d,%d) CTS(%d,%d) RTS(%d,%d)", uart_num, //log_v("attaching UART%d pins: prev,new RX(%d,%d) TX(%d,%d) CTS(%d,%d) RTS(%d,%d)", uart_num,
// uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10); // uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10);
// IDF _uartInternalSetPin() checks if the pin is used within LP UART and if it is a valid RTC IO pin
// No need for Arduino Layer to check it again
bool retCode = true; bool retCode = true;
if (rxPin >= 0) { if (rxPin >= 0) {
// forces a clean detaching from a previous peripheral // forces a clean detaching from a previous peripheral
@ -210,7 +469,12 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
perimanClearPinBus(rxPin); perimanClearPinBus(rxPin);
} }
// connect RX Pad // connect RX Pad
bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); bool ret = ESP_OK == _uartInternalSetPin(uart->num, UART_PIN_NO_CHANGE, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
#if SOC_UART_LP_NUM >= 1
if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
ret &= lp_uart_config_io(uart->num, rxPin, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_RX_PIN_IDX);
}
#endif
if (ret) { if (ret) {
ret &= perimanSetPinBus(rxPin, ESP32_BUS_TYPE_UART_RX, (void *)uart, uart_num, -1); ret &= perimanSetPinBus(rxPin, ESP32_BUS_TYPE_UART_RX, (void *)uart, uart_num, -1);
if (ret) { if (ret) {
@ -228,7 +492,12 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
perimanClearPinBus(txPin); perimanClearPinBus(txPin);
} }
// connect TX Pad // connect TX Pad
bool ret = ESP_OK == uart_set_pin(uart->num, txPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); bool ret = ESP_OK == _uartInternalSetPin(uart->num, txPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
#if SOC_UART_LP_NUM >= 1
if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
ret &= lp_uart_config_io(uart->num, txPin, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_TX_PIN_IDX);
}
#endif
if (ret) { if (ret) {
ret &= perimanSetPinBus(txPin, ESP32_BUS_TYPE_UART_TX, (void *)uart, uart_num, -1); ret &= perimanSetPinBus(txPin, ESP32_BUS_TYPE_UART_TX, (void *)uart, uart_num, -1);
if (ret) { if (ret) {
@ -246,7 +515,12 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
perimanClearPinBus(ctsPin); perimanClearPinBus(ctsPin);
} }
// connect CTS Pad // connect CTS Pad
bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, ctsPin); bool ret = ESP_OK == _uartInternalSetPin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, ctsPin);
#if SOC_UART_LP_NUM >= 1
if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
ret &= lp_uart_config_io(uart->num, ctsPin, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_CTS_PIN_IDX);
}
#endif
if (ret) { if (ret) {
ret &= perimanSetPinBus(ctsPin, ESP32_BUS_TYPE_UART_CTS, (void *)uart, uart_num, -1); ret &= perimanSetPinBus(ctsPin, ESP32_BUS_TYPE_UART_CTS, (void *)uart, uart_num, -1);
if (ret) { if (ret) {
@ -264,7 +538,12 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
perimanClearPinBus(rtsPin); perimanClearPinBus(rtsPin);
} }
// connect RTS Pad // connect RTS Pad
bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, rtsPin, UART_PIN_NO_CHANGE); bool ret = ESP_OK == _uartInternalSetPin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, rtsPin, UART_PIN_NO_CHANGE);
#if SOC_UART_LP_NUM >= 1
if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
ret &= lp_uart_config_io(uart->num, rtsPin, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_RTS_PIN_IDX);
}
#endif
if (ret) { if (ret) {
ret &= perimanSetPinBus(rtsPin, ESP32_BUS_TYPE_UART_RTS, (void *)uart, uart_num, -1); ret &= perimanSetPinBus(rtsPin, ESP32_BUS_TYPE_UART_RTS, (void *)uart, uart_num, -1);
if (ret) { if (ret) {
@ -321,13 +600,20 @@ bool uartIsDriverInstalled(uart_t *uart) {
// Negative Pin Number will keep it unmodified, thus this function can set individual pins // Negative Pin Number will keep it unmodified, thus this function can set individual pins
// When pins are changed, it will detach the previous one // When pins are changed, it will detach the previous one
bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
if (uart_num >= SOC_UART_HP_NUM) { if (uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
return false; return false;
} }
// get UART information // get UART information
uart_t *uart = &_uart_bus_array[uart_num]; uart_t *uart = &_uart_bus_array[uart_num];
#if SOC_UART_LP_NUM >= 1
// check if LP UART is being used and if the pins are valid
if (!lpuartCheckPins(rxPin, txPin, ctsPin, rtsPin, uart_num)) {
return false; // failed to set pins
}
#endif
bool retCode = true; bool retCode = true;
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
@ -391,7 +677,7 @@ bool _testUartBegin(
uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint32_t rx_buffer_size, uint32_t tx_buffer_size, bool inverted, uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint32_t rx_buffer_size, uint32_t tx_buffer_size, bool inverted,
uint8_t rxfifo_full_thrhd uint8_t rxfifo_full_thrhd
) { ) {
if (uart_nr >= SOC_UART_HP_NUM) { if (uart_nr >= SOC_UART_NUM) {
return false; // no new driver has to be installed return false; // no new driver has to be installed
} }
uart_t *uart = &_uart_bus_array[uart_nr]; uart_t *uart = &_uart_bus_array[uart_nr];
@ -413,13 +699,24 @@ uart_t *uartBegin(
uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint32_t rx_buffer_size, uint32_t tx_buffer_size, bool inverted, uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint32_t rx_buffer_size, uint32_t tx_buffer_size, bool inverted,
uint8_t rxfifo_full_thrhd uint8_t rxfifo_full_thrhd
) { ) {
if (uart_nr >= SOC_UART_HP_NUM) { if (uart_nr >= SOC_UART_NUM) {
log_e("UART number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); log_e("UART number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
return NULL; // no new driver was installed return NULL; // no new driver was installed
} }
uart_t *uart = &_uart_bus_array[uart_nr]; uart_t *uart = &_uart_bus_array[uart_nr];
log_v("UART%d baud(%ld) Mode(%x) rxPin(%d) txPin(%d)", uart_nr, baudrate, config, rxPin, txPin); log_v("UART%d baud(%ld) Mode(%x) rxPin(%d) txPin(%d)", uart_nr, baudrate, config, rxPin, txPin);
#if SOC_UART_LP_NUM >= 1
// check if LP UART is being used and if the pins are valid
if (!lpuartCheckPins(rxPin, txPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, uart_nr)) {
if (uart_is_driver_installed(uart_nr)) {
return uart; // keep the same installed driver
} else {
return NULL; // no new driver was installed
}
}
#endif
#if !CONFIG_DISABLE_HAL_LOCKS #if !CONFIG_DISABLE_HAL_LOCKS
if (uart->lock == NULL) { if (uart->lock == NULL) {
uart->lock = xSemaphoreCreateMutex(); uart->lock = xSemaphoreCreateMutex();
@ -436,20 +733,18 @@ uart_t *uartBegin(
if (uart->_rx_buffer_size != rx_buffer_size || uart->_tx_buffer_size != tx_buffer_size || uart->_inverted != inverted if (uart->_rx_buffer_size != rx_buffer_size || uart->_tx_buffer_size != tx_buffer_size || uart->_inverted != inverted
|| uart->_rxfifo_full_thrhd != rxfifo_full_thrhd) { || uart->_rxfifo_full_thrhd != rxfifo_full_thrhd) {
log_v("UART%d changing buffer sizes or inverted signal or rxfifo_full_thrhd. IDF driver will be restarted", uart_nr); log_v("UART%d changing buffer sizes or inverted signal or rxfifo_full_thrhd. IDF driver will be restarted", uart_nr);
log_v("RX buffer size: %d -> %d", uart->_rx_buffer_size, rx_buffer_size);
log_v("TX buffer size: %d -> %d", uart->_tx_buffer_size, tx_buffer_size);
log_v("Inverted signal: %s -> %s", uart->_inverted ? "true" : "false", inverted ? "true" : "false");
log_v("RX FIFO full threshold: %d -> %d", uart->_rxfifo_full_thrhd, rxfifo_full_thrhd);
uartEnd(uart_nr); uartEnd(uart_nr);
} else { } else {
bool retCode = true; bool retCode = true;
UART_MUTEX_LOCK();
//User may just want to change some parameters, such as baudrate, data length, parity, stop bits or pins //User may just want to change some parameters, such as baudrate, data length, parity, stop bits or pins
if (uart->_baudrate != baudrate) { if (uart->_baudrate != baudrate) {
if (ESP_OK != uart_set_baudrate(uart_nr, baudrate)) { retCode = uartSetBaudRate(uart, baudrate);
log_e("UART%d changing baudrate failed.", uart_nr);
retCode = false;
} else {
log_v("UART%d changed baudrate to %d", uart_nr, baudrate);
uart->_baudrate = baudrate;
}
} }
UART_MUTEX_LOCK();
uart_word_length_t data_bits = (config & 0xc) >> 2; uart_word_length_t data_bits = (config & 0xc) >> 2;
uart_parity_t parity = config & 0x3; uart_parity_t parity = config & 0x3;
uart_stop_bits_t stop_bits = (config & 0x30) >> 4; uart_stop_bits_t stop_bits = (config & 0x30) >> 4;
@ -500,7 +795,7 @@ uart_t *uartBegin(
} }
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
if (retCode) { if (retCode) {
// UART driver was already working, just return the uart_t structure, syaing that no new driver was installed // UART driver was already working, just return the uart_t structure, saying that no new driver was installed
return uart; return uart;
} }
// if we reach this point, it means that we need to restart the UART driver // if we reach this point, it means that we need to restart the UART driver
@ -516,22 +811,49 @@ uart_t *uartBegin(
uart_config.parity = (config & 0x3); uart_config.parity = (config & 0x3);
uart_config.stop_bits = (config & 0x30) >> 4; uart_config.stop_bits = (config & 0x30) >> 4;
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
uart_config.rx_flow_ctrl_thresh = rxfifo_full_thrhd; uart_config.rx_flow_ctrl_thresh = rxfifo_full_thrhd >= UART_HW_FIFO_LEN(uart_nr) ? UART_HW_FIFO_LEN(uart_nr) - 6 : rxfifo_full_thrhd;
log_v(
"UART%d RX FIFO full threshold set to %d (value requested: %d || FIFO Max = %d)", uart_nr, uart_config.rx_flow_ctrl_thresh, rxfifo_full_thrhd,
UART_HW_FIFO_LEN(uart_nr)
);
rxfifo_full_thrhd = uart_config.rx_flow_ctrl_thresh; // makes sure that it will be set correctly in the struct
uart_config.baud_rate = baudrate; uart_config.baud_rate = baudrate;
#if SOC_UART_LP_NUM >= 1
if (uart_nr >= SOC_UART_HP_NUM) { // it is a LP UART NUM
if (uart->_uart_clock_source > 0) {
uart_config.lp_source_clk = (soc_periph_lp_uart_clk_src_t)uart->_uart_clock_source; // use user defined LP UART clock
log_v("Setting UART%d to user defined LP clock source (%d) ", uart_nr, uart->_uart_clock_source);
} else {
uart_config.lp_source_clk = LP_UART_SCLK_DEFAULT; // use default LP clock
log_v("Setting UART%d to Default LP clock source", uart_nr);
}
} else
#endif // SOC_UART_LP_NUM >= 1
{
if (uart->_uart_clock_source >= 0) {
uart_config.source_clk = (soc_module_clk_t)uart->_uart_clock_source; // use user defined HP UART clock
log_v("Setting UART%d to user defined HP clock source (%d) ", uart_nr, uart->_uart_clock_source);
} else {
// there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored // there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored
// therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue. // therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue.
#if SOC_UART_SUPPORT_XTAL_CLK #if SOC_UART_SUPPORT_XTAL_CLK
uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4 uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4
log_v("Setting UART%d to use XTAL clock", uart_nr);
#elif SOC_UART_SUPPORT_REF_TICK #elif SOC_UART_SUPPORT_REF_TICK
if (baudrate <= REF_TICK_BAUDRATE_LIMIT) { if (baudrate <= REF_TICK_BAUDRATE_LIMIT) {
uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
log_v("Setting UART%d to use REF_TICK clock", uart_nr);
} else { } else {
uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency! uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency!
log_v("Setting UART%d to use APB clock", uart_nr);
} }
#else #else
// Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6 // Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6|P4
uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency! uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency!
#endif log_v("Setting UART%d to use DEFAULT clock", uart_nr);
#endif // SOC_UART_SUPPORT_XTAL_CLK
}
}
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
bool retCode = ESP_OK == uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0); bool retCode = ESP_OK == uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0);
@ -559,6 +881,14 @@ uart_t *uartBegin(
uart->_tx_buffer_size = tx_buffer_size; uart->_tx_buffer_size = tx_buffer_size;
uart->has_peek = false; uart->has_peek = false;
uart->peek_byte = 0; uart->peek_byte = 0;
#if SOC_UART_LP_NUM >= 1
if (uart_nr >= SOC_UART_HP_NUM) {
uart->_uart_clock_source = uart_config.lp_source_clk;
} else
#endif
{
uart->_uart_clock_source = uart_config.source_clk;
}
} }
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
@ -600,7 +930,11 @@ bool uartSetRxTimeout(uart_t *uart, uint8_t numSymbTimeout) {
if (uart == NULL) { if (uart == NULL) {
return false; return false;
} }
uint16_t maxRXTimeout = uart_get_max_rx_timeout(uart->num);
if (numSymbTimeout > maxRXTimeout) {
log_e("Invalid RX Timeout value, its limit is %d", maxRXTimeout);
return false;
}
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
bool retCode = (ESP_OK == uart_set_rx_timeout(uart->num, numSymbTimeout)); bool retCode = (ESP_OK == uart_set_rx_timeout(uart->num, numSymbTimeout));
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
@ -611,16 +945,25 @@ bool uartSetRxFIFOFull(uart_t *uart, uint8_t numBytesFIFOFull) {
if (uart == NULL) { if (uart == NULL) {
return false; return false;
} }
uint8_t rxfifo_full_thrhd = numBytesFIFOFull >= UART_HW_FIFO_LEN(uart->num) ? UART_HW_FIFO_LEN(uart->num) - 6 : numBytesFIFOFull;
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
bool retCode = (ESP_OK == uart_set_rx_full_threshold(uart->num, numBytesFIFOFull)); bool retCode = (ESP_OK == uart_set_rx_full_threshold(uart->num, rxfifo_full_thrhd));
if (retCode) {
uart->_rxfifo_full_thrhd = rxfifo_full_thrhd;
if (rxfifo_full_thrhd != numBytesFIFOFull) {
log_w("The RX FIFO Full value for UART%d was set to %d instead of %d", uart->num, rxfifo_full_thrhd, numBytesFIFOFull);
}
log_v("UART%d RX FIFO Full value set to %d from a requested value of %d", uart->num, rxfifo_full_thrhd, numBytesFIFOFull);
} else {
log_e("UART%d failed to set RX FIFO Full value to %d", uart->num, numBytesFIFOFull);
}
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
return retCode; return retCode;
} }
void uartEnd(uint8_t uart_num) { void uartEnd(uint8_t uart_num) {
if (uart_num >= SOC_UART_HP_NUM) { if (uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1);
return; return;
} }
// get UART information // get UART information
@ -638,14 +981,14 @@ void uartSetRxInvert(uart_t *uart, bool invert) {
if (uart == NULL) { if (uart == NULL) {
return; return;
} }
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
// POTENTIAL ISSUE :: original code only set/reset rxd_inv bit // POTENTIAL ISSUE :: original code only set/reset rxd_inv bit
// IDF or LL set/reset the whole inv_mask! // IDF or LL set/reset the whole inv_mask!
// if (invert) // if (invert)
// ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_RXD_INV)); // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_RXD_INV));
// else // else
// ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_INV_DISABLE)); // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_INV_DISABLE));
log_e("uartSetRxInvert is not supported in ESP32C6, ESP32H2 and ESP32P4");
#else #else
// this implementation is better over IDF API because it only affects RXD // this implementation is better over IDF API because it only affects RXD
// this is supported in ESP32, ESP32-S2 and ESP32-C3 // this is supported in ESP32, ESP32-S2 and ESP32-C3
@ -800,21 +1143,66 @@ void uartFlushTxOnly(uart_t *uart, bool txOnly) {
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
} }
void uartSetBaudRate(uart_t *uart, uint32_t baud_rate) { bool uartSetBaudRate(uart_t *uart, uint32_t baud_rate) {
if (uart == NULL) { if (uart == NULL) {
return; return false;
}
bool retCode = true;
soc_module_clk_t newClkSrc = UART_SCLK_DEFAULT;
int8_t previousClkSrc = uart->_uart_clock_source;
#if SOC_UART_LP_NUM >= 1
if (uart->num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
if (uart->_uart_clock_source > 0) {
newClkSrc = (soc_periph_lp_uart_clk_src_t)uart->_uart_clock_source; // use user defined LP UART clock
log_v("Setting UART%d to user defined LP clock source (%d) ", uart->num, newClkSrc);
} else {
newClkSrc = LP_UART_SCLK_DEFAULT; // use default LP clock
log_v("Setting UART%d to Default LP clock source", uart->num);
}
} else
#endif // SOC_UART_LP_NUM >= 1
{
if (uart->_uart_clock_source >= 0) {
newClkSrc = (soc_module_clk_t)uart->_uart_clock_source; // use user defined HP UART clock
log_v("Setting UART%d to use HP clock source (%d) ", uart->num, newClkSrc);
} else {
// there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored
// therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue.
#if SOC_UART_SUPPORT_XTAL_CLK
newClkSrc = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4
log_v("Setting UART%d to use XTAL clock", uart->num);
#elif SOC_UART_SUPPORT_REF_TICK
if (baud_rate <= REF_TICK_BAUDRATE_LIMIT) {
newClkSrc = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps
log_v("Setting UART%d to use REF_TICK clock", uart->num);
} else {
newClkSrc = UART_SCLK_APB; // baudrate may change with the APB Frequency!
log_v("Setting UART%d to use APB clock", uart->num);
}
#else
// Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6|P4
// using newClkSrc = UART_SCLK_DEFAULT as defined in the variable declaration
log_v("Setting UART%d to use DEFAULT clock", uart->num);
#endif // SOC_UART_SUPPORT_XTAL_CLK
}
} }
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
#if !SOC_UART_SUPPORT_XTAL_CLK // if necessary, set the correct UART Clock Source before changing the baudrate
soc_module_clk_t newClkSrc = baud_rate <= REF_TICK_BAUDRATE_LIMIT ? SOC_MOD_CLK_REF_TICK : SOC_MOD_CLK_APB; if (previousClkSrc < 0 || previousClkSrc != newClkSrc) {
HP_UART_SRC_CLK_ATOMIC() {
uart_ll_set_sclk(UART_LL_GET_HW(uart->num), newClkSrc); uart_ll_set_sclk(UART_LL_GET_HW(uart->num), newClkSrc);
#endif }
uart->_uart_clock_source = newClkSrc;
}
if (uart_set_baudrate(uart->num, baud_rate) == ESP_OK) { if (uart_set_baudrate(uart->num, baud_rate) == ESP_OK) {
log_v("Setting UART%d baud rate to %ld.", uart->num, baud_rate);
uart->_baudrate = baud_rate; uart->_baudrate = baud_rate;
} else { } else {
log_e("Setting UART%d baud rate to %d has failed.", uart->num, baud_rate); retCode = false;
log_e("Setting UART%d baud rate to %ld has failed.", uart->num, baud_rate);
} }
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
return retCode;
} }
uint32_t uartGetBaudRate(uart_t *uart) { uint32_t uartGetBaudRate(uart_t *uart) {
@ -889,7 +1277,7 @@ void uart_install_putc() {
// Routines that take care of UART mode in the HardwareSerial Class code // Routines that take care of UART mode in the HardwareSerial Class code
// used to set UART_MODE_RS485_HALF_DUPLEX auto RTS for TXD for ESP32 chips // used to set UART_MODE_RS485_HALF_DUPLEX auto RTS for TXD for ESP32 chips
bool uartSetMode(uart_t *uart, uart_mode_t mode) { bool uartSetMode(uart_t *uart, uart_mode_t mode) {
if (uart == NULL || uart->num >= SOC_UART_HP_NUM) { if (uart == NULL || uart->num >= SOC_UART_NUM) {
return false; return false;
} }
@ -899,7 +1287,37 @@ bool uartSetMode(uart_t *uart, uart_mode_t mode) {
return retCode; return retCode;
} }
// this function will set the uart clock source
// it must be called before uartBegin(), otherwise it won't change any thing.
bool uartSetClockSource(uint8_t uartNum, uart_sclk_t clkSrc) {
if (uartNum >= SOC_UART_NUM) {
log_e("UART%d is invalid. This device has %d UARTs, from 0 to %d.", uartNum, SOC_UART_NUM, SOC_UART_NUM - 1);
return false;
}
uart_t *uart = &_uart_bus_array[uartNum];
#if SOC_UART_LP_NUM >= 1
if (uart->num >= SOC_UART_HP_NUM) {
switch (clkSrc) {
case UART_SCLK_XTAL: uart->_uart_clock_source = LP_UART_SCLK_XTAL_D2; break;
#if CONFIG_IDF_TARGET_ESP32C5
case UART_SCLK_RTC: uart->_uart_clock_source = LP_UART_SCLK_RC_FAST; break;
#else
case UART_SCLK_RTC: uart->_uart_clock_source = LP_UART_SCLK_LP_FAST; break;
#endif
case UART_SCLK_DEFAULT:
default: uart->_uart_clock_source = LP_UART_SCLK_DEFAULT;
}
} else
#endif
{
uart->_uart_clock_source = clkSrc;
}
//log_i("UART%d set clock source to %d", uart->num, uart->_uart_clock_source);
return true;
}
void uartSetDebug(uart_t *uart) { void uartSetDebug(uart_t *uart) {
// LP UART is not supported for debug
if (uart == NULL || uart->num >= SOC_UART_HP_NUM) { if (uart == NULL || uart->num >= SOC_UART_HP_NUM) {
s_uart_debug_nr = -1; s_uart_debug_nr = -1;
} else { } else {
@ -926,7 +1344,7 @@ int log_printfv(const char *format, va_list arg) {
return 0; return 0;
} }
} }
/* /*
// This causes dead locks with logging in specific cases and also with C++ constructors that may send logs // This causes dead locks with logging in specific cases and also with C++ constructors that may send logs
#if !CONFIG_DISABLE_HAL_LOCKS #if !CONFIG_DISABLE_HAL_LOCKS
if(s_uart_debug_nr != -1 && _uart_bus_array[s_uart_debug_nr].lock){ if(s_uart_debug_nr != -1 && _uart_bus_array[s_uart_debug_nr].lock){
@ -934,16 +1352,8 @@ int log_printfv(const char *format, va_list arg) {
} }
#endif #endif
*/ */
#if (ARDUINO_USB_CDC_ON_BOOT == 1 && ARDUINO_USB_MODE == 0) || CONFIG_IDF_TARGET_ESP32C3 \
|| ((CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4) && ARDUINO_USB_CDC_ON_BOOT == 1)
vsnprintf(temp, len + 1, format, arg); vsnprintf(temp, len + 1, format, arg);
ets_printf("%s", temp); ets_printf("%s", temp);
#else
int wlen = vsnprintf(temp, len + 1, format, arg);
for (int i = 0; i < wlen; i++) {
ets_write_char_uart(temp[i]);
}
#endif
/* /*
// This causes dead locks with logging and also with constructors that may send logs // This causes dead locks with logging and also with constructors that may send logs
#if !CONFIG_DISABLE_HAL_LOCKS #if !CONFIG_DISABLE_HAL_LOCKS
@ -1131,49 +1541,28 @@ unsigned long uartDetectBaudrate(uart_t *uart) {
} }
/* /*
These functions are for testing purpose only and can be used in Arduino Sketches * These functions are for testing purposes only and can be used in Arduino Sketches.
Those are used in the UART examples * They are utilized in the UART examples and CI.
*/ */
/*
This is intended to make an internal loopback connection using IOMUX
The function uart_internal_loopback() shall be used right after Arduino Serial.begin(...)
This code "replaces" the physical wiring for connecting TX <--> RX in a loopback
*/
// gets the right TX or RX SIGNAL, based on the UART number from gpio_sig_map.h
#ifdef CONFIG_IDF_TARGET_ESP32P4
#define UART_TX_SIGNAL(uartNumber) \
(uartNumber == UART_NUM_0 \
? UART0_TXD_PAD_OUT_IDX \
: (uartNumber == UART_NUM_1 \
? UART1_TXD_PAD_OUT_IDX \
: (uartNumber == UART_NUM_2 ? UART2_TXD_PAD_OUT_IDX : (uartNumber == UART_NUM_3 ? UART3_TXD_PAD_OUT_IDX : UART4_TXD_PAD_OUT_IDX))))
#define UART_RX_SIGNAL(uartNumber) \
(uartNumber == UART_NUM_0 \
? UART0_RXD_PAD_IN_IDX \
: (uartNumber == UART_NUM_1 \
? UART1_RXD_PAD_IN_IDX \
: (uartNumber == UART_NUM_2 ? UART2_RXD_PAD_IN_IDX : (uartNumber == UART_NUM_3 ? UART3_RXD_PAD_IN_IDX : UART4_RXD_PAD_IN_IDX))))
#else
#if SOC_UART_HP_NUM > 2
#define UART_TX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0TXD_OUT_IDX : (uartNumber == UART_NUM_1 ? U1TXD_OUT_IDX : U2TXD_OUT_IDX))
#define UART_RX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0RXD_IN_IDX : (uartNumber == UART_NUM_1 ? U1RXD_IN_IDX : U2RXD_IN_IDX))
#else
#define UART_TX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0TXD_OUT_IDX : U1TXD_OUT_IDX)
#define UART_RX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0RXD_IN_IDX : U1RXD_IN_IDX)
#endif
#endif // ifdef CONFIG_IDF_TARGET_ESP32P4
/* /*
This function internally binds defined UARTs TX signal with defined RX pin of any UART (same or different). This function internally binds defined UARTs TX signal with defined RX pin of any UART (same or different).
This creates a loop that lets us receive anything we send on the UART without external wires. This creates a loop that lets us receive anything we send on the UART without external wires.
*/ */
void uart_internal_loopback(uint8_t uartNum, int8_t rxPin) { void uart_internal_loopback(uint8_t uartNum, int8_t rxPin) {
if (uartNum > SOC_UART_HP_NUM - 1 || !GPIO_IS_VALID_GPIO(rxPin)) { // LP UART is not supported for loopback
if (uartNum >= SOC_UART_HP_NUM || !GPIO_IS_VALID_GPIO(rxPin)) {
log_e("UART%d is not supported for loopback or RX pin %d is invalid.", uartNum, rxPin);
return; return;
} }
esp_rom_gpio_connect_out_signal(rxPin, UART_TX_SIGNAL(uartNum), false, false); #if 0 // leave this code here for future reference and need
// forces rxPin to use GPIO Matrix and setup the pin to receive UART TX Signal - IDF 5.4.1 Change with uart_release_pin()
gpio_func_sel((gpio_num_t)rxPin, PIN_FUNC_GPIO);
gpio_pullup_en((gpio_num_t)rxPin);
gpio_input_enable((gpio_num_t)rxPin);
esp_rom_gpio_connect_in_signal(rxPin, uart_periph_signal[uartNum].pins[SOC_UART_RX_PIN_IDX].signal, false);
#endif
esp_rom_gpio_connect_out_signal(rxPin, uart_periph_signal[uartNum].pins[SOC_UART_TX_PIN_IDX].signal, false, false);
} }
/* /*
@ -1198,4 +1587,24 @@ int uart_send_msg_with_break(uint8_t uartNum, uint8_t *msg, size_t msgSize) {
return uart_write_bytes_with_break(uartNum, (const void *)msg, msgSize, 12); return uart_write_bytes_with_break(uartNum, (const void *)msg, msgSize, 12);
} }
// returns the maximum valid uart RX Timeout based on the UART Source Clock and Baudrate
uint16_t uart_get_max_rx_timeout(uint8_t uartNum) {
if (uartNum >= SOC_UART_NUM) {
log_e("UART%d is invalid. This device has %d UARTs, from 0 to %d.", uartNum, SOC_UART_NUM, SOC_UART_NUM - 1);
return (uint16_t)-1;
}
uint16_t tout_max_thresh = uart_ll_max_tout_thrd(UART_LL_GET_HW(uartNum));
uint8_t symbol_len = 1; // number of bits per symbol including start
uart_parity_t parity_mode;
uart_stop_bits_t stop_bit;
uart_word_length_t data_bit;
uart_ll_get_data_bit_num(UART_LL_GET_HW(uartNum), &data_bit);
uart_ll_get_stop_bits(UART_LL_GET_HW(uartNum), &stop_bit);
uart_ll_get_parity(UART_LL_GET_HW(uartNum), &parity_mode);
symbol_len += (data_bit < UART_DATA_BITS_MAX) ? (uint8_t)data_bit + 5 : 8;
symbol_len += (stop_bit > UART_STOP_BITS_1) ? 2 : 1;
symbol_len += (parity_mode > UART_PARITY_DISABLE) ? 1 : 0;
return (uint16_t)(tout_max_thresh / symbol_len);
}
#endif /* SOC_UART_SUPPORTED */ #endif /* SOC_UART_SUPPORTED */

View file

@ -1,4 +1,4 @@
// Copyright 2015-2023 Espressif Systems (Shanghai) PTE LTD // Copyright 2015-2025 Espressif Systems (Shanghai) PTE LTD
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#if SOC_UART_SUPPORTED #if SOC_UART_SUPPORTED
#include "soc/uart_pins.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -57,7 +58,7 @@ void uartWriteBuf(uart_t *uart, const uint8_t *data, size_t len);
void uartFlush(uart_t *uart); void uartFlush(uart_t *uart);
void uartFlushTxOnly(uart_t *uart, bool txOnly); void uartFlushTxOnly(uart_t *uart, bool txOnly);
void uartSetBaudRate(uart_t *uart, uint32_t baud_rate); bool uartSetBaudRate(uart_t *uart, uint32_t baud_rate);
uint32_t uartGetBaudRate(uart_t *uart); uint32_t uartGetBaudRate(uart_t *uart);
void uartSetRxInvert(uart_t *uart, bool invert); void uartSetRxInvert(uart_t *uart, bool invert);
@ -96,6 +97,19 @@ bool uartSetHwFlowCtrlMode(uart_t *uart, uart_hw_flowcontrol_t mode, uint8_t thr
// UART_MODE_RS485_APP_CTRL = 0x04 mode: application control RS485 UART mode (used for test purposes) // UART_MODE_RS485_APP_CTRL = 0x04 mode: application control RS485 UART mode (used for test purposes)
bool uartSetMode(uart_t *uart, uart_mode_t mode); bool uartSetMode(uart_t *uart, uart_mode_t mode);
// Used to set the UART clock source mode. It must be set before calling uartBegin(), otherwise it won't have any effect.
// Not all clock source are available to every SoC. The compatible option are listed here:
// UART_SCLK_DEFAULT :: any SoC - it will set whatever IDF defines as the default UART Clock Source
// UART_SCLK_APB :: ESP32, ESP32-S2, ESP32-C3 and ESP32-S3
// UART_SCLK_PLL_F80M :: ESP32-C5, ESP32-C6, ESP32-C61 and ESP32-P4
// UART_SCLK_PLL_F40M :: ESP32-C2
// UART_SCLK_PLL_F48M :: ESP32-H2
// UART_SCLK_XTAL :: ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-S3 and ESP32-P4
// UART_SCLK_RTC :: ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-S3 and ESP32-P4
// UART_SCLK_REF_TICK :: ESP32 and ESP32-S2
// Note: ESP32-C6, C61, ESP32-P4 and ESP32-C5 have LP UART that will use only LP_UART_SCLK_LP_FAST (RTC_FAST) or LP_UART_SCLK_XTAL_D2 (XTAL/2) as Clock Source
bool uartSetClockSource(uint8_t uartNum, uart_sclk_t clkSrc);
void uartStartDetectBaudrate(uart_t *uart); void uartStartDetectBaudrate(uart_t *uart);
unsigned long uartDetectBaudrate(uart_t *uart); unsigned long uartDetectBaudrate(uart_t *uart);
@ -115,6 +129,10 @@ void uart_send_break(uint8_t uartNum);
// Sends a buffer and at the end of the stream, it generates BREAK in the line // Sends a buffer and at the end of the stream, it generates BREAK in the line
int uart_send_msg_with_break(uint8_t uartNum, uint8_t *msg, size_t msgSize); int uart_send_msg_with_break(uint8_t uartNum, uint8_t *msg, size_t msgSize);
// UART RX Timeout (in UART Symbols) depends on the UART Clock Source and the SoC that is used
// This is a helper function that calculates what is the maximum RX Timeout that a running UART IDF driver allows.
uint16_t uart_get_max_rx_timeout(uint8_t uartNum);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

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

View file

@ -31,7 +31,8 @@ void printRunningTasks(Print &printer) {
#endif #endif
configRUN_TIME_COUNTER_TYPE ulTotalRunTime = 0; configRUN_TIME_COUNTER_TYPE ulTotalRunTime = 0;
TaskStatus_t *pxTaskStatusArray = NULL; TaskStatus_t *pxTaskStatusArray = NULL;
volatile UBaseType_t uxArraySize = 0, x = 0; volatile UBaseType_t uxArraySize = 0;
uint32_t x = 0;
const char *taskStates[] = {"Running", "Ready", "Blocked", "Suspended", "Deleted", "Invalid"}; const char *taskStates[] = {"Running", "Ready", "Blocked", "Suspended", "Deleted", "Invalid"};
// Take a snapshot of the number of tasks in case it changes while this function is executing. // Take a snapshot of the number of tasks in case it changes while this function is executing.

View file

@ -2,6 +2,12 @@
from esp_docs.conf_docs import * # noqa: F403,F401 from esp_docs.conf_docs import * # noqa: F403,F401
# Used for substituting variables in the documentation
rst_prolog = """
.. |version| replace:: 3.3.0
.. |idf_version| replace:: 5.5
"""
languages = ["en"] languages = ["en"]
# idf_targets = [ # idf_targets = [
@ -27,6 +33,7 @@ html_static_path = ["../_static"]
extensions += [ # noqa: F405 extensions += [ # noqa: F405
"sphinx_copybutton", "sphinx_copybutton",
"sphinx_tabs.tabs", "sphinx_tabs.tabs",
"sphinx_substitution_extensions", # For allowing substitutions inside code blocks
"esp_docs.esp_extensions.dummy_build_system", "esp_docs.esp_extensions.dummy_build_system",
] ]

View file

@ -347,20 +347,147 @@ This function will return ``true`` if the peripheral was initialized correctly.
onReceive onReceive
^^^^^^^^^ ^^^^^^^^^
The ``onReceive`` function is used to define the callback for the data received from the master. The ``onReceive`` function is used to define the callback for data received from the master device.
.. code-block:: arduino .. code-block:: arduino
void onReceive( void (*)(int) ); void onReceive(const std::function<void(int)>& callback);
**Function Signature:**
The callback function must have the signature ``void(int numBytes)`` where ``numBytes`` indicates how many bytes were received from the master.
**Usage Examples:**
.. code-block:: arduino
// Method 1: Regular function
void handleReceive(int numBytes) {
Serial.printf("Received %d bytes: ", numBytes);
while (Wire.available()) {
char c = Wire.read();
Serial.print(c);
}
Serial.println();
}
Wire.onReceive(handleReceive);
// Method 2: Lambda function
Wire.onReceive([](int numBytes) {
Serial.printf("Master sent %d bytes\n", numBytes);
while (Wire.available()) {
uint8_t data = Wire.read();
// Process received data
Serial.printf("Data: 0x%02X\n", data);
}
});
// Method 3: Lambda with capture (for accessing variables)
int deviceId = 42;
Wire.onReceive([deviceId](int numBytes) {
Serial.printf("Device %d received %d bytes\n", deviceId, numBytes);
// Process data...
});
// Method 4: Using std::function variable
std::function<void(int)> receiveHandler = [](int bytes) {
Serial.printf("Handling %d received bytes\n", bytes);
};
Wire.onReceive(receiveHandler);
// Method 5: Class member function (using lambda wrapper)
class I2CDevice {
private:
int deviceAddress;
public:
I2CDevice(int addr) : deviceAddress(addr) {}
void handleReceive(int numBytes) {
Serial.printf("Device 0x%02X received %d bytes\n", deviceAddress, numBytes);
}
void setup() {
Wire.onReceive([this](int bytes) {
this->handleReceive(bytes);
});
}
};
.. note::
The ``onReceive`` callback is triggered when the I2C master sends data to this slave device.
Use ``Wire.available()`` and ``Wire.read()`` inside the callback to retrieve the received data.
onRequest onRequest
^^^^^^^^^ ^^^^^^^^^
The ``onRequest`` function is used to define the callback for the data to be send to the master. The ``onRequest`` function is used to define the callback for responding to master read requests.
.. code-block:: arduino .. code-block:: arduino
void onRequest( void (*)(void) ); void onRequest(const std::function<void()>& callback);
**Function Signature:**
The callback function must have the signature ``void()`` with no parameters. This callback is triggered when the master requests data from this slave device.
**Usage Examples:**
.. code-block:: arduino
// Method 1: Regular function
void handleRequest() {
static int counter = 0;
Wire.printf("Response #%d", counter++);
}
Wire.onRequest(handleRequest);
// Method 2: Lambda function
Wire.onRequest([]() {
// Send sensor data to master
int sensorValue = analogRead(A0);
Wire.write(sensorValue >> 8); // High byte
Wire.write(sensorValue & 0xFF); // Low byte
});
// Method 3: Lambda with capture (for accessing variables)
int deviceStatus = 1;
String deviceName = "Sensor1";
Wire.onRequest([&deviceStatus, &deviceName]() {
Wire.write(deviceStatus);
Wire.write(deviceName.c_str(), deviceName.length());
});
// Method 4: Using std::function variable
std::function<void()> requestHandler = []() {
Wire.write("Hello Master!");
};
Wire.onRequest(requestHandler);
// Method 5: Class member function (using lambda wrapper)
class TemperatureSensor {
private:
float temperature;
public:
void updateTemperature() {
temperature = 25.5; // Read from actual sensor
}
void sendTemperature() {
// Convert float to bytes and send
uint8_t* tempBytes = (uint8_t*)&temperature;
Wire.write(tempBytes, sizeof(float));
}
void setup() {
Wire.onRequest([this]() {
this->sendTemperature();
});
}
};
.. note::
The ``onRequest`` callback is triggered when the I2C master requests data from this slave device.
Use ``Wire.write()`` inside the callback to send response data back to the master.
slaveWrite slaveWrite
^^^^^^^^^^ ^^^^^^^^^^

View file

@ -18,16 +18,18 @@ The ESP32 is divided by family:
* ESP32 * ESP32
* Wi-Fi, BT and BLE 4 * Wi-Fi, BT and BLE 4
* ESP32-S2
* Wi-Fi only
* ESP32-S3
* Wi-Fi and BLE 5
* ESP32-C3 * ESP32-C3
* Wi-Fi and BLE 5 * Wi-Fi and BLE 5
* ESP32-C6 * ESP32-C6
* Wi-Fi, BLE 5 and IEEE 802.15.4 * Wi-Fi, BLE 5 and IEEE 802.15.4
* ESP32-H2 * ESP32-H2
* BLE 5 and IEEE 802.15.4 * BLE 5 and IEEE 802.15.4
* ESP32-P4
* 400 MHz Dual Core RISC-V CPU, 40 MHz ULP Co-processor, single-precision FPU and AI extensions.
* ESP32-S2
* Wi-Fi only
* ESP32-S3
* Wi-Fi and BLE 5
For each family, we have SoC variants with some differentiation. The differences are more about the embedded flash and its size and the number of the cores (dual or single). For each family, we have SoC variants with some differentiation. The differences are more about the embedded flash and its size and the number of the cores (dual or single).

View file

@ -2,16 +2,20 @@ Datasheet
--------- ---------
* `ESP32`_ (Datasheet) * `ESP32`_ (Datasheet)
* `ESP32-S2`_ (Datasheet) * `ESP32-C2`_ (Datasheet)
* `ESP32-C3`_ (Datasheet) * `ESP32-C3`_ (Datasheet)
* `ESP32-S3`_ (Datasheet)
* `ESP32-C6`_ (Datasheet) * `ESP32-C6`_ (Datasheet)
* `ESP32-H2`_ (Datasheet) * `ESP32-H2`_ (Datasheet)
* `ESP32-P4`_ (Datasheet)
* `ESP32-S2`_ (Datasheet)
* `ESP32-S3`_ (Datasheet)
.. _Espressif Product Selector: https://products.espressif.com/ .. _Espressif Product Selector: https://products.espressif.com/
.. _ESP32: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf .. _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-C2: https://www.espressif.com/sites/default/files/documentation/esp8684_datasheet_en.pdf
.. _ESP32-C3: https://www.espressif.com/sites/default/files/documentation/esp32-c3_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
.. _ESP32-C6: https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf .. _ESP32-C6: https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf
.. _ESP32-H2: https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf .. _ESP32-H2: https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf
.. _ESP32-P4: https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf
.. _ESP32-S2: https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf
.. _ESP32-S3: https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf

View file

@ -15,6 +15,9 @@ Before Contributing
Before sending us a Pull Request, please consider this: Before sending us a Pull Request, please consider this:
* All contributions must be written in English to ensure effective communication and support.
Pull Requests written in other languages will be closed, with a request to rewrite them in English.
* Is the contribution entirely your own work, or is it already licensed under an LGPL 2.1 compatible Open Source License? * Is the contribution entirely your own work, or is it already licensed under an LGPL 2.1 compatible Open Source License?
If not, cannot accept it. If not, cannot accept it.
@ -219,7 +222,7 @@ Documentation
------------- -------------
If you are contributing to the documentation, please follow the instructions described in the If you are contributing to the documentation, please follow the instructions described in the
`documentation guidelines <guides/docs_contributing>`_ to properly format and test your changes. `documentation guidelines <guides/docs_contributing.html>`_ to properly format and test your changes.
Testing and CI Testing and CI
-------------- --------------
@ -318,7 +321,7 @@ ESP32-C3 target, you would run:
./.github/scripts/tests_build.sh -s uart -t esp32c3 ./.github/scripts/tests_build.sh -s uart -t esp32c3
You should see the output of the build process and the test binary should be generated in the ``~/.arduino/tests/<test_name>/build.tmp`` folder. You should see the output of the build process and the test binary should be generated in the ``~/.arduino/tests/<target_chip>/<test_name>/build.tmp`` folder.
Now that the test is built, you can run it in the target board. Connect the target board to your computer and run: Now that the test is built, you can run it in the target board. Connect the target board to your computer and run:
@ -339,7 +342,7 @@ The test will run on the target board and you should see the output of the test
lucassvaz@Lucas--MacBook-Pro esp32 % ./.github/scripts/tests_run.sh -s uart -t esp32c3 lucassvaz@Lucas--MacBook-Pro esp32 % ./.github/scripts/tests_run.sh -s uart -t esp32c3
Sketch uart test type: validation Sketch uart test type: validation
Running test: uart -- Config: Default Running test: uart -- Config: Default
pytest tests --build-dir /Users/lucassvaz/.arduino/tests/uart/build.tmp -k test_uart --junit-xml=/Users/lucassvaz/Espressif/Arduino/hardware/espressif/esp32/tests/validation/uart/esp32c3/uart.xml --embedded-services esp,arduino pytest tests --build-dir /Users/lucassvaz/.arduino/tests/esp32c3/uart/build.tmp -k test_uart --junit-xml=/Users/lucassvaz/Espressif/Arduino/hardware/espressif/esp32/tests/validation/uart/esp32c3/uart.xml --embedded-services esp,arduino
=============================================================================================== test session starts ================================================================================================ =============================================================================================== test session starts ================================================================================================
platform darwin -- Python 3.12.3, pytest-8.2.2, pluggy-1.5.0 platform darwin -- Python 3.12.3, pytest-8.2.2, pluggy-1.5.0
rootdir: /Users/lucassvaz/Espressif/Arduino/hardware/espressif/esp32/tests rootdir: /Users/lucassvaz/Espressif/Arduino/hardware/espressif/esp32/tests
@ -432,7 +435,7 @@ Documentation Checks
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
The CI also checks the documentation for any compilation errors. This is important to ensure that the documentation layout is not broken. The CI also checks the documentation for any compilation errors. This is important to ensure that the documentation layout is not broken.
To build the documentation locally, please refer to the `documentation guidelines <guides/docs_contributing>`_. To build the documentation locally, please refer to the `documentation guidelines <guides/docs_contributing.html>`_.
Code Style Checks Code Style Checks
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^

View file

@ -14,9 +14,9 @@ For a simplified method, see `Installing using Boards Manager <https://docs.espr
If you plan to use these modified settings multiple times, for different projects and targets, you can recompile the Arduino core with the new settings using the Arduino Static Library Builder. If you plan to use these modified settings multiple times, for different projects and targets, you can recompile the Arduino core with the new settings using the Arduino Static Library Builder.
For more information, see the `Lib Builder documentation <lib_builder.html>`_. For more information, see the `Lib Builder documentation <lib_builder.html>`_.
.. note:: Latest Arduino Core ESP32 version (3.0.X) is now compatible with `ESP-IDF v5.1 <https://github.com/espressif/esp-idf/tree/release/v5.1>`_. Please consider this compatibility when using Arduino as a component in ESP-IDF. .. note:: Latest Arduino Core ESP32 version (|version|) is now compatible with ESP-IDF v\ |idf_version|\ . Please consider this compatibility when using Arduino as a component in ESP-IDF.
For easiest use of Arduino framework as a ESP-IDF component, you can use the `IDF Component Manager <https://docs.espressif.com/projects/esp-idf/en/v5.1.4/esp32/api-guides/tools/idf-component-manager.html>`_ to add the Arduino component to your project. For easiest use of Arduino framework as a ESP-IDF component, you can use the `IDF Component Manager <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html>`_ to add the Arduino component to your project.
This will automatically clone the repository and its submodules. You can find the Arduino component in the `ESP Registry <https://components.espressif.com/components/espressif/arduino-esp32>`_ together with dependencies list and examples. This will automatically clone the repository and its submodules. You can find the Arduino component in the `ESP Registry <https://components.espressif.com/components/espressif/arduino-esp32>`_ together with dependencies list and examples.
Installation Installation
@ -32,14 +32,16 @@ Installing using IDF Component Manager
To add the Arduino component to your project using the IDF Component Manager, run the following command in your project directory: To add the Arduino component to your project using the IDF Component Manager, run the following command in your project directory:
.. code-block:: bash .. code-block:: bash
:substitutions:
idf.py add-dependency "espressif/arduino-esp32^3.0.2" idf.py add-dependency "espressif/arduino-esp32^|version|"
Or you can start a new project from a template with the Arduino component: Or you can start a new project from a template with the Arduino component:
.. code-block:: bash .. code-block:: bash
:substitutions:
idf.py create-project-from-example "espressif/arduino-esp32^3.0.2:hello_world" idf.py create-project-from-example "espressif/arduino-esp32^|version|:hello_world"
Manual installation of Arduino framework Manual installation of Arduino framework
**************************************** ****************************************

View file

@ -38,17 +38,18 @@ Here are the ESP32 series supported by the Arduino-ESP32 project:
SoC Stable Development Datasheet SoC Stable Development Datasheet
========== ====== =========== ================================= ========== ====== =========== =================================
ESP32 Yes Yes `ESP32`_ ESP32 Yes Yes `ESP32`_
ESP32-S2 Yes Yes `ESP32-S2`_
ESP32-C3 Yes Yes `ESP32-C3`_ ESP32-C3 Yes Yes `ESP32-C3`_
ESP32-S3 Yes Yes `ESP32-S3`_
ESP32-C6 Yes Yes `ESP32-C6`_ ESP32-C6 Yes Yes `ESP32-C6`_
ESP32-H2 Yes Yes `ESP32-H2`_ ESP32-H2 Yes Yes `ESP32-H2`_
ESP32-P4 Yes Yes `ESP32-P4`_
ESP32-S2 Yes Yes `ESP32-S2`_
ESP32-S3 Yes Yes `ESP32-S3`_
========== ====== =========== ================================= ========== ====== =========== =================================
.. note:: .. note::
ESP32-C2 is also supported by Arduino-ESP32 but requires rebuilding the static libraries. ESP32-C2 is also supported by Arduino-ESP32 but requires using Arduino as an ESP-IDF component or rebuilding the static libraries.
This is not trivial and requires a good understanding of the ESP-IDF build system. For more information, see the `Arduino as an ESP-IDF component documentation <esp-idf_component.html>`_ or the
For more information, see the `Lib Builder documentation <lib_builder.html>`_. `Lib Builder documentation <lib_builder.html>`_, respectively.
See `Boards <boards/boards.html>`_ for more details about ESP32 development boards. See `Boards <boards/boards.html>`_ for more details about ESP32 development boards.

View file

@ -9,9 +9,9 @@ Welcome to the compatibility guide for library developers aiming to support mult
Code Adaptations Code Adaptations
---------------- ----------------
To ensure compatibility with both versions of the ESP32 Arduino core, developers should utilize conditional compilation directives in their code. Below is an example of how to conditionally include code based on the ESP32 Arduino core version:: To ensure compatibility with both versions of the ESP32 Arduino core, developers should utilize conditional compilation directives in their code. Below is an example of how to conditionally include code based on the ESP32 Arduino core version:
.. code-block:: cpp .. code-block:: cpp
#ifdef ESP_ARDUINO_VERSION_MAJOR #ifdef ESP_ARDUINO_VERSION_MAJOR
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0) #if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
@ -26,9 +26,9 @@ To ensure compatibility with both versions of the ESP32 Arduino core, developers
Version Print Version Print
------------- -------------
To easily print the ESP32 Arduino core version at runtime, developers can use the `ESP_ARDUINO_VERSION_STR` macro. Below is an example of how to print the ESP32 Arduino core version:: To easily print the ESP32 Arduino core version at runtime, developers can use the `ESP_ARDUINO_VERSION_STR` macro. Below is an example of how to print the ESP32 Arduino core version:
.. code-block:: cpp .. code-block:: cpp
Serial.printf(" ESP32 Arduino core version: %s\n", ESP_ARDUINO_VERSION_STR); Serial.printf(" ESP32 Arduino core version: %s\n", ESP_ARDUINO_VERSION_STR);

View file

@ -49,11 +49,11 @@ Before starting your collaboration, you need to get the documentation source cod
Requirements Requirements
************ ************
To properly work with the documentation, you need to install some packages in your system. To build the documentation properly, you need to install some packages in your system. Note that depending on
your system, you may need to use a virtual environment to install the packages.
.. code-block:: .. code-block::
pip install -U Sphinx
pip install -r requirements.txt pip install -r requirements.txt
The requirements file is under the ``docs`` folder. The requirements file is under the ``docs`` folder.
@ -62,17 +62,14 @@ Using Visual Studio Code
************************ ************************
If you are using the Visual Studio Code, you can install some extensions to help you while writing documentation. If you are using the Visual Studio Code, you can install some extensions to help you while writing documentation.
For reStructuredText, you can install the `reStructuredText Pack <https://marketplace.visualstudio.com/items?itemName=lextudio.restructuredtext-pack>`_ extension.
`reStructuredText Pack <https://marketplace.visualstudio.com/items?itemName=lextudio.restructuredtext-pack>`_ We also recommend you to install some grammar check extension to help you to review English grammar.
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 Building
******** ********
To build the documentation and generate the HTML files, you can use the following command inside the ``docs`` folder. After a successful build, you can check the files inside the `_build/en/generic/html` folder. To build the documentation and generate the HTML files, you can use the following command inside the ``docs`` folder. After a successful build, you can check the files inside the ``_build/en/generic/html`` folder.
.. code-block:: .. code-block::

View file

@ -3,6 +3,7 @@ Welcome to ESP32 Arduino Core's documentation
############################################# #############################################
Here you will find all the relevant information about the project. Here you will find all the relevant information about the project.
This documentation is valid for the Arduino Core for ESP32 version |version| based on ESP-IDF |idf_version|.
.. note:: .. note::
This is a work in progress documentation and we will appreciate your help! We are looking for contributors! This is a work in progress documentation and we will appreciate your help! We are looking for contributors!

View file

@ -10,6 +10,11 @@ Before Installing
We recommend you install the support using your favorite IDE, 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. To install Arduino-ESP32 support, you can use one of the following options.
.. note::
Users in China might have troubles with connection and download speeds using GitHub. Please use our Jihulab mirror as the repository source:
``https://jihulab.com/esp-mirror/espressif/arduino-esp32.git``
Installing using Arduino IDE Installing using Arduino IDE
---------------------------- ----------------------------
@ -32,6 +37,16 @@ This is the way to install Arduino-ESP32 directly from the Arduino IDE.
https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json
Users in China might have troubles with connection and download speeds using the links above. Please use our Jihulab mirror:
- Stable release link::
https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_index_cn.json
- Development release link::
https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_dev_index_cn.json
.. note:: .. note::
Starting with the Arduino IDE version 1.6.4, Arduino allows installation of third-party platform Starting with the Arduino IDE version 1.6.4, Arduino allows installation of third-party platform
packages using Boards Manager. We have packages available for Windows, macOS, and Linux. packages using Boards Manager. We have packages available for Windows, macOS, and Linux.
@ -55,6 +70,8 @@ To start the installation process using the Boards Manager, follow these steps:
:figclass: align-center :figclass: align-center
- Open Boards Manager from Tools > Board menu and install *esp32* platform (and do not forget to select your ESP32 board from Tools > Board menu after installation). - Open Boards Manager from Tools > Board menu and install *esp32* platform (and do not forget to select your ESP32 board from Tools > Board menu after installation).
Users in China must select the package version with the "-cn" suffix and perform updates manually.
Automatic updates are not supported in this region, as they target the default package without the "-cn" suffix, resulting in download failures.
.. figure:: ../_static/install_guide_boards_manager_esp32.png .. figure:: ../_static/install_guide_boards_manager_esp32.png
:align: center :align: center

View file

@ -151,13 +151,13 @@ Set the build target(chip). ex. 'esp32s3'
This build command will build for the ESP32-S3 target. You can specify other targets. This build command will build for the ESP32-S3 target. You can specify other targets.
* esp32 * esp32
* esp32s2
* esp32s3
* esp32c2 * esp32c2
* esp32c3 * esp32c3
* esp32c6 * esp32c6
* esp32h2 * esp32h2
* esp32p4 * esp32p4
* esp32s2
* esp32s3
Set Build Type Set Build Type
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
@ -293,8 +293,9 @@ You have two options to run the Docker image to build the libraries. Manually or
To run the Docker image manually, use the following command from the root of the ``arduino-esp32`` repository: To run the Docker image manually, use the following command from the root of the ``arduino-esp32`` repository:
.. code-block:: bash .. code-block:: bash
:substitutions:
docker run --rm -it -v $PWD:/arduino-esp32 -e TERM=xterm-256color espressif/esp32-arduino-lib-builder:release-v5.1 docker run --rm -it -v $PWD:/arduino-esp32 -e TERM=xterm-256color espressif/esp32-arduino-lib-builder:release-v|idf_version|
This will start the Lib Builder UI for compiling the libraries. The above command explained: This will start the Lib Builder UI for compiling the libraries. The above command explained:
@ -304,7 +305,7 @@ This will start the Lib Builder UI for compiling the libraries. The above comman
- ``-t`` Allocate a pseudo-TTY; - ``-t`` Allocate a pseudo-TTY;
- ``-e TERM=xterm-256color``: Optional. Sets the terminal type to ``xterm-256color`` to display colors correctly; - ``-e TERM=xterm-256color``: Optional. Sets the terminal type to ``xterm-256color`` to display colors correctly;
- ``-v $PWD:/arduino-esp32``: Optional. Mounts the current folder at ``/arduino-esp32`` inside the container. If not provided, the container will not copy the compiled libraries to the host machine; - ``-v $PWD:/arduino-esp32``: Optional. Mounts the current folder at ``/arduino-esp32`` inside the container. If not provided, the container will not copy the compiled libraries to the host machine;
- ``espressif/esp32-arduino-lib-builder:release-v5.1``: uses Docker image ``espressif/esp32-arduino-lib-builder`` with tag ``release-v5.1``. - :substitution-code:`espressif/esp32-arduino-lib-builder:release-v|idf_version|`: uses Docker image ``espressif/esp32-arduino-lib-builder`` with tag :substitution-code:`release-v|idf_version|`.
The ``latest`` tag is implicitly added by Docker when no tag is specified. It is recommended to use a specific version tag to ensure reproducibility of the build process. The ``latest`` tag is implicitly added by Docker when no tag is specified. It is recommended to use a specific version tag to ensure reproducibility of the build process.
.. warning:: .. warning::
@ -324,24 +325,27 @@ By default the docker container will run the user interface script. If you want
For example, to run a terminal inside the container, you can run: For example, to run a terminal inside the container, you can run:
.. code-block:: bash .. code-block:: bash
:substitutions:
docker run -it espressif/esp32-arduino-lib-builder:release-v5.1 /bin/bash docker run -it espressif/esp32-arduino-lib-builder:release-v|idf_version| /bin/bash
Running the Docker image using the provided run script will depend on the host OS. Running the Docker image using the provided run script will depend on the host OS.
Use the following command from the root of the ``arduino-esp32`` repository to execute the image in a Linux or macOS environment for Use the following command from the root of the ``arduino-esp32`` repository to execute the image in a Linux or macOS environment for
the ``release-v5.1`` tag: the :substitution-code:`release-v|idf_version|` tag:
.. code-block:: bash .. code-block:: bash
:substitutions:
curl -LJO https://raw.githubusercontent.com/espressif/esp32-arduino-lib-builder/refs/heads/release/v5.1/tools/docker/run.sh curl -LJO https://raw.githubusercontent.com/espressif/esp32-arduino-lib-builder/refs/heads/release/v|idf_version|/tools/docker/run.sh
chmod +x run.sh chmod +x run.sh
./run.sh $PWD ./run.sh $PWD
For Windows, use the following command in PowerShell from the root of the ``arduino-esp32`` repository: For Windows, use the following command in PowerShell from the root of the ``arduino-esp32`` repository:
.. code-block:: powershell .. code-block:: powershell
:substitutions:
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/espressif/esp32-arduino-lib-builder/refs/heads/release/v5.1/tools/docker/run.ps1" -OutFile "run.ps1" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/espressif/esp32-arduino-lib-builder/refs/heads/release/v|idf_version|/tools/docker/run.ps1" -OutFile "run.ps1"
.\run.ps1 $pwd .\run.ps1 $pwd
As the script is unsigned, you may need to change the execution policy of the current session before running the script. As the script is unsigned, you may need to change the execution policy of the current session before running the script.

View file

@ -9,60 +9,68 @@ Supported Peripherals
Currently, the Arduino ESP32 supports the following peripherals with Arduino APIs. Currently, the Arduino ESP32 supports the following peripherals with Arduino APIs.
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Peripheral | ESP32 | S2 | C3 | S3 | C6 | H2 | Notes | | Peripheral | ESP32 | C3 | C6 | H2 | P4 | S2 | S3 | Notes |
+===============+=======+=======+=======+=======+=======+=======+=======+ +===============+=======+=======+=======+=======+=======+=======+=======+=======+
| ADC | Yes | Yes | Yes | Yes | Yes | Yes | | | ADC | Yes | Yes | Yes | Yes | Yes | Yes | Yes | (1) |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| BT Classic | Yes | N/A | N/A | N/A | N/A | N/A | | | BT Classic | Yes | N/A | N/A | N/A | N/A | N/A | N/A | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| BLE | Yes | N/A | Yes | Yes | Yes | Yes | | | BLE | Yes | Yes | Yes | Yes | No | N/A | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| DAC | Yes | Yes | N/A | N/A | N/A | N/A | | | DAC | Yes | N/A | N/A | N/A | Yes | Yes | N/A | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Ethernet | Yes | N/A | N/A | N/A | N/A | N/A | (*) | | Ethernet | Yes | N/A | N/A | N/A | Yes | N/A | N/A | (2) |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| GPIO | Yes | Yes | Yes | Yes | Yes | Yes | | | GPIO | Yes | Yes | Yes | Yes | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Hall Sensor | N/A | N/A | N/A | N/A | N/A | N/A | | | Hall Sensor | N/A | N/A | N/A | N/A | N/A | N/A | N/A | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| I2C | Yes | Yes | Yes | Yes | Yes | Yes | | | I2C | Yes | Yes | Yes | Yes | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| I2S | Yes | Yes | Yes | Yes | Yes | Yes | | | I2S | Yes | Yes | Yes | Yes | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| LEDC | Yes | Yes | Yes | Yes | Yes | Yes | | | LEDC | Yes | Yes | Yes | Yes | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Motor PWM | No | N/A | N/A | N/A | N/A | N/A | | | MIPI | N/A | N/A | N/A | N/A | No | N/A | N/A | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pulse Counter | No | No | No | No | No | No | | | Motor PWM | No | N/A | N/A | N/A | N/A | N/A | N/A | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| RMT | Yes | Yes | Yes | Yes | Yes | Yes | | | MSPI | N/A | N/A | N/A | N/A | No | N/A | N/A | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| SDIO | No | No | No | No | No | No | | | Pulse Counter | No | No | No | No | No | No | No | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| SDMMC | Yes | N/A | N/A | Yes | N/A | N/A | | | RMT | Yes | Yes | Yes | Yes | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Timer | Yes | Yes | Yes | Yes | Yes | Yes | | | SDIO | No | No | No | No | No | No | No | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Temp. Sensor | N/A | Yes | Yes | Yes | Yes | Yes | | | SDMMC | Yes | N/A | N/A | N/A | N/A | N/A | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Touch | Yes | Yes | N/A | Yes | N/A | N/A | | | Timer | Yes | Yes | Yes | Yes | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| TWAI | No | No | No | No | No | No | | | Temp. Sensor | N/A | Yes | Yes | Yes | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| UART | Yes | Yes | Yes | Yes | Yes | Yes | | | Touch | Yes | N/A | N/A | N/A | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| USB | N/A | Yes | Yes | Yes | Yes | Yes | (**) | | TWAI | No | No | No | No | No | No | No | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Wi-Fi | Yes | Yes | Yes | Yes | Yes | N/A | | | UART | Yes | Yes | Yes | Yes | Yes | Yes | Yes | |
+---------------+-------+-------+-------+-------+-------+-------+-------+ +---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| USB | N/A | Yes | Yes | Yes | Yes | Yes | Yes | (3) |
+---------------+-------+-------+-------+-------+-------+-------+-------+-------+
| Wi-Fi | Yes | Yes | Yes | N/A | Yes | Yes | Yes | (4) |
+---------------+-------+-------+-------+-------+-------+-------+-------+-------+
Notes Notes
^^^^^ ^^^^^
(*) SPI Ethernet is supported by all ESP32 families and RMII only for ESP32. (1) ESP32-P4 calibration schemes not supported yet in IDF and ADC Continuous also lacks IDF support.
(**) ESP32-C3, C6, H2 only support USB CDC/JTAG (2) SPI Ethernet is supported by all ESP32 families and RMII only for ESP32 and ESP32-P4.
(3) ESP32-C3, C6, H2 only support USB CDC/JTAG
(4) ESP32-P4 only supports Wi-Fi through another SoC by using ``esp_hosted``.
.. 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. .. 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.
@ -83,3 +91,15 @@ The Arduino ESP32 offers some unique APIs, described in this section:
:glob: :glob:
api/* api/*
Zigbee APIs
-----------
.. toctree::
:maxdepth: 1
:glob:
zigbee/zigbee
zigbee/zigbee_core
zigbee/zigbee_ep
zigbee/ep_*

View file

@ -14,6 +14,23 @@ Installing
Here are the common issues during the installation. Here are the common issues during the installation.
Slow or unstable downloads
**************************
Users in China might have troubles with connection and download speeds using GitHub. Please use our Jihulab mirror as the repository source:
`https://jihulab.com/esp-mirror/espressif/arduino-esp32.git <https://jihulab.com/esp-mirror/espressif/arduino-esp32.git>`_
JSON files for the boards manager are available here:
- Stable release::
https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_index_cn.json
- Development release::
https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_dev_index_cn.json
Building Building
-------- --------

View file

@ -0,0 +1,280 @@
############
ZigbeeAnalog
############
About
-----
The ``ZigbeeAnalog`` class provides analog input and output endpoints for Zigbee networks. This endpoint implements the Zigbee Home Automation (HA) standard for analog signal processing and control.
Analog Input (AI) is meant to be used for sensors that provide an analog signal, such as temperature, humidity, pressure to be sent to the coordinator.
Analog Output (AO) is meant to be used for actuators that require an analog signal, such as dimmers, valves, etc. to be controlled by the coordinator.
Common API
----------
Constructor
***********
ZigbeeAnalog
^^^^^^^^^^^^
Creates a new Zigbee analog endpoint.
.. code-block:: arduino
ZigbeeAnalog(uint8_t endpoint);
* ``endpoint`` - Endpoint number (1-254)
Cluster Management
******************
addAnalogInput
^^^^^^^^^^^^^^
Adds analog input cluster to the endpoint.
.. code-block:: arduino
bool addAnalogInput();
This function will return ``true`` if successful, ``false`` otherwise.
addAnalogOutput
^^^^^^^^^^^^^^^
Adds analog output cluster to the endpoint.
.. code-block:: arduino
bool addAnalogOutput();
This function will return ``true`` if successful, ``false`` otherwise.
Analog Input API
----------------
Configuration Methods
*********************
setAnalogInputApplication
^^^^^^^^^^^^^^^^^^^^^^^^^
Sets the application type for the analog input.
.. code-block:: arduino
bool setAnalogInputApplication(uint32_t application_type);
* ``application_type`` - Application type constant (see esp_zigbee_zcl_analog_input.h for values)
This function will return ``true`` if successful, ``false`` otherwise.
setAnalogInputDescription
^^^^^^^^^^^^^^^^^^^^^^^^^
Sets a custom description for the analog input.
.. code-block:: arduino
bool setAnalogInputDescription(const char *description);
* ``description`` - Description string
This function will return ``true`` if successful, ``false`` otherwise.
setAnalogInputResolution
^^^^^^^^^^^^^^^^^^^^^^^^
Sets the resolution for the analog input.
.. code-block:: arduino
bool setAnalogInputResolution(float resolution);
* ``resolution`` - Resolution value
This function will return ``true`` if successful, ``false`` otherwise.
setAnalogInputMinMax
^^^^^^^^^^^^^^^^^^^^
Sets the minimum and maximum values for the analog input.
.. code-block:: arduino
bool setAnalogInputMinMax(float min, float max);
* ``min`` - Minimum value
* ``max`` - Maximum value
This function will return ``true`` if successful, ``false`` otherwise.
Value Control
*************
setAnalogInput
^^^^^^^^^^^^^^
Sets the analog input value.
.. code-block:: arduino
bool setAnalogInput(float analog);
* ``analog`` - Analog input value
This function will return ``true`` if successful, ``false`` otherwise.
Reporting Methods
*****************
setAnalogInputReporting
^^^^^^^^^^^^^^^^^^^^^^^
Sets the reporting configuration for analog input.
.. code-block:: arduino
bool setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta);
* ``min_interval`` - Minimum reporting interval in seconds
* ``max_interval`` - Maximum reporting interval in seconds
* ``delta`` - Minimum change in value to trigger a report
This function will return ``true`` if successful, ``false`` otherwise.
reportAnalogInput
^^^^^^^^^^^^^^^^^
Manually reports the current analog input value.
.. code-block:: arduino
bool reportAnalogInput();
This function will return ``true`` if successful, ``false`` otherwise.
Analog Output API
-----------------
Configuration Methods
*********************
setAnalogOutputApplication
^^^^^^^^^^^^^^^^^^^^^^^^^^
Sets the application type for the analog output.
.. code-block:: arduino
bool setAnalogOutputApplication(uint32_t application_type);
* ``application_type`` - Application type constant (see esp_zigbee_zcl_analog_output.h for values)
This function will return ``true`` if successful, ``false`` otherwise.
setAnalogOutputDescription
^^^^^^^^^^^^^^^^^^^^^^^^^^
Sets a custom description for the analog output.
.. code-block:: arduino
bool setAnalogOutputDescription(const char *description);
* ``description`` - Description string
This function will return ``true`` if successful, ``false`` otherwise.
setAnalogOutputResolution
^^^^^^^^^^^^^^^^^^^^^^^^^
Sets the resolution for the analog output.
.. code-block:: arduino
bool setAnalogOutputResolution(float resolution);
* ``resolution`` - Resolution value
This function will return ``true`` if successful, ``false`` otherwise.
setAnalogOutputMinMax
^^^^^^^^^^^^^^^^^^^^^
Sets the minimum and maximum values for the analog output.
.. code-block:: arduino
bool setAnalogOutputMinMax(float min, float max);
* ``min`` - Minimum value
* ``max`` - Maximum value
This function will return ``true`` if successful, ``false`` otherwise.
Value Control
*************
setAnalogOutput
^^^^^^^^^^^^^^^
Sets the analog output value.
.. code-block:: arduino
bool setAnalogOutput(float analog);
* ``analog`` - Analog output value
This function will return ``true`` if successful, ``false`` otherwise.
getAnalogOutput
^^^^^^^^^^^^^^^
Gets the current analog output value.
.. code-block:: arduino
float getAnalogOutput();
This function will return current analog output value.
Reporting Methods
*****************
reportAnalogOutput
^^^^^^^^^^^^^^^^^^
Manually reports the current analog output value.
.. code-block:: arduino
bool reportAnalogOutput();
This function will return ``true`` if successful, ``false`` otherwise.
Event Handling
**************
onAnalogOutputChange
^^^^^^^^^^^^^^^^^^^^
Sets a callback function to be called when the analog output value changes.
.. code-block:: arduino
void onAnalogOutputChange(void (*callback)(float analog));
* ``callback`` - Function to call when analog output changes
Example
-------
Analog Input/Output
*******************
.. literalinclude:: ../../../libraries/Zigbee/examples/Zigbee_Analog_Input_Output/Zigbee_Analog_Input_Output.ino
:language: arduino

View file

@ -0,0 +1,137 @@
############
ZigbeeBinary
############
About
-----
The ``ZigbeeBinary`` class provides an endpoint for binary input/output sensors in Zigbee networks. This endpoint implements the Zigbee Home Automation (HA) standard for binary sensors, supporting various application types for HVAC, security, and general binary sensing.
Binary Input (BI) is meant to be used for sensors that provide a binary signal, such as door/window sensors, motion detectors, etc. to be sent to the network.
.. note::
Binary Output (BO) is not supported yet.
API Reference
-------------
Constructor
***********
ZigbeeBinary
^^^^^^^^^^^^
Creates a new Zigbee binary sensor endpoint.
.. code-block:: arduino
ZigbeeBinary(uint8_t endpoint);
* ``endpoint`` - Endpoint number (1-254)
Binary Input Application Types
******************************
HVAC Application Types
^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: arduino
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_BOILER_STATUS 0x00000003
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_CHILLER_STATUS 0x00000013
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_OCCUPANCY 0x00000031
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_FAN_STATUS 0x00000035
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_FILTER_STATUS 0x00000036
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_HEATING_ALARM 0x0000003E
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_COOLING_ALARM 0x0000001D
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_UNIT_ENABLE 0x00000090
#define BINARY_INPUT_APPLICATION_TYPE_HVAC_OTHER 0x0000FFFF
Security Application Types
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: arduino
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_GLASS_BREAKAGE_DETECTION_0 0x01000000
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_INTRUSION_DETECTION 0x01000001
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_MOTION_DETECTION 0x01000002
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_GLASS_BREAKAGE_DETECTION_1 0x01000003
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_ZONE_ARMED 0x01000004
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_GLASS_BREAKAGE_DETECTION_2 0x01000005
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_SMOKE_DETECTION 0x01000006
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_CARBON_DIOXIDE_DETECTION 0x01000007
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_HEAT_DETECTION 0x01000008
#define BINARY_INPUT_APPLICATION_TYPE_SECURITY_OTHER 0x0100FFFF
API Methods
***********
addBinaryInput
^^^^^^^^^^^^^^
Adds a binary input cluster to the endpoint.
.. code-block:: arduino
bool addBinaryInput();
This function will return ``true`` if successful, ``false`` otherwise.
setBinaryInputApplication
^^^^^^^^^^^^^^^^^^^^^^^^^
Sets the application type for the binary input.
.. code-block:: arduino
bool setBinaryInputApplication(uint32_t application_type);
* ``application_type`` - Application type constant (see above)
This function will return ``true`` if successful, ``false`` otherwise.
setBinaryInputDescription
^^^^^^^^^^^^^^^^^^^^^^^^^
Sets a custom description for the binary input.
.. code-block:: arduino
bool setBinaryInputDescription(const char *description);
* ``description`` - Description string
This function will return ``true`` if successful, ``false`` otherwise.
setBinaryInput
^^^^^^^^^^^^^^
Sets the binary input value.
.. code-block:: arduino
bool setBinaryInput(bool input);
* ``input`` - Binary value (true/false)
This function will return ``true`` if successful, ``false`` otherwise.
reportBinaryInput
^^^^^^^^^^^^^^^^^
Manually reports the current binary input value.
.. code-block:: arduino
bool reportBinaryInput();
This function will return ``true`` if successful, ``false`` otherwise.
Example
-------
Binary Input Implementation
****************************
.. literalinclude:: ../../../libraries/Zigbee/examples/Zigbee_Binary_Input/Zigbee_Binary_Input.ino
:language: arduino

View file

@ -0,0 +1,105 @@
#########################
ZigbeeCarbonDioxideSensor
#########################
About
-----
The ``ZigbeeCarbonDioxideSensor`` class provides a CO2 sensor endpoint for Zigbee networks. This endpoint implements the Zigbee Home Automation (HA) standard for carbon dioxide measurement devices.
API Reference
-------------
Constructor
***********
ZigbeeCarbonDioxideSensor
^^^^^^^^^^^^^^^^^^^^^^^^^
Creates a new Zigbee CO2 sensor endpoint.
.. code-block:: arduino
ZigbeeCarbonDioxideSensor(uint8_t endpoint);
* ``endpoint`` - Endpoint number (1-254)
API Methods
***********
setCarbonDioxide
^^^^^^^^^^^^^^^^
Sets the CO2 concentration measurement value.
.. code-block:: arduino
bool setCarbonDioxide(float carbon_dioxide);
* ``carbon_dioxide`` - CO2 concentration value in ppm
This function will return ``true`` if successful, ``false`` otherwise.
setMinMaxValue
^^^^^^^^^^^^^^
Sets the minimum and maximum measurement values.
.. code-block:: arduino
bool setMinMaxValue(float min, float max);
* ``min`` - Minimum CO2 concentration value in ppm
* ``max`` - Maximum CO2 concentration value in ppm
This function will return ``true`` if successful, ``false`` otherwise.
setTolerance
^^^^^^^^^^^^
Sets the tolerance value for measurements.
.. code-block:: arduino
bool setTolerance(float tolerance);
* ``tolerance`` - Tolerance value in ppm
This function will return ``true`` if successful, ``false`` otherwise.
setReporting
^^^^^^^^^^^^
Sets the reporting configuration for CO2 measurements.
.. code-block:: arduino
bool setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta);
* ``min_interval`` - Minimum reporting interval in seconds
* ``max_interval`` - Maximum reporting interval in seconds
* ``delta`` - Minimum change required to trigger a report in ppm
**Note:** Delta reporting is currently not supported by the carbon dioxide sensor.
This function will return ``true`` if successful, ``false`` otherwise.
report
^^^^^^
Manually reports the current CO2 concentration value.
.. code-block:: arduino
bool report();
This function will return ``true`` if successful, ``false`` otherwise.
Example
-------
CO2 Sensor Implementation
*************************
.. literalinclude:: ../../../libraries/Zigbee/examples/Zigbee_CarbonDioxide_Sensor/Zigbee_CarbonDioxide_Sensor.ino
:language: arduino

View file

@ -0,0 +1,223 @@
########################
ZigbeeColorDimmableLight
########################
About
-----
The ``ZigbeeColorDimmableLight`` class provides an endpoint for color dimmable lights in Zigbee networks. This endpoint implements the Zigbee Home Automation (HA) standard for color lighting devices, supporting RGB color control, dimming, and scene management.
**Features:**
* On/off control
* Brightness level control (0-100%)
* RGB color control
* HSV color support
* Scene and group support
* Automatic state restoration
* Integration with common endpoint features (binding, OTA, etc.)
* Zigbee HA standard compliance
**Use Cases:**
* Smart RGB light bulbs
* Color-changing LED strips
* Mood lighting systems
* Entertainment lighting
* Architectural lighting
* Smart home color lighting
API Reference
-------------
Constructor
***********
ZigbeeColorDimmableLight
^^^^^^^^^^^^^^^^^^^^^^^^
Creates a new Zigbee color dimmable light endpoint.
.. code-block:: arduino
ZigbeeColorDimmableLight(uint8_t endpoint);
* ``endpoint`` - Endpoint number (1-254)
Callback Functions
******************
onLightChange
^^^^^^^^^^^^^
Sets the callback function for light state changes.
.. code-block:: arduino
void onLightChange(void (*callback)(bool, uint8_t, uint8_t, uint8_t, uint8_t));
* ``callback`` - Function pointer to the light change callback (state, red, green, blue, level)
Control Methods
***************
setLightState
^^^^^^^^^^^^^
Sets the light on/off state.
.. code-block:: arduino
bool setLightState(bool state);
* ``state`` - Light state (true = on, false = off)
This function will return ``true`` if successful, ``false`` otherwise.
setLightLevel
^^^^^^^^^^^^^
Sets the light brightness level.
.. code-block:: arduino
bool setLightLevel(uint8_t level);
* ``level`` - Brightness level (0-100, where 0 is off, 100 is full brightness)
This function will return ``true`` if successful, ``false`` otherwise.
setLightColor (RGB)
^^^^^^^^^^^^^^^^^^^
Sets the light color using RGB values.
.. code-block:: arduino
bool setLightColor(uint8_t red, uint8_t green, uint8_t blue);
bool setLightColor(espRgbColor_t rgb_color);
* ``red`` - Red component (0-255)
* ``green`` - Green component (0-255)
* ``blue`` - Blue component (0-255)
* ``rgb_color`` - RGB color structure
This function will return ``true`` if successful, ``false`` otherwise.
setLightColor (HSV)
^^^^^^^^^^^^^^^^^^^
Sets the light color using HSV values.
.. code-block:: arduino
bool setLightColor(espHsvColor_t hsv_color);
* ``hsv_color`` - HSV color structure
This function will return ``true`` if successful, ``false`` otherwise.
setLight
^^^^^^^^
Sets all light parameters at once.
.. code-block:: arduino
bool setLight(bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue);
* ``state`` - Light state (true/false)
* ``level`` - Brightness level (0-100)
* ``red`` - Red component (0-255)
* ``green`` - Green component (0-255)
* ``blue`` - Blue component (0-255)
This function will return ``true`` if successful, ``false`` otherwise.
State Retrieval Methods
***********************
getLightState
^^^^^^^^^^^^^
Gets the current light state.
.. code-block:: arduino
bool getLightState();
This function will return current light state (true = on, false = off).
getLightLevel
^^^^^^^^^^^^^
Gets the current brightness level.
.. code-block:: arduino
uint8_t getLightLevel();
This function will return current brightness level (0-100).
getLightColor
^^^^^^^^^^^^^
Gets the current RGB color.
.. code-block:: arduino
espRgbColor_t getLightColor();
This function will return current RGB color structure.
getLightRed
^^^^^^^^^^^
Gets the current red component.
.. code-block:: arduino
uint8_t getLightRed();
This function will return current red component (0-255).
getLightGreen
^^^^^^^^^^^^^
Gets the current green component.
.. code-block:: arduino
uint8_t getLightGreen();
This function will return current green component (0-255).
getLightBlue
^^^^^^^^^^^^
Gets the current blue component.
.. code-block:: arduino
uint8_t getLightBlue();
This function will return current blue component (0-255).
Utility Methods
***************
restoreLight
^^^^^^^^^^^^
Restores the light to its last known state.
.. code-block:: arduino
void restoreLight();
Example
-------
Color Dimmable Light Implementation
***********************************
.. literalinclude:: ../../../libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/Zigbee_Color_Dimmable_Light.ino
:language: arduino

View file

@ -0,0 +1,186 @@
#######################
ZigbeeColorDimmerSwitch
#######################
About
-----
The ``ZigbeeColorDimmerSwitch`` class provides a color dimmer switch endpoint for Zigbee networks. This endpoint implements the Zigbee Home Automation (HA) standard for advanced lighting control switches that can control both dimming and color of lights.
**Features:**
* On/off control for bound lights
* Brightness level control (0-100%)
* Color control (RGB, HSV)
* Color temperature control
* Scene and group support
* Special effects and timed operations
* Integration with common endpoint features (binding, OTA, etc.)
* Zigbee HA standard compliance
**Use Cases:**
* Smart lighting switches
* Color control remotes
* Advanced lighting controllers
* Smart home lighting automation
* Entertainment lighting control
API Reference
-------------
Constructor
***********
ZigbeeColorDimmerSwitch
^^^^^^^^^^^^^^^^^^^^^^^
Creates a new Zigbee color dimmer switch endpoint.
.. code-block:: arduino
ZigbeeColorDimmerSwitch(uint8_t endpoint);
* ``endpoint`` - Endpoint number (1-254)
Basic Control Commands
**********************
lightToggle
^^^^^^^^^^^
Toggles the state of bound lights (on to off, or off to on).
.. code-block:: arduino
void lightToggle();
void lightToggle(uint16_t group_addr);
void lightToggle(uint8_t endpoint, uint16_t short_addr);
void lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
* ``group_addr`` - Group address to control (optional)
* ``endpoint`` - Target device endpoint (optional)
* ``short_addr`` - Target device short address (optional)
* ``ieee_addr`` - Target device IEEE address (optional)
lightOn
^^^^^^^
Turns on bound lights.
.. code-block:: arduino
void lightOn();
void lightOn(uint16_t group_addr);
void lightOn(uint8_t endpoint, uint16_t short_addr);
void lightOn(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
* ``group_addr`` - Group address to control (optional)
* ``endpoint`` - Target device endpoint (optional)
* ``short_addr`` - Target device short address (optional)
* ``ieee_addr`` - Target device IEEE address (optional)
lightOff
^^^^^^^^
Turns off bound lights.
.. code-block:: arduino
void lightOff();
void lightOff(uint16_t group_addr);
void lightOff(uint8_t endpoint, uint16_t short_addr);
void lightOff(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
* ``group_addr`` - Group address to control (optional)
* ``endpoint`` - Target device endpoint (optional)
* ``short_addr`` - Target device short address (optional)
* ``ieee_addr`` - Target device IEEE address (optional)
Dimmer Control Commands
***********************
setLightLevel
^^^^^^^^^^^^^
Sets the brightness level of bound lights.
.. code-block:: arduino
void setLightLevel(uint8_t level);
void setLightLevel(uint8_t level, uint16_t group_addr);
void setLightLevel(uint8_t level, uint8_t endpoint, uint16_t short_addr);
void setLightLevel(uint8_t level, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
* ``level`` - Brightness level (0-100, where 0 is off, 100 is full brightness)
* ``group_addr`` - Group address to control (optional)
* ``endpoint`` - Target device endpoint (optional)
* ``short_addr`` - Target device short address (optional)
* ``ieee_addr`` - Target device IEEE address (optional)
Color Control Commands
**********************
setLightColor
^^^^^^^^^^^^^
Sets the color of bound lights using RGB values.
.. code-block:: arduino
void setLightColor(uint8_t red, uint8_t green, uint8_t blue);
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr);
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr);
void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
* ``red`` - Red component (0-255)
* ``green`` - Green component (0-255)
* ``blue`` - Blue component (0-255)
* ``group_addr`` - Group address to control (optional)
* ``endpoint`` - Target device endpoint (optional)
* ``short_addr`` - Target device short address (optional)
* ``ieee_addr`` - Target device IEEE address (optional)
Advanced Control Commands
*************************
lightOffWithEffect
^^^^^^^^^^^^^^^^^^
Turns off lights with a specific effect.
.. code-block:: arduino
void lightOffWithEffect(uint8_t effect_id, uint8_t effect_variant);
* ``effect_id`` - Effect identifier
* ``effect_variant`` - Effect variant
lightOnWithTimedOff
^^^^^^^^^^^^^^^^^^^
Turns on lights with automatic turn-off after specified time.
.. code-block:: arduino
void lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, uint16_t time_off);
* ``on_off_control`` - Control byte
* ``time_on`` - Time to stay on (in 1/10th seconds)
* ``time_off`` - Time to stay off (in 1/10th seconds)
lightOnWithSceneRecall
^^^^^^^^^^^^^^^^^^^^^^
Turns on lights with scene recall.
.. code-block:: arduino
void lightOnWithSceneRecall();
Example
-------
Color Dimmer Switch Implementation
**********************************
.. literalinclude:: ../../../libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino
:language: arduino

View file

@ -0,0 +1,95 @@
###################
ZigbeeContactSwitch
###################
About
-----
The ``ZigbeeContactSwitch`` class provides a contact switch endpoint for Zigbee networks. This endpoint implements the Zigbee Home Automation (HA) standard for door/window contact sensors and other binary contact devices.
**Features:**
* Contact state detection (open/closed)
* Configurable application types
* Automatic reporting capabilities
* Integration with common endpoint features (binding, OTA, etc.)
* Zigbee HA standard compliance
**Use Cases:**
* Door and window sensors
* Security system contacts
* Cabinet and drawer sensors
* Industrial contact monitoring
* Smart home security applications
API Reference
-------------
Constructor
***********
ZigbeeContactSwitch
^^^^^^^^^^^^^^^^^^^
Creates a new Zigbee contact switch endpoint.
.. code-block:: arduino
ZigbeeContactSwitch(uint8_t endpoint);
* ``endpoint`` - Endpoint number (1-254)
API Methods
***********
setClosed
^^^^^^^^^
Sets the contact switch to closed state.
.. code-block:: arduino
bool setClosed();
This function will return ``true`` if successful, ``false`` otherwise.
setOpen
^^^^^^^
Sets the contact switch to open state.
.. code-block:: arduino
bool setOpen();
This function will return ``true`` if successful, ``false`` otherwise.
setIASClientEndpoint
^^^^^^^^^^^^^^^^^^^^
Sets the IAS Client endpoint number (default is 1).
.. code-block:: arduino
void setIASClientEndpoint(uint8_t ep_number);
* ``ep_number`` - IAS Client endpoint number
report
^^^^^^
Manually reports the current contact state.
.. code-block:: arduino
bool report();
This function will return ``true`` if successful, ``false`` otherwise.
Example
-------
Contact Switch Implementation
*****************************
.. literalinclude:: ../../../libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino
:language: arduino

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