Compare commits

...

643 Commits

Author SHA1 Message Date
ris
a7612ada45 LED data gets transmitted using signal but not stable yet
Some checks failed
CI - nightly / esp-hal | nightly (${{ matrix.device.soc }}) (map[soc:esp32c2 target:riscv32imc-unknown-none-elf]) (push) Has been cancelled
CI - nightly / esp-hal | nightly (${{ matrix.device.soc }}) (map[soc:esp32c3 target:riscv32imc-unknown-none-elf]) (push) Has been cancelled
CI - nightly / esp-hal | nightly (${{ matrix.device.soc }}) (map[soc:esp32c6 target:riscv32imac-unknown-none-elf]) (push) Has been cancelled
CI - nightly / esp-hal | nightly (${{ matrix.device.soc }}) (map[soc:esp32h2 target:riscv32imac-unknown-none-elf]) (push) Has been cancelled
2025-01-09 19:43:59 -05:00
ris
d581195df7 LEDs write correctly and mulitcore now 2025-01-09 15:34:38 -05:00
Dániel Buga
040c0fd353
Mark Flex methods as unstable (#2917) 2025-01-09 16:13:12 +00:00
Dániel Buga
021676e871
Remove more enum prefixes (#2922) 2025-01-09 15:33:58 +00:00
Dániel Buga
848029b152
Test all feature sets (#2901)
* Mark interconnect as unstable

* Explicitly set unstable feature in HIL tests

* WIP append feature set name to artifact

* Add name to feature sets, build all combinations

* Fix tests

* Provide a looping executor for stable async tests

* Fix usb serial jtag

* Hide interconnect types
2025-01-09 13:58:14 +00:00
Dániel Buga
2b80e4d123
Return error instead of panic (#2916) 2025-01-09 13:47:54 +00:00
Dániel Buga
0ef00206d5
Remove all instance type params (#2907) 2025-01-09 11:27:48 +00:00
Dániel Buga
409641dd7e
Document that UART TX should be set up first (#2914) 2025-01-09 10:29:46 +00:00
Dániel Buga
9f553b1b0e
Mark ClockSources as #[non_exhaustive] (#2912) 2025-01-08 19:07:25 +00:00
Juraj Sadel
8a7f8361a6
UART: Move RX/TX pin assignment from constructor to builder functions (#2904)
* Add with_rx() and with_tx() methods to UART drivers

* changelog

* migration guide

* forgotten tests

* fmt

* fix H2 example

* Use the same calling order of calling TX and RX as before
2025-01-08 16:35:22 +00:00
Jesse Braham
7d0b39dbd2
Fix naming violations for SPI Address and Command enums (#2906)
* Fix naming violations for SPI `Address` and `Command` enums

* Update migration guide

* Update `CHANGELOG.md`
2025-01-08 14:39:54 +00:00
Dániel Buga
246e7f1c8b
Disable failing tests (#2910) 2025-01-08 14:38:10 +00:00
Björn Quentin
6b4312fb90
Use own implementation instead of ROM functions, re-add memchr (#2896)
* Use own implementation instead of ROM functions, re-add memchr ROM function

* CHANGELOG.md

* Improve

* Cast
2025-01-08 07:12:04 +00:00
Davo
5a64d9ba8f
feat: add support for internal temperature sensor (tsens) for esp32c6 and esp32c3 (#2875)
* feat: add basic support for temperature sensor (tsens) for esp32c6

* feat: add basic support for temperature sensor (tsens) for esp32c3

* feat: add configurable clock source for temperature sensor

* feat: add Temperature struct to avoid enforcing usage of floats

- Also add misc derives to multiple structs
- Add power_up / power_down methods to TemperatureSensor
- Enable ApbSarAdc via PeripheralGuard

* fix: move tsens module to unstable module list
2025-01-07 16:40:12 +00:00
Juraj Sadel
f1276f7d1b
Remove unnecessary prefixes/suffixes from Error and TxEvent enums (#2898)
* Remove unnecessary prefixes/suffixes from Error and TxEvent enums

* Remove #[allow(clippy::enum_variant_names ...)

* Use object+verb naming in Error enum variant

* Migration guide entry

* Remove ZeroLengthBufferPassed variant

* docs
2025-01-07 16:08:10 +00:00
Jesse Braham
bb406cec6b
Fix naming violations for spi::Mode enum variants (#2902)
* Fix naming violations for `spi::Mode`

* Update migration guide

* Update `CHANGELOG.md`
2025-01-07 15:55:19 +00:00
Björn Quentin
66d2effee2
Stabilize CpuClock, make non-exhaustive, rename variants (#2899)
* Stabilize CpuClock, make non-exhaustive, rename variants

* CHANGELOG.md

* Fix
2025-01-07 14:43:41 +00:00
Dominic Fischer
b3401bff59
Refactor SPI MISO setup (#2557)
* Refactor SPI MISO setup

* update HIL

* docs

* missed a spot

* fix changelog

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
Co-authored-by: Scott Mabin <scott@mabez.dev>
2025-01-07 11:31:26 +00:00
Jesse Braham
2a4e58a230
UART: Remove blocking version of read_bytes and rename drain_fifo to read_bytes instead (#2895)
* Remove `read_bytes` function, rename `drain_fifo` to `read_bytes`

* Update migration guide

* Update `CHANGELOG.md`

* Use `crate::interrupt::free` in `read_byte`

* Fix HIL test

* Only use `crate::interrupt:free` for ESP32
2025-01-07 10:02:29 +00:00
Juraj Sadel
5cd0d6f6bf
Alter stability note in README and briefly explain unstable feature (#2894)
* Alter stability note in README and briefly explain unstable feature

* Review comments
2025-01-07 09:03:30 +00:00
Jesse Braham
39da5337ac
Fix naming violations and clean up some doc comments in UART driver (#2893)
* Resolve naming violation for `Parity` enum

* Remove unnecessary/redundant information from doc comments

* Resolve naming violations for `DataBits` and `StopBits` enums

* Update migration guide

* Update `CHANGELOG.md`
2025-01-06 12:11:06 +00:00
Dominic Fischer
7319458dd2
Properly reset descriptors in DmaRxStreamBuf::prepare (#2890)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2025-01-06 09:16:44 +00:00
Jesse Braham
05b5bac027
Add package metadata to esp-storage to make documentation build (#2891) 2025-01-06 08:03:53 +00:00
Dominic Fischer
6494354a91
Fix small typo in migration guide (#2888)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2025-01-06 07:14:47 +00:00
Dániel Buga
713cd491b6
GPIO: Refactor AnyPin to contain a u8 (#2854)
* Remove panicking match from Flex::set_level

* Rework AnyPin to contain a u8

* SPI

---------

Co-authored-by: Scott Mabin <scott@mabez.dev>
2025-01-03 14:46:39 +00:00
Dániel Buga
337b3cc6b7
Use _CONFIG_ to separate config prefix and key (#2848)
* Use two underscores to separate prefix

* Change separator to _CONFIG_

---------

Co-authored-by: Scott Mabin <scott@mabez.dev>
2025-01-03 14:36:30 +00:00
Björn Quentin
dc2b968491
qa-test (#2871)
* Run multiple examples/tests

* Adapt some qa-tests
2025-01-03 14:31:19 +00:00
Dániel Buga
19eb7728bb
Allow clippy to break API, ignore a few initialism errors (#2840) 2025-01-03 14:13:07 +00:00
Björn Quentin
551386216e
Mention performance considerations (#2881) 2025-01-03 12:34:52 +00:00
Dániel Buga
1f929af377
Remove redundant config setters (#2847)
Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2025-01-02 09:55:37 +00:00
Sergio Gasquez Arcos
06a15807e3
Fix C-METADATA violations (#2874)
* fix: C-METADATA violations of esp-hal

* feat: Normalize keyword and categories for most of the pacakges
2025-01-02 09:44:27 +00:00
Anthony Grondin
0f384992cf
Update smoltcp to 0.12.0 and embassy-net to 0.5.0 (#2849)
* chore: Update smoltcp to `0.12.0` and embassy-net to `0.5.0`

* Add CHANGELOG entry

* Remove `wifi_dhcp_smoltcp_nal.rs` example

`smoltcp-nal`, a core dependency on which this example depends on doesn't receive the desired amount of maintainability needed to keep up to date with new dependencies releases.
2025-01-02 09:41:31 +00:00
Björn Quentin
36095e447e
Hide Info,State,Instance (#2856)
* Hide Info,State,Instance

* Fix lp_gpio macro

* Fix visibility
2024-12-23 13:57:31 +00:00
Dániel Buga
c2de8a1859
Mark SPI slave as unstable (#2853) 2024-12-20 15:23:29 +00:00
Juraj Sadel
b9ebeb1809
Solve unstable inconsistencies in SPI master driver (#2852)
* Solve unstable unconsistencies in SPI master driver

* Mark Command, Address, and DataMode unstable as well
2024-12-20 14:49:59 +00:00
Kirill Mikhailov
8b16365c2d
Make ConfigError enum follow naming convention (#2855)
* Make `ConfigError` follow naming convention

* changelog entry

* !(changelog entry)
2024-12-20 14:36:54 +00:00
Kirill Mikhailov
62c72947dd
Multiple API fixes in UART driver (#2851)
* Close a number of issues

doctest update

fmt

* changelog entry

* dumb

* addressing reviews

* Add an entry to migration guide
2024-12-20 14:01:11 +00:00
Kirill Mikhailov
286219707c
I2C: Prefer compile-time checks over runtime checks where possible, prefer a fallible API over panics. (#2831)
* I2C module improvements (raw)

* fmt

* dumb

dumb2

dumb 3

dumb 4

dumb 5

* re-use `ExceedingFifo` instead of new `ExceedingTransactionSize` error

* changelog entry

* address reviews

* rebase

* dumb 6

* rebase

...
2024-12-20 13:18:28 +00:00
Dániel Buga
d66e153686
Remove Pin::gpio_bank (#2850) 2024-12-20 12:33:10 +00:00
Dániel Buga
7f8af8a651
Remove prelude (#2845)
* Remove prelude

* Changelog
2024-12-20 10:24:57 +00:00
C2D
2e6a95ac99
Add SpiDmaBus::split for moving between manual & automatic DMA buffers (#2824)
* Allow swapping dma buffers

* Deconstruct makes more sense

* Format

* Changelog

* Race-conditioned

* Change SpiDmaBus::deconstruct name to SpiDmaBus::split

* Add flush & bracket references

* Fix mutability

* Fix name of generic param

---------

Co-authored-by: ferris <ferris@devdroplets.com>
Co-authored-by: Dániel Buga <bugadani@gmail.com>
2024-12-20 09:23:33 +00:00
Björn Quentin
5c30c925ca
Make more SPI interrupts available (#2833)
* Make more SPI interrupts available

* CHANGELOG.md

* SPI interrupts for ESP32/ESP32-S2

* Fix

* Don't offer error interrupts

* Change doc wording

* Renaming

* Rebase fun

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-12-20 07:54:58 +00:00
Scott Mabin
f83ab23f04
Avoid abbreviations in API (#2844)
* Avoid abbreviations in API

* changelog/migration
2024-12-19 14:39:40 +00:00
C2D
f1c372f250
Fix SpiDmaBus write impl (#2843)
* Fix SpiDmaBus write impl

* Add hil test for SpiDmaBus::{read,write}

---------

Co-authored-by: ferris <ferris@devdroplets.com>
2024-12-19 13:57:21 +00:00
Dániel Buga
151e66c3b3
Implement missing traits on GPIO types (#2842) 2024-12-19 11:31:54 +00:00
Dániel Buga
a3b3547212
Implement some missing traits (#2823) 2024-12-19 10:58:49 +00:00
Jesse Braham
1fff464b66
Derive common traits for various types in uart and i2c drivers (#2825)
* Derive `Eq` for `uart::ConfigError`

* Derive common traits in `i2c::master` module for various types

* Update `CHANGELOG.md`

* Implement `Display` and `Error` traits for I2C/UART error types

* Remove `PartialEq` and `Eq` derives from I2C driver
2024-12-19 10:10:30 +00:00
Jesse Braham
036d08e09f
Annotate builder functions with #[must_use] (#2841) 2024-12-19 10:10:23 +00:00
Dániel Buga
cde6169d6d
Walk back on PartialEq/Eq (#2834) 2024-12-19 09:00:35 +00:00
Sergio Gasquez Arcos
d4386adfc7
Rename Spi enums (#2828)
* feat: Rename Spi enums

* docs: Update changelog

* feat: Rename crate::Mode to crate::DriverMode

* docs: Udpate changelog

* feat: Rename DM type parameter to Dm for ECC

* style: rustfmt

* feat: Rename crate::Mode to crate::DriverMode
2024-12-19 08:41:59 +00:00
Dániel Buga
97598968eb
GPIO: prevent woken task interrupting GPIO handler (#2838)
* Clear interrupt bit before allowing waker to wake a task

* Add test
2024-12-19 07:53:48 +00:00
Dániel Buga
b8f15f0a8b
Refine API-GUIDELINES recommendations (#2832)
* Refine C-COMMON-TRAITS recommendations

* Recommend deriving Error

* Clarify that Instance, State and Info are private implementation details at this point
2024-12-19 07:08:25 +00:00
Dániel Buga
f2b958b501
Convert into c_char (#2837) 2024-12-18 18:59:28 +00:00
Dániel Buga
f7c1bdbfc5
Implement Hash and defmt::Format for InterruptHandler (#2830) 2024-12-18 16:27:27 +00:00
Scott Mabin
78c63a7a0f
fix link to esp-wifi self hosted docs (#2836) 2024-12-18 14:43:38 +00:00
Dániel Buga
af8eaea1e3
Pin 1.83.0.1 in CI (#2835) 2024-12-18 12:29:48 +00:00
Juraj Sadel
1684ba10f0
Rename TOUCHMODE to Tm (#2829) 2024-12-18 08:37:09 +00:00
Dániel Buga
2ca1545b50
SPI: Implement interrupt-driven transfer_in_place_async (#2691)
* Implement transfer_async

* The start of our shiny future

* Add State

* Wake from interrupt

* Rename and remove return value

* Fix register write

* Fix S2

* Rename traits

* Async flushes

* Flush before async operations

* Fix comments

* Rename start fn, place async handler in RAM

* Explicitly stop listening before async operations
2024-12-18 07:32:12 +00:00
Frostie314159
f990957f21
Updated PACs and made Wi-Fi non virtual on the ESP32. (#2822) 2024-12-17 16:54:51 +00:00
Juraj Sadel
d9f1e9a53f
Rename DM type parameter to Dm (#2821)
* Rename DM type parameter to Dm

* Rename M, DmaMode, MODE type parameters to Dm

* fmt
2024-12-17 16:49:23 +00:00
Scott Mabin
85d30e9816
Updates for Xtensa enabled 1.83 compiler (#2615)
* test ci

* fix ci with new compiler

* god bless clippy fix

* refmuts

* clippy

* tests work

* use new compiler

* use new compiler

* bump MSRV of esp-hal and crates that depend on esp-hal

* fix eyesore

* clippy again

* remove hardcoded compiler version

* bump rust-version as well

* note MSRV bump in changelog
2024-12-17 15:02:03 +00:00
Dániel Buga
a12e7fece1
Fix WIFI_EVENT (#2817)
* Fix WIFI_EVENT

* Update esp-wifi/src/common_adapter/mod.rs

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-12-16 11:53:45 +00:00
Dániel Buga
bc0bedd628
Add priority-limited locks (#2684)
* Add priority-limited locks

* Rename to RawMutex, only provide lock() publicly

* Explode implementation and move into the interrupt module
2024-12-16 08:39:42 +00:00
Juraj Sadel
3a03dd88c7
Prefer line comments // over block comments /* */ (#2738)
* Prefer line comments // over block comments /* */

* esp-wifi: Prefer line comments // over block comments /* */

* Mention in our API guideline that // should be prefered over /* */
2024-12-12 15:53:38 +00:00
Dániel Buga
cc4e527eaf
Fix async USB OTG-FS driver (#2742)
* Use unwrap macro

* Clean up reset

* Better replicate synopsys init

* Fix indentation

* Clean up constructor

* Initialize before poll

* Remove prefix

* Keep the Usb PeripheralGuard around

* Remove example addition
2024-12-12 13:16:32 +00:00
Kaspar Schleiser
d66281609b
esp-hal: otg_fs: drop obsolete late cnak quirk (#2621)
* esp-hal: otg_fs: drop obsolete late cnak quirk

* build: bump embassy-usb-synopsys-otg to 0.2.0
2024-12-11 23:49:16 +00:00
Björn Quentin
62994578c2
Fix qa-test build.rs (#2722)
* Fix qa-test build.rs

* Once is enough
2024-12-10 15:32:29 +00:00
Dániel Buga
35d3ed301c
Clean the correct bit (#2721) 2024-12-10 14:09:11 +00:00
Dániel Buga
273fdc0928
ESP32-S2: implement CryptoDMA for AES (#2699)
* Changelog

* Split up PDMA into modules

* Add CryptoDMA implementation

* Move file

* Import SELECT only in the function where we use it

---------

Co-authored-by: Juraj Sadel <juraj.sadel@espressif.com>
2024-12-10 13:02:20 +00:00
Dániel Buga
3cc8d611bd
Update PACs (#2719) 2024-12-10 11:23:52 +00:00
Jesse Braham
f6126502ae
Actually use a random seed in Wi-Fi examples (#2718) 2024-12-10 11:02:05 +00:00
Dániel Buga
d2f15d69d7
Fix signal fn recommendation (#2692) 2024-12-06 13:36:20 +00:00
Dániel Buga
5135965116
Hide most of the unstable peripherals (#2667)
* Hide most of the unstable peripherals

* Lint with correct toolchain, lint with unstable enabled

* Require unstable feature and lint using it

* Auto-lint xtensas with esp toolchain

* Fix msrv and ieee802154

* Add feature to examples

* Don't require building ieee802154 for all examples

* Mark modules in documentation
2024-12-06 11:03:56 +00:00
Dániel Buga
6b01f7993b
SPI and related changes (#2681)
* Define Octal SpiDataMode

* Fix BitOrder capitalization

* Hide DmaError

* Derive more traits

* Return error for unsupported half-duplex parameter combinations

* Remove unnecessary implementation detail

* Return error instead of silently breaking transaction

* Downgrade assert to debug_assert

* Expand on the enum variants

* Remove redundant imports

* Hide some unstable functions
2024-12-06 10:30:43 +00:00
Jesse Braham
d86a079ea9
Seal the PeripheralInput and PeripheralOutput traits (#2690)
* Seal the `PeripheralInput` and `PeripheralOutput` traits

* Update `CHANGELOG.md`
2024-12-06 09:13:39 +00:00
Dániel Buga
9458fd3ed4
[DMA 8/8] Burst configuration (#2543)
* Implement burst configuration

* Reject transfers if the DMA in incapable of accessing external memory

* Fix psram

* Rename, documentation

* Address a few review comments

* Check buffer length, too

* Return error instead of panic

* Allow users to only specify the relevant burst config

* Add missing conversion

* Add missing docs

* Fix IN alignment requirements

* Fix test

* Deduplicate chunk size literal
2024-12-06 08:30:58 +00:00
Dániel Buga
2d4ccd735f
Prevent creating GpioPin (#2688) 2024-12-06 06:20:49 +00:00
Dániel Buga
b4379b8518
Auto-implement Debug, PartialEq and defmt::Format for peripherals (#2682) 2024-12-05 13:33:12 +00:00
Jesse Braham
b26b31f1ce
Mention that config structs should derive procmacros::BuilderLite in the API guidelines (#2686) 2024-12-05 13:23:09 +00:00
Tommaso Clini
dfa96820f0
DHCP support added to wifi embassy access point example (#2683)
* added dhcp to access point example, also GW IP is configure from environment as shown in Cargo.toml

* changelog entry

* Revert "changelog entry"

This reverts commit 3412d1c194.

* default gateway IP in case env IP isn't provided

* dhcp server runs in a loop so that it will restart on an error
2024-12-05 11:22:36 +00:00
Kirill Mikhailov
033c4b84c6
RESERVED_INTERRUPTS to be INTERRUPT_TO_PRIORITY (#2676) 2024-12-04 16:43:41 +00:00
Dániel Buga
50387290d9
API-GUIDELINES tweaks (#2677)
* Add PeripheralGuard exception

* Add cfg! macro recommendation
2024-12-04 15:52:59 +00:00
Dániel Buga
dcded33d3d
Fix into_async/blocking on typed Spi (#2674) 2024-12-04 14:45:52 +00:00
Juraj Sadel
d54f8440a5
HIL(QOL): Use global timeout instead of timeout macros (#2489)
* HIL(QOL): Add missing timeouts to various tests

* Increase timeouts for ECC

* Use global timeout in hil tests

* sha: increase test_digest_of_size_1_to_200 timeout from 10 to 15 seconds
2024-12-04 12:03:39 +00:00
Dániel Buga
91d7f23982
Mark some dependencies as unstable (#2668)
* Mark some dependencies as unstable

* Fix docs

* Pass unstable to doctests

* Document the unstable feature
2024-12-04 09:58:41 +00:00
Jesse Braham
a189eff517
Use cfg_if in favour of multiple cfgs in set_rx_fifo_full_threshold function (#2670) 2024-12-03 09:27:08 +00:00
Jesse Braham
da59a4eb36
Use upper camel case for UART's StopBits variants (#2669)
* Use upper camel case for UART's `StopBits` variants

* Update `CHANGELOG.md`
2024-12-03 08:28:04 +00:00
Dominic Fischer
94e7ffbcef
Remove Dma[Rx|Tx]Buffer::length (#2587)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-12-03 08:27:13 +00:00
Dániel Buga
a6a83d3bb5
Track async GPIOs in memory (#2625)
* Track async GPIOs in memory

* Add an example

* Deduplicate interrupt handling

* Changelog

* Add gpio_bank_1 symbol

* Derive EnumCount

* Try to fix issues around manual listen calls and multi-core

* Fix test

* Update esp-hal/src/gpio/mod.rs

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

* Do not prevent pending interrupt from being handled

* Remove unnecessary unpin

* Add a note about interrupt status flags

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-12-02 15:35:10 +00:00
Jesse Braham
891a12e13f
Derive Builder Lite pattern for HAL configuration, update examples/tests (#2645)
* Derive Builder Lite pattern for `esp_hal::Config` and `WatchdogConfig`

* User builder pattern for `esp_hal::Config` in examples/tests

* Update `CHANGELOG.md`
2024-12-02 14:45:05 +00:00
Dániel Buga
9f3476b006
Unstable documentation proof of concept (#2628)
* Unstable documentation proof of concept

* Hide the red banner in esp-wifi documentation

* Changelog
2024-12-02 10:49:06 +00:00
Dániel Buga
2d3fdeb876
Don't require importing macro for esp-config (#2630) 2024-12-02 08:03:46 +00:00
Danila Gornushko
2d87bb0002
Add heap usage stats with defmt (#2619)
* feat(esp-alloc): Add heap usage stats and provide `esp_alloc::get_info!()` macro

* refactor(esp-alloc): Feature gate internal memory usage that requires extra computation.

- Introduce the `internal-heap-stats` feature for `esp-alloc`.
- Add `esp_alloc::get_info!()` to `psram_quad` example to show usage and
ensure coverage of the feature in tests.

* refactor(esp-alloc): Remove `get_info!()` macro in favour of documenting `HEAP.stats()`

* Implement defmt::Format for HeapStats and RegionStats

* rustfmt

* show usage percent + move bar drawing logic to separate functions

* update doc comments

* Fixed a typo in qa-test/src/bin/psram_quad.rs

Co-authored-by: Scott Mabin <scott@mabez.dev>

* minor improvements to write bar functions

* Aligned the indentation in Cargo.toml

Co-authored-by: Kirill Mikhailov <62840029+playfulFence@users.noreply.github.com>

* Fixed a typo in docs

Co-authored-by: Kirill Mikhailov <62840029+playfulFence@users.noreply.github.com>

* Nitpicking x2

Co-authored-by: Kirill Mikhailov <62840029+playfulFence@users.noreply.github.com>

* Surround a function call with backticks

Co-authored-by: Kirill Mikhailov <62840029+playfulFence@users.noreply.github.com>

* rustfmt

---------

Co-authored-by: Anthony Grondin <104731965+AnthonyGrondin@users.noreply.github.com>
Co-authored-by: Scott Mabin <scott@mabez.dev>
Co-authored-by: Kirill Mikhailov <62840029+playfulFence@users.noreply.github.com>
2024-11-28 13:07:36 +00:00
Björn Quentin
b6117d5040
Use opt-level to detect debug profile (#2622) 2024-11-28 10:52:11 +00:00
Dániel Buga
92910bf1cb
Constructor consistency update (#2610)
* UART: only implement constructors with config, define ConfigError

* UART: only implement interrupt functions for Blocking

* I2C: fallible constructors

* Lcd/Cam

* SPI

* Update tests and examples

* Changelog

* Add note about ConfigError

* Fmt
2024-11-28 09:28:50 +00:00
Jesse Braham
1a2bee6f1f
Add derive macro for BuilderLite, add #[non_exhaustive] to some enums and structs (#2614)
* Add a derive procmacro to implement the Builder Lite pattern for a struct

* Add `#[non_exhaustive]` and derive `BuilderLite` where necessary in I2C module

* Add `#[non_exhaustive]` and derive `BuilderLite` where necessary in UART module

* Add `#[non_exhaustive]` and derive `BuilderLite` where necessary in SPI module

* Update `CHANGELOG.md`

* Fix build errors in HIL tests

* Fix generated doc comments

* Return a `ParseError` rather than panicking

* Add a method to set the value to `None` for `Option` types
2024-11-27 15:54:43 +00:00
Kirill Mikhailov
aeda6ac00a
Remove embedded-hal 0.2.x impls and dependency from esp-lp-hal package (#2609)
* removed eh02 dependencies, sh*tcode, not yet tested properly,copy-pasted

* changelog entry

* Don't implement eh1 traits
2024-11-27 14:54:00 +00:00
Björn Quentin
cfb83b153d
Fixed triggering a debug-assertion during scan (#2612)
* Fixed triggering a debug-assertion during scan

* CHANGELOGs

* Change `debug_assert` into warning level log

* Enable debug-asserts in hil-test, qa-test and examples

* Change the way we detect and warn about debug-builds

* Warn if opt-level is `0` or `1`
2024-11-27 14:14:04 +00:00
Scott Mabin
2512658653
[3/3] Timer refactor: Timer driver mode, ETM support and erasure (#2586)
* Add mode param and type erasure to high level timer drivers

* Add async impls for the timers plus eha impl

* re add etm example, fix etm for systimer

* re add tests

* Add Into<AnyTimer> + 'static bounds to the Timer trait

* remove set_alarm_active impl detail from the timer trait

* clippy

* doc fix ups

* changelog and migration guide

* review

* fix h2, reuse schedule for delay
2024-11-27 14:10:56 +00:00
Dániel Buga
b50a075449
Amend rust guidelines (#2617) 2024-11-27 12:41:51 +00:00
Scott Mabin
7095576e6a
Move interrupt related bits out of lib.rs and into the interrupt module (#2613)
* move interrupt related bits out of lib.rs and into the interrupt module

* changelog and migration guide

* review
2024-11-27 10:29:32 +00:00
Dániel Buga
eec75c8f82
Replace some esp-wifi critical sections with locks (#2554)
* Replace some esp-wifi critical sections with locks

* Remove critical section from event handlers

* Fix doc warnings and accidentally hard-coded esp32s3

* Use Lock in wifi_int_disable/restore

* Replace critical_section in ConcurrentQueue

* Deduplicate wifi_int_disable
2024-11-25 17:06:05 +00:00
Dániel Buga
aed0fac0eb
Rewrite time driver (#2559)
* Rewrite time driver

* Don't store priority

* Changelog

* Fix doc example

* Use separate locks for Alarms

* Mention generic queues

* Cache the next wakeup timestamp

* Immediately repoll if timestamp is in the past

* Add benchmark

* Remove equality check for now

* Enable interrupts when allocating the alarm

* Clean up

* Use relaxed ordering

* wut

* Typo

* Move benchmar

* fmt
2024-11-25 17:02:47 +00:00
Jesse Braham
b06c7a470c
Remove unnecessary features from esp-hal-procmacros, enable rtc-slow feature for Xtensa devices (#2594)
* Remove unnecessary features from `esp-hal-procmacros`

* Enable the `esp-hal-procmacros/rtc-slow` feature for Xtensa devices

* Update CHANGELOGs
2024-11-25 15:18:14 +00:00
Scott Mabin
6a008bf597
note rustdoc linkage (#2595) 2024-11-25 14:32:01 +00:00
Kirill Mikhailov
a00643f22d
Remove embedded-hal 0.2.x impls and deps from esp-hal (#2593)
* Initial remove

* update ssd1306 driver version

* small docs cleanup

* migration guide

* changelog entry

* update changelog entry (move under `Removed` section)

* eh migration guide link

* `Wait` trait linking
2024-11-25 14:13:10 +00:00
Dániel Buga
ef98e2b24f
[DMA 7/8]: Remove Dma, move channels to Peripherals (#2545)
* Move DMA channels into Peripherals

* Initialize DMA in the critical section needed for clock management

* Update esp-hal/MIGRATING-0.22.md

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-11-25 09:31:18 +00:00
Kirill Mikhailov
8b36a43c07
Remove more examples. Update doctests. (#2547)
* WIP

* WIP(1)

* done

* changelog entry

* swint example needs to lose some weight

+ fix psram

* get twai and touch examples back, lcd example to qa, less embassy

* more moving

* move changelog entry

* address reviews

upd: revert "is_not_release" check

* rebase + a bit more changes

remove useless feature

* address review

remove inappropriate doctest tutorial

* get all sleep examples back and to qa-test

fmt

* get rid of some redundant printlns in doctests

* etm timer upd

* make printlns great again

* writeln! -> println!

* clear "timer with interrupts" doctest
2024-11-25 08:13:35 +00:00
Dániel Buga
3adb0b288e
0.21 Migration guide fixes (#2592) 2024-11-23 15:20:14 +00:00
Dániel Buga
fe482bdd05
Auto-initialize PSRAM (#2546) 2024-11-23 14:10:44 +00:00
Dániel Buga
09511c750a
Trim down xtensa-lx (#2357)
* Remove mutex, InterruptNumber, bare_metal and spin

* Changelog
2024-11-23 01:01:37 +00:00
Dániel Buga
51215093ca
AES cleanups (#2588)
* Deduplicate DMA trigger impl

* Deduplicate write_mode

* Fix num_block

* Clean up CipherMode setting
2024-11-23 00:37:11 +00:00
Dániel Buga
45395d4cc9
Add custom AtomicWaker and embassy-sync mutex implementation (#2555)
* Add custom AtomicWaker

* Replace Option with a null waker

* Revert "Replace Option with a null waker"

This reverts commit 9a861571790d13087e1448fa9d209d2edf956cb8.

* Clippy

* Implement RawMutex

* Move AtomicWaker, reimplement using Generic
2024-11-23 00:36:32 +00:00
Scott Mabin
79ca9d07aa
[2/3] Timer refactor: TIMG (#2581)
* system timer simplfication

* Removes _all_ type params on Alarm
* Systimer no longer implements peripheral ref, the peripheral ref
  pattern is instead intended to be used on the higher level timer
  drivers
* Removed `Unit` as a type, in favour of an enum
* Alarms are back in the main `SystemTimer` "driver"
* Made all `Unit` modification methods unsafe, it's not possible to
  modify the `Unit`'s safely whilst timers and or the `time::now` API is
  in use

* fix examples and tests (by removing them :D)

* changelog and migration

* Review feedback

* changelog and migration

* /unit_count/unit_value/g

* changelog and migration

* /unit_count/unit_value/g

* system timer simplfication

* Removes _all_ type params on Alarm
* Systimer no longer implements peripheral ref, the peripheral ref
  pattern is instead intended to be used on the higher level timer
  drivers
* Removed `Unit` as a type, in favour of an enum
* Alarms are back in the main `SystemTimer` "driver"
* Made all `Unit` modification methods unsafe, it's not possible to
  modify the `Unit`'s safely whilst timers and or the `time::now` API is
  in use

* Make TimerGroup Timer's dumb and untyped

* changelog

* review

* review
2024-11-22 16:14:14 +00:00
Dániel Buga
e98674e8fa
[DMA 6/8] More helper types & working split (#2532)
* Add helper traits to simplify DMA channel trait bounds

* Document changes

* Update doc example

* Remove clutter from MG

* Move DmaEligible down to place helper types closer

* Rename

* Include split in the MG
2024-11-22 15:59:31 +00:00
Dániel Buga
c1f0c134c3
Use a separate lock in esp-println (#2567) 2024-11-22 12:29:26 +00:00
Dániel Buga
b5775667b4
[DMA 5/8]: Clean up macros (#2527)
* Deduplicate PDMA channel impl macro

* Explicitly provide AnyDma prefix, regblock and compatible peripherals

* Clean up defining interrupt handlers

* Clean up ad-hoc ignore macro branches
2024-11-22 11:28:41 +00:00
Scott Mabin
60a2c76005
[1/4] Timer refactor: system timer (#2576)
* system timer simplfication

* Removes _all_ type params on Alarm
* Systimer no longer implements peripheral ref, the peripheral ref
  pattern is instead intended to be used on the higher level timer
  drivers
* Removed `Unit` as a type, in favour of an enum
* Alarms are back in the main `SystemTimer` "driver"
* Made all `Unit` modification methods unsafe, it's not possible to
  modify the `Unit`'s safely whilst timers and or the `time::now` API is
  in use

* fix examples and tests (by removing them :D)

* changelog and migration

* /unit_count/unit_value/g

* etm doctest

* Review feedback
2024-11-22 11:24:06 +00:00
Dániel Buga
9c1d99d9b4
Don't read to clear interrupts (#2585) 2024-11-22 10:55:53 +00:00
Dániel Buga
3a4a7632b1
[DMA 4/8]: Apply Peripheral pattern (#2526)
* Create DMA Channels inside peripherals

* Add PARL_IO into_async functions

* Update tests and examples

* Restore configurable priority via DmaChannel

* Add mode param to DPI driver

* Fix test by raising SPI frequency

* Fix split

* Changelog

* Update esp-hal/CHANGELOG.md

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-11-22 09:05:22 +00:00
Dániel Buga
f81b5f6c7f
Run a custom script before running HIL tests (#2580)
* Do not cycle USB power

* Call a script before running tests
2024-11-21 15:17:35 +00:00
Dániel Buga
973671c3cb
[DMA 3/8] Remove ChannelCreator types, temporarily disable burst mode (#2403)
* Remove ChannelCreator types and burst mode

* Fix up I2sParallel

* Always enable burst transfering descriptors

* Configure burst transfer with a non-bool for future chip support

* Reuse buffer preparation code

* Update LoopBuf as well

* Update lcd_cam tests

* Rename config, fix changelog
2024-11-21 15:01:29 +00:00
Björn Quentin
f9203dc523
Disable peripherals when unused (#2544)
* Disable peripherals when unused

* Fixes

* CHANGELOG.md

* Fix

* Address review comments

* Have dedicated guards for CAM and LCD

* Re-use `Cam`'s guard

* De-duplicate, assert

* fmt

* Require CriticalSection

* Address comments

* Remove redundant guard

* Use `GenericPeripheralGuard`

* Renaming
2024-11-21 09:21:28 +00:00
Dániel Buga
457ed44802
Slight cleanup throughout (#2575)
* Slight cleanup throughout

* Explain empty build script
2024-11-21 09:06:49 +00:00
Jesse Braham
02ddad47c0
Add new migration guides (#2571) 2024-11-21 09:05:33 +00:00
Dániel Buga
a824963943
Avoid old API in SPI example in migration guide (#2578) 2024-11-21 08:25:33 +00:00
Scott Mabin
2fc10d684c
API guideline touchups (#2573)
* guideline touchups

* review comments
2024-11-21 07:41:26 +00:00
Dominic Fischer
8600c4009f
ESP32-S3: Added SDMMC signals (#2556)
* ESP32-S3: Added SDMMC signals

* fmt

* Daniel's request

* changelog

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-11-20 21:49:24 +00:00
Jesse Braham
3c1aba5088
Add --no-verify for esp-riscv-rt to xtask publish (#2570) 2024-11-20 10:44:24 +00:00
Jesse Braham
bdfec3781f
New package releases (#2569)
* New package releases

* Update `CHANGELOG.md` for all packages to be published
2024-11-20 09:16:33 +00:00
Dániel Buga
73a6e32971
Add pin driver examples, explain drivers a bit better (#2563)
* Add pin driver examples, explain modes

* Remove redundant blinky mention

* Wireless keyboard strikes agan

Co-authored-by: Sergio Gasquez Arcos <sergio.gasquez@gmail.com>

* Add println macro to before_snippet

---------

Co-authored-by: Sergio Gasquez Arcos <sergio.gasquez@gmail.com>
2024-11-19 13:53:12 +00:00
Dániel Buga
432622ca9f
Clarify embassy migration guide (#2565) 2024-11-19 13:31:43 +00:00
Dániel Buga
70fe8fb077
Remove some unnecessary prelude reexports (#2564)
* Remove some unnecessary prelude reexports

* Fix test
2024-11-19 13:31:08 +00:00
Dominic Fischer
7821968df8
Introduce RGB/DPI driver (#2415)
* Introduce RGB/DPI driver

* Choose different pin for HIL test

* fail

* Use official devkit

* merge update

* non_exhaustive

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-11-19 10:15:09 +00:00
Dániel Buga
26fd1a40d9
Avoid polling for no reason (#2551) 2024-11-19 07:58:02 +00:00
Scott Mabin
9c06c69600
Touch up the migration guide for esp-wifi (#2561) 2024-11-18 14:41:11 +00:00
Dániel Buga
4f6d51fefa
Add missing Sealed impl (#2560)
* Add missing Sealed impl

* Typos

* It compiles
2024-11-18 14:15:40 +00:00
Jesse Braham
2472e36232
Add the qa-test package (#2558)
* Teach `xtask` about the `qa-test` package

* Create the `qa-test` package and move some examples to it

* Check `qa-test` package in CI

* Add `README.md`
2024-11-18 11:00:17 +00:00
Dániel Buga
c6404fe569
Forget our problems (#2541) 2024-11-14 15:30:48 +00:00
Jesse Braham
d68550c485
Add a publish subcommand to the xtask (which performs a dry-run by default) (#2539)
* Update and reorganize xtask dependencies

* Add a publish subcommand (which performs a dry run by default)

* Update xtask/src/main.rs

Co-authored-by: Sergio Gasquez Arcos <sergio.gasquez@gmail.com>

---------

Co-authored-by: Sergio Gasquez Arcos <sergio.gasquez@gmail.com>
2024-11-14 11:27:30 +00:00
Dániel Buga
52c65dd149
[DMA 2/N] Split DMA IN/OUT handlers (#2521)
* Separate IN/OUT handlers

* Split DMA IN/OUT handlers

* Reset channel async status when re-creating

* Remove resolved TODO

* Hide Cpu iterator functions
2024-11-14 10:49:16 +00:00
Jesse Braham
64f4fea403
Remove some examples which are adequately covered by documentation (#2538) 2024-11-14 09:32:18 +00:00
Dániel Buga
38dde2ebbd
[DMA 1/N] Add mode to DMA channel drivers (#2519)
* Add mode to DMA channel drivers

* Swap dma Channel CH and DM

* Fix copy-paste mistake
2024-11-14 08:03:05 +00:00
Jesse Braham
959631ee55
Fix nightly lint errors (#2537) 2024-11-14 07:59:55 +00:00
Jesse Braham
014a04faad
Use correct toolchain when building documentation or running doctests via xtask (#2536)
* Add an alias for `fmt-packages` (since I always get this wrong)

* Use correct toolchain when building documentation or running doc tests
2024-11-14 07:38:50 +00:00
Jesse Braham
f3346a80b9
Update documentation to recommend esp-generate instead of esp-template (#2535)
* Update documentation to recommend `esp-generate` instead of `esp-template`

* Hide the `trm_link` macro in the documentation
2024-11-14 07:32:10 +00:00
Jesse Braham
c19c7fcf01
Remove get_core() in favour of Cpu::current() (#2533)
* Remove `esp_hal::core()` in favour of `Cpu::current()`

* Update migration guide

* Update `CHANGELOG.md`
2024-11-13 16:13:47 +00:00
Jesse Braham
92b91257e9
Remove get_ prefix from functions (#2528)
* Remove `get_` prefixes from functions

* Update migration guides for `esp-hal` and `esp-wifi`

* Update `CHANGELOG.md` files
2024-11-13 15:40:26 +00:00
Dániel Buga
b11fc0fce8
Remove NoClkPin (#2531) 2024-11-13 15:07:55 +00:00
Jesse Braham
099e0eacdf
Use newest published PACs (#2530) 2024-11-13 15:06:22 +00:00
Dániel Buga
b538e48ea4
Fix RMT test (#2529) 2024-11-13 13:52:11 +00:00
Björn Quentin
7da4444a7e
Fail RMT one-shot transactions if end-marker is missing (#2463)
* Fail RMT one-shot transactions if end-marker is missing

* CHANGELOG.md

* Add test

* Fix

* Fix

* RMT: use u32, turn PulseCode into a convenience trait

* Clippy

* Adapt test
2024-11-13 11:29:36 +00:00
Dániel Buga
8cbc249e2e
I2c: attempt empty writes (#2506)
* Attempt 0-length writes

* Deduplicate

* Changelog

* Test existing address

* Name addresses

* Fix formatting
2024-11-13 09:57:30 +00:00
Easyoakland
30276e1609
implement wifi event handling with data (#2453)
* implement event handling for apsta{,dis}connect and probe

add to wifi_access_point example

* hide internal `Option` to simplify api

* move handler call logic to event.rs

* update_handler_leak

* - Add comments

- match simpler api from `std::panic::update_hook`

- do not assume size_of in prelude

- make all events handleable

- box static instead of leak

* update changelog

* elide lifetime on default handler

* newtypes for all event types.

* add doc to newtypes

* fix previous doc example

* - `get_handler` -> `handler`
- pass critical section to event handlers
- comment on perf of Box<ZST>
- don't pass `prev` in `update_handler`, instead call previous handler first unconditionally

* pass cs to dispatch_event_handler

* don't print "unhandled event" for handled events.
2024-11-13 08:49:41 +00:00
Dominic Fischer
456bcfb7c6
Remove redundant Enable trait (#2523)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-11-13 08:26:18 +00:00
Björn Quentin
0b452f7933
C6/H2 Make higher LEDC frequencies work (#2520)
* ESP32-C6/H2: Make higher LEDC frequencies work

* FMT

* CHANGELOG.md
2024-11-13 08:11:01 +00:00
Dániel Buga
5d9cc1a588
Add ESP32-S2 alternate functions (#2512) 2024-11-12 12:18:16 +00:00
Björn Quentin
5d120f7a70
Remove the integrated blocking networking stack (#2488)
* Add simple example using `smoltcp-nal`

* Remove the blocking networking stack

* Renaming

* Fix CI

* CHANGELOG.md

* Fixes after re-base

* Update esp-wifi/MIGRATING-0.10.md

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

* Improve diff in migration guide

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-11-12 11:43:01 +00:00
Dániel Buga
6cb5d9643f
Deduplicate impl, chunk data in ehal transaction Operations (#2481) 2024-11-12 10:49:30 +00:00
Dániel Buga
fbc57542a8
Remove pins from Io (#2508)
* Split pins off of Io

* Remove the GPIO peripheral

* p.GPIO
2024-11-12 10:36:25 +00:00
Jesse Braham
321ca2f131
Add CHANGELOG.md for remaining packages which do not have one (#2518)
* Add `CHANGELOG.md` for remaining packages which do not have it

* Update `changelog` workflow to check all relevant packages
2024-11-12 10:17:11 +00:00
Jesse Braham
cf10f07a9e
Add validation to esp-config (#2475)
* Clean up and re-organize `lib.rs` a bit (sorry)

* Add configuration validation, some other refactoring/improvements

* Add a built-in range validator, re-document the `generate_config` function

* Update build scripts to reflect new configuration API
2024-11-12 10:14:14 +00:00
Jesse Braham
57fc5df858
Modify bump-version subcommand to also bump dependent packages' dependencies (#2514) 2024-11-12 07:08:32 +00:00
Jesse Braham
33659380dd
Update revision of PACs and fix all build errors (#2515) 2024-11-11 21:27:50 +00:00
Dániel Buga
4af44b1498
Introduce Driver and move implementation into it (#2480) 2024-11-11 15:43:07 +00:00
Dániel Buga
2c14e595db
I2C: add apply_config, implement SetConfig, add with_sda and with_scl (#2477)
* Implement apply_config, SetConfig

* Remove pins from constructors

* Implement timeout changes, document them

* Fix up changelog
2024-11-08 22:51:42 +00:00
Dániel Buga
e10ae2ddff
GPIO: do not overwrite interrupt handler (#2486)
* Prefer defmt unwrap

* Auto-bind the GPIO interrupt handler

* Changelog

* Bind interrupt handler when initializing the hal

* Remove user handler overhead unless user handler is bound

* Add tests

* Try to preserve direct-bound handlers

* Fix match

* Don't rely on the vector table to check direct binding

* Fix comment
2024-11-08 17:04:06 +00:00
Sergio Gasquez Arcos
7402ad61ed
Expose CSI API in esp-wifi (#2422)
* feat: (WIP) add CSI api

* feat: Enable G_CONFIG.csi_enable and update example

* fix: Allow user to set the dessired cb method

* fix: Clippy warnings

* fix: Add missing doccomments

* feat: Add csi_enable config

* refactor: Update CsiConfiguration c6 struct

* feat: Create set_csi WifiController and EspNowManager methods

* docs: Update changelog

* refactor: Rename CsiConfig struct

* docs: Document c6 version of CsiConfig

* feat: impl From<CsiConfig> for crate::include::wifi_csi_config_t

* style: Rustfmt

* docs: Fix comment

Co-authored-by: Dániel Buga <bugadani@gmail.com>

* docs: Fix typo

Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>

* feat: Enable CSI on examples by default

* feat: Handle errors

* style: Rustfmt

* feat: Update error

* feat: Panic if csi config is not enabled

* feat: Cfg CSI stuff when CSI is disabled instead of panicing

* fix: Clippy lints

* feat: Fix signed bitfields

* feat: Pass the cb via ctx

* feat: Update CSI callback to use closures

* refactor: Rename promiscuous_csi_rx_cb to csi_rx_cb

* feat: Move extra boxing inside set_receive_cb

* feat: Refactor CSI callback to use generic types

* refactor: Remove Sized bound from CsiCallback trait

* feat: Add csi_enable field to EspWifiConfig and update CsiCallback trait for conditional compilation

* feat: Remove unnecessary boxes

* feat: Update callback type in set_csi to require Send trait

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

---------

Co-authored-by: Dániel Buga <bugadani@gmail.com>
Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>
Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-11-08 16:33:13 +00:00
Björn Quentin
3c4b7f0f66
Test more embassy interrupt spi dma (#2490)
* Add C3,C6 and H2 for `embassy_interrupt_spi_dma`

* Test more

* Don't require physically connected pins
2024-11-08 13:43:34 +00:00
Scott Mabin
50d8187e39
esp-wifi: Remove unneeded features (#2446)
* remove async features

* phy-usb config

* modem powersaving

* Fix examples

* make ps a runtime config

* fix linting

* changelog and migration guide

* revert esp-config changes

* remove blanklines after doc comments

* cfg away ps API
2024-11-08 13:30:33 +00:00
Dániel Buga
6d6f6a7baa
Move I2C driver to i2c::master (#2476)
* Move I2C driver to i2c::master

* Update esp-hal/CHANGELOG.md

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-11-08 12:28:53 +00:00
Dániel Buga
31d714a156
Tweak guidelines (#2482)
* Tweak guidelines

* Restore builder rule

* Address review comments
2024-11-08 11:50:52 +00:00
Dániel Buga
ac4679a1ae
Remove public hidden I2C APIs (#2474) 2024-11-08 10:37:13 +00:00
Dominic Fischer
d6f63d67a9
Fix I8080.set_byte_order() (#2487)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-11-08 08:01:36 +00:00
Dániel Buga
d5e6ba5ceb
SPI slave with_pin functions (#2485) 2024-11-08 07:29:37 +00:00
Dániel Buga
4233bddf23
Fix test warnings (#2483) 2024-11-07 15:05:49 +00:00
yanshay
639853ede9
Add MultiwriteNorFlash trait to FlashStorage (#2478)
* Add MultiwriteNorFlash trait to FlashStorage

* add PR number

* Revert "add PR number"

This reverts commit 28bf0acd24.

* Added changelog with PR number
2024-11-07 13:58:32 +00:00
Dániel Buga
ac819fb42f
Remove PeripheralMarker (#2468)
* Redo DMA compatibility check using DmaEligible

* Remove PeripheralMarker
2024-11-07 13:51:48 +00:00
Dániel Buga
8782429e9f
SPI slave: remove public hidden API (#2470)
* Redo declaration as macro

* Add Info

* Move impl out of Instance traits

* Publish traits
2024-11-07 09:41:16 +00:00
Dániel Buga
0da6eec089
Move I2S drivers to i2s::master and i2s::parallel (#2472)
* Move I2S drivers to i2s::master and i2s::parallel

* Remove mention of master mode
2024-11-07 09:39:08 +00:00
Dániel Buga
feac6f17c3
Mark State/Info as #[non_exhaustive] (#2471) 2024-11-07 09:37:56 +00:00
Dániel Buga
255f5e7c73
TWAI: Always configure a default filter (#2467) 2024-11-06 14:11:49 +00:00
Dániel Buga
4c5be2c907
Interconnect: force signals through GPIO matrix if split (#2419)
* Allow splitting off of gpio drivers

* Extract and correct low level connection bits

* Add Input/OutputSignal::connect_to

* Remove unnecessary public API

* Fix typos

* Remove unused private methods

* Add separate Direct signals that do bypass the GPIO matrix

* Do not disable stage input

* Clean up spi_slave test

* Constrain to static Flex

* Improve docs

* Separate input_enable and open_drain parameters

* Link to the chapter

* Changelog

* Clarify
2024-11-06 13:55:34 +00:00
Björn Quentin
ccb3a1ba40
Use diagnostic on DmaChannelConvert (#2465)
* Use `diagnostic` on `DmaChannelConvert`

* Typo
2024-11-06 11:43:25 +00:00
Dániel Buga
8860aba9b2
Spi master: remove public hidden APIs, add Config/apply_config (#2448)
* Remove hidden public SPI API

* Fix in_progress flags not being set

* Remove redundant checks, fix full-duplex flag

* Remove now-redundant Send impl

* apply_config

* SetConfig

* Return ConfigError

* Unwrap config result in ctor
2024-11-06 09:03:43 +00:00
Dániel Buga
eabb6fb1c6
ETM improvements (#2427)
* ETM simplifications

* Work with GPIO signals

* Fix changelog
2024-11-05 13:39:19 +00:00
Dániel Buga
665fb0e278
Flatten Uart module, remove unnecessary data, replace methods with apply_config (#2449)
* Flatten uart config

* Do not remember at_command config

* Don't save config values in memory

* Move config implementations to Info

* Changelog

* Remove unused methods

* apply_config, SetConfig

* Fix test

* simplify futures

* Update esp-hal/CHANGELOG.md

Co-authored-by: Sergio Gasquez Arcos <sergio.gasquez@gmail.com>

---------

Co-authored-by: Sergio Gasquez Arcos <sergio.gasquez@gmail.com>
2024-11-05 09:56:14 +00:00
Dániel Buga
ed7960ce8b
Also add into_async for ParlIO (#2461) 2024-11-04 16:00:21 +00:00
Björn Quentin
ca9ee23b5e
Prefer ROM-fns over custom impl (#2462)
* Prefer ROM-fns over custom impl

* PR number
2024-11-04 15:55:23 +00:00
Dániel Buga
1e6820d1a7
Systimer improvements (#2451)
* Do not read to set update bit

* Deduplicate

* Try to bind interrupts to the correct core

* Inline poll_count into read_count

* Clean up

* Make sure only a single update is done at a time

* Changelog

* Fix docs

* Correct the channel count

* Assign enough timers for HIL test

* Use a lock to prevent re-update

* Remove locking, use esp-idf implementation

* Document timer count requirement
2024-11-04 11:36:34 +00:00
Dániel Buga
0c86740418
Peripheral interconnect redo, vol 2 (split()) (#2418)
* Replace peripheral connection conversions with split

* Constrain Flex conversions
2024-11-04 11:29:28 +00:00
Dániel Buga
177db100fb
Remove redundant lifetimes (#2459) 2024-11-04 10:51:12 +00:00
Dániel Buga
40c0a6944e
into_async (#2430)
* Remove configure_for_async

* Add into_async and into_blocking to I2c

* Add into_async and into_blocking to UsbSerialJtag

* Rework LCD_CAM

* Rmt

* RSA

* TWAI

* Uart

* Documentation

* Disable interrupts set on other core

* Move configure into RegisterAccess

* Disable interrupts on the other core

* Use EnumSet in RMT
2024-11-04 09:32:12 +00:00
Scott Mabin
c717f04d4d
Remove EspWifiInitFor & more granular init/deinit per driver (#2301)
* More granular init and deinit per driver

- Rework EspWifiInit
- No longer require EspWifiInitFor
- Add Drop impls for each driver, and add Drop for EspWifiController to
  fully deinit the stack

* unwrap! more stuff

* fixup examples and esp-now

* unwrap less stuff

* review feedback

* seal wifi traits, allow rng or trng to init esp-wifi

* changelog and migration guide

* return wifi error in esp now constructor instead of panic
2024-11-04 08:08:19 +00:00
Dominic Fischer
f9ba299f2e
Mark DmaDescriptors as Send (#2456)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-11-04 07:50:44 +00:00
Dominic Fischer
05f2ee5a72
Allow users to create DMA Preparations (#2455)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-11-04 07:38:46 +00:00
Dominic Fischer
b953f178b8
Add check owner support to DMA buffers (#2337)
* Add check owner support to DMA buffers

* More docs

* Explicit check owner bit setting

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-11-02 16:07:40 +00:00
Dániel Buga
111ae93cc5
Fix, clean up and type-erase parallel i2s (#2436)
* Fix, clean up and type-erase parallel i2s

* Fix capitalization

* Add link to esp-idf code that offsets by 8
2024-11-01 10:50:39 +00:00
Jesse Braham
fc4eaa1ebf
Make our nightly CI checks pass (#2356)
* Fix nightly lint errors for ESP32-C2

* Fix nightly lint errors for ESP32-C3

* Fix nightly lint errors for ESP32-C6

* Fix remaining nightly lint errors
2024-11-01 10:31:56 +00:00
Dániel Buga
a5c4aa1cea
Tweak interrupt API (#2442)
* Tweak interrupt API

* Constrain SPI interrupt handling to Blocking mode
2024-10-31 16:18:44 +00:00
Dániel Buga
7d717c6acf
Fix UART erratum on ESP32 (#2441) 2024-10-31 15:00:36 +00:00
Dániel Buga
f9c7d06a6e
Disable i2s test (#2439) 2024-10-31 14:16:39 +00:00
Björn Quentin
e5b923b678
Esp wifi/more dynamic allocations (#2396)
* Dynamic allocation of timers

* Replace statically allocated NPL events

* Remove NPL CALLOUTS

* Remove NPL EventQueue

* Use `Vec` instead of `heapless::spsc::Queue` internally in NPL

* Use `alloc` since we have it in NPL

* Refactor

* Fix

* More `Vec`

* Fix

* Fix nightly-warnings

* Limit RX_STA queue

* Revert unintentional change

* esp-now: Make data private

* CHANGELOG.md

* Clippy

* MSRV

* Move locking into RawQueue

* Remove unused import

* Simplify `queue_recv`

* Address TODO

* Clippy

* Review I

* Review II

* Clarify

* Review III

* Review IV

* Review V

* Fix

* `steal` RNG and RADIO_CLOCKS

* `drop_in_place`

* De-duplicate

* Use `VecDeque`

* Revert unintentional changes

* Fix

* Update esp-wifi/MIGRATING-0.10.md

Co-authored-by: Dániel Buga <bugadani@gmail.com>

* assert

* Fix

* Expect `*mut ConcurrentQueue` where applicable

* Comment why stealing is fine

* Fix

---------

Co-authored-by: Dániel Buga <bugadani@gmail.com>
2024-10-31 12:26:10 +00:00
Jesse Braham
6fa2823e10
Use latest PAC which aligns TWAI field names (#2438) 2024-10-31 12:22:37 +00:00
Dominic Fischer
25d8390d68
Fix typo in migration guide (#2435) 2024-10-31 06:43:11 +00:00
liebman
448ed9a001
implement a parallel interface for esp32 using the i2s peripheral (#2348)
* i2s_parallel for esp32 - partially working

* i2s_parallel for esp32 - works sync 16bit (still WIP)

* i2s_parallel - add 8-bit

* i2s_parallel - naive async implementation

* i2s_parallel - clippy

* add examples (mainly for testing now and we can reduce these before merge)

* set tx_wrx2 in 8 bit mode or it updates on half clocks!

* adjust clock config (still really a hack)

* better clock calculation/configuration

* no need to reset dma or interrupts in start, the DMA DmaTxBuf handles that

* seems to need a short delay during tx_reset

* use 20 clocks instead of 1us

* 1us delay between dma start and tx_start (like idf)

* changelog & documentation

* remove debugging functions

* no need for option in example

* make async example actually use async & remove Option

* implement Drop for I2sParallelTransfer

* fix signal offset comment for I2S0

* small cleanup in i2s_parallel examples

* added a note re I2S0 not supporting true 8bit

* update doc & fmt

* instace functions take &self

* fmt

* if run at 240MHz (CPU) delay needs to be bigger

* wait for fifo on start and fixes for 240MHz

* update for esp-hal-changes

* fmt

---------

Co-authored-by: Dániel Buga <bugadani@gmail.com>
2024-10-30 18:55:47 +00:00
Tu Nguyen
9d4b8fdbc6
[TWAI] bus-off error is never reached when using transmit_async (#2421)
* cancel pending tx request when error is from tx

* fix format error

* update CHANGELOG.md
2024-10-30 16:59:11 +00:00
Björn Quentin
05a1ebead3
Use esp-wifi-sys from Git (#2426)
* Use esp-wifi-sys from Git

* Update esp-wifi-sys rev
2024-10-30 16:38:16 +00:00
Björn Quentin
416c1481ae
Circular dma improvements (#2409)
* Check for error when pushing into a circular dma transaction too late

* Adapt tests

* Adapt example

* Don't block forever if trxing to pop from a circular DMA transfer too late

* Have a dedicated error for circular-DMA reading/writing too late

* Stop I2S RX before resetting it

* Migration guide

* Address review comment, make CI pass

* Adopt ideas from review

* Fix

* Update esp-hal/MIGRATING-0.21.md

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

* assert

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-10-30 16:25:29 +00:00
Dániel Buga
4546f861c8
Reduce UART Instance trait to the bare minimum (#2410)
* Merge signal fns

* Remove logic from UART Instance, remove uart_number

* Use the unwrap macro

* Place peripheral info into static structs

* Clean up

* Clean up

* Update todo

* Rename

* Separate out state
2024-10-30 15:51:33 +00:00
Dániel Buga
a8fedf0130
Move some implementation details out of GPIO (#2429)
* Move macros out of gpio

* Align S2 impl
2024-10-30 15:11:48 +00:00
Kirill Mikhailov
3e42b76993
Add an option to configure WDT action (#2330)
* WIP

* revert example

revert config

* changelog entry

* Make `RWDT` API work correctly, make `RWDT` and `MWDT`APIs same

* update documentation code

oops

* rev

* Polishing

* Document bootloader limitation

+ typo fix

* Address reviews

* fix documentation examples
2024-10-30 09:46:34 +00:00
Dániel Buga
f07e25c970
Add option to disable waiti (#2329) 2024-10-30 08:12:15 +00:00
Björn Quentin
b7224ef4c9
RISC-V: Fix interrupt stack alignment (#2425) 2024-10-29 11:45:30 +00:00
Dániel Buga
8a23dbe1b6
Modernize UART interrupts (#2406)
* Modernize UART interrupts

* Also derive Debug and Format for interrupt enums

* Fix changelog

* Touch up API-GUIDELINES
2024-10-28 09:07:15 +00:00
Dániel Buga
4e257f74aa
Merge/remove some GPIO-related macros (#2404)
* Remove redundant macros

* Deduplicate rtcio dispatch macros

* Clean up unnecessary import

* Remove manual bank assignment
2024-10-28 07:08:53 +00:00
Dániel Buga
f3c5286028
Add Cpu::COUNT and clean up in esp-hal-embassy (#2411)
* Add Cpu::COUNT and simplify

* Avoid a bounds check during pending
2024-10-26 13:36:10 +00:00
Dániel Buga
6bf03f63a9
Small SPI slave cleanup (#2405) 2024-10-25 15:07:43 +02:00
Dániel Buga
681f4ef0aa
Implement UART type erasure (#2381)
* Simplify test

* Remove unnecessary refs

* Improve readability

* Require Instance: PeripheralMarker

* Take &self

* Avoid unsafe code on non-s2

* SImplify drain_fifo

* Simplify read_bytes

* Avoid a register read on ESP32

* Deduplicate is_idle functions

* Add missing inlines

* Move code out of trait

* Erase UART instances

* Disable LTO
2024-10-25 08:03:20 +00:00
Dániel Buga
561b582a80
Overhaul peripheral signal system, first run (#2388)
* Remove redundant bound

* Remove redundant Dummy variant

* Make PeripheralOutput extend PeripehralInput

* Rename AnyInputSignal to InputConnection

* Add OutputConnection

* Convert into type-erased interconnect conections

* Clean up LCD/CAM

* Document changes

* Review changes

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

* Clean up

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-10-25 07:01:45 +00:00
Dániel Buga
19b08efc1d
Rework how pin capabilities are declared (#2400) 2024-10-24 11:55:46 +00:00
Björn Quentin
a7d8b2009d
Use panic instead of process::exit (#2402) 2024-10-24 11:06:05 +00:00
Dániel Buga
2ac47868f7
Remove FullDuplexMode and HalfDuplexMode type params (#2373)
* Remove duplex type param

* Rename dma_ functions
2024-10-24 07:22:21 +00:00
Dániel Buga
f03527f6fc
Change example to set max clocks (#2399)
* Change example to set max clocks

* Update esp-hal/src/lib.rs

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-10-24 07:18:29 +00:00
Dániel Buga
c163b0586a
Erase TWAI (#2359)
* Swap order of generics

* Don't refer to Instance in irq handler

* Deduplicate a bit

* Take &self

* Reduce nesting

* Erase TWAI instance
2024-10-24 06:47:02 +00:00
Easyoakland
1de2483609
fix wifi async fn disconnect hanging if not connected when called (#2392)
* fix wifi async fn disconnect hanging if not connected when called

* update changelog

* clarify comment

* add pr number to changelog
2024-10-23 21:29:00 +00:00
Dániel Buga
5f6ca8d252
Fix embassy migration guide (#2393) 2024-10-23 13:49:20 +00:00
Dániel Buga
4c1c6131df
Wait more before re-enabling USB power (#2397) 2024-10-23 12:56:59 +00:00
Dániel Buga
71c4fc5a24
Add note to start_app_core (#2395) 2024-10-23 08:54:53 +00:00
Dániel Buga
5486cdb5e3
Clean up i2c add_cmd (#2394) 2024-10-23 08:44:30 +00:00
Dániel Buga
e367c83bde
Erase i2c peripheral instances (#2361)
* Clean up

* Erase I2C instance type

* Clean up

* Implement Peripheral

* Changelog

* Remove with_timeout constructors
2024-10-23 06:31:08 +00:00
Dániel Buga
1afc9eef89
Remove unnecessary generic from ChannelHW (#2387)
* Remove unnecessary generic from ChannelHW

* Changelog
2024-10-22 15:41:42 +00:00
Björn Quentin
54d4407042
Better align atoi to what the C-library does (#2380)
* Better align `atoi` to what the C-library does

* Address review comments

* Clippy

* More clippy

* Prefer `read` over `read_volatile`
2024-10-22 14:55:24 +00:00
Dániel Buga
632bbc6461
Fix interrupt executors waking up thread-mode executors on the first core (#2377)
* Clean up

* Add failing multi-core test

* Reset interrupts before main

* Changelog

* Add test case
2024-10-22 14:45:06 +00:00
Dániel Buga
aec83bdd31
GPIO cleanup (#2384)
* Return alternate function maps as slices

* Prefer steal() over ptr deref

* Clean up rtc_io
2024-10-22 12:56:45 +00:00
Jesse Braham
56cd5a288f
Update PACs to latest git revision (#2383)
* Update to latest git revision of all PACs

* Update RSA module to reflect changes in PACs

* Update TWAI module to reflect changes in PACs

* Further simplification
2024-10-22 12:33:36 +00:00
Björn Quentin
c574834ae3
Include ROM API symbols (#2374)
* Include ROM API symbols

* Fixes and CHANGELOG.md

* Fix

* Move migration steps to the right crate's migration guide

* Remove `-Trom_functions.x` where necessary
2024-10-22 10:02:49 +00:00
dimpolo
62ee60d43f
Fix conflict between RtcClock::get_xtal_freq and Rtc::disable_rom_message_printing (#2360)
* deduplicate some code in rtc_cntl

* mask out the RTC_DISABLE_ROM_LOG bit when reading RTC_XTAL_FREQ
2024-10-22 08:35:46 +00:00
Dániel Buga
a4bc0536a3
PAC update (#2378)
* PAC update

* Inline steals into reg expressions
2024-10-22 06:41:33 +00:00
Dániel Buga
d914a0301f
Erase i2s (#2367)
* Implement I2S type erasure

* Clean up
2024-10-22 06:33:27 +00:00
Dániel Buga
a754e411b1
SPI type erasure (#2334)
* Move SPI peripheral type to the last position

* Implement AnySpi

* Convert peripheral types

* Add new_typed constructors

* Implement PDMA

* Fix conditional

* Clean up constructors

* Fix test

* Move stuff to utils

* Extract any macros

* Merge PeripheralMarker defs into peripherals macro

* Changelogs

* Implement fn degrade

* Changelog num

* Fix typo

* Rename type-erased dma channel

* Remove degrade fn

* Remove utils

* Explain peripherals macro
2024-10-21 14:03:14 +00:00
Dániel Buga
f2aa3f9863
Update embedded-test (#2375) 2024-10-21 09:35:15 +00:00
Dániel Buga
d32a7336bb
Simplify traits and erratum 36 workaround, add Pins::steal (#2335)
* Simplify erratum 36

* Add Pins::steal

* Fix typo

* Move pin operations into Flex

* Cleanup braces

* Avoid panicking when handling erratum

* Add disable_usb_pad to other devices

* Touch up changelog

* Fix changelog
2024-10-18 14:17:43 +00:00
akesser
326e006335
doc: add hint for feature flag in wifi examples (#2365) 2024-10-18 14:14:21 +00:00
Dániel Buga
f0d0dd92c4
Do not optimise ecc test (#2366) 2024-10-18 14:05:02 +00:00
Björn Quentin
358d884643
Add option to place more .rodata in RAM for performance (#2331)
* Add option to place more `.rodata` in RAM for performance

* Make CI green, again

* Removed unnecessaries

* Split option into two

* Make `place-switch-tables-in-ram` default

* Xtensa

---------

Co-authored-by: Scott Mabin <scott@mabez.dev>
2024-10-18 11:47:12 +00:00
Georges
9d51d1befe
fix doc (#2363) 2024-10-18 10:22:39 +00:00
Kirill Mikhailov
88c4dba9e0
esp-wifi docs improve (#2354)
* Improve esp-wifi docs (WIP)

* Finalize

* Address reviews, make cratewide public functions be `pub(crate)`.

* config -> configure
2024-10-18 08:23:16 +00:00
Dániel Buga
472d5f93e0
Add PeripheralRef::map_into (#2326)
* Add PeripheralRef::map_into

* Update clone_unchecked to take shared self

* Simplify pin erasure
2024-10-16 13:34:11 +00:00
Dominic Fischer
6e2606b367
Add burst transfer support to DMA buffers (#2336)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-10-16 13:25:48 +00:00
Dániel Buga
99a579973a
Preparatory i2s refactor (#2316)
* Take self

* Consolidate signal impls

* Remove traits

* Deduplicate impls

* Seal AcceptedWord

* Changelog

* Migration guide

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-10-16 13:04:00 +00:00
Jesse Braham
39c0baf2c7
New patch release for esp-hal (#2355) 2024-10-16 08:39:49 +00:00
Anthony Grondin
060aa7262c
feat(esp-wifi): Implement serde:{Deserialize, Serialize} for wifi structs (#2346)
* feat(esp-wifi): Implement `serde:{Deserialize, Serialize}` for wifi structs

* Update changelog

* Add missing serde feature for dependencies that supports it.
2024-10-16 07:10:43 +00:00
Dániel Buga
67bc37fb93
Add --fix to lint-packages (#2351)
* Add --fix to lint-packages

* Fix suggestion that breaks clippy
2024-10-15 09:33:15 +00:00
Dániel Buga
f0a361e448
Point to usage examples (#2349) 2024-10-15 09:24:46 +00:00
Dominic Fischer
da9c0b0579
Move mem2mem out of GDMA module (#2323)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-10-15 09:20:36 +00:00
Alexandra Clifford
a15cfe7f21
Make RX queue size configurable (#2324) 2024-10-15 07:38:09 +00:00
Dániel Buga
ef7842fab4
Reimplement blocking trait for async i2c (#2343) 2024-10-14 12:50:37 +00:00
Kirill Mikhailov
0dc8dcf8e2
XTASK: add a way to activate features per chip (docs) (#2287)
* XTASK: add a way to activate features per chip (docs)

* Address reviews
2024-10-14 09:04:38 +00:00
Dániel Buga
7aa8145213
Silence clippy (#2332) 2024-10-11 17:38:42 +00:00
Scott Mabin
e22103d867
fix esp-wifi docs (#2333) 2024-10-10 14:37:56 +00:00
Jesse Braham
d08dc3dcb7
Add new living migration guides (#2327) 2024-10-10 12:44:28 +00:00
Scott Mabin
f29d539a78
Prepare new radio related releases (#2328) 2024-10-10 12:20:52 +00:00
Jesse Braham
5af3d9ddf2
Add missing description field to Cargo manifest for esp-config (#2325) 2024-10-10 10:53:20 +00:00
Jesse Braham
d655fe665f
New package releases (#2310)
* Bump version numbers of all packages to be published, update deps as needed

* Update all `CHANGELOG.md` files

* Update migration guide headings
2024-10-10 10:19:04 +00:00
Dániel Buga
ba8daafb0b
Require float-save-restore in esp-wifi (#2322)
* Add failing test case

* Make sure task contexts are properly initialised

* Require float-save-restore for esp-wifi
2024-10-10 08:24:50 +00:00
Scott Mabin
0142703112
I2c rename, small docs clean up (#2320)
* cleanup prelude docs

* fixups and i2c rename

* changelog and migration

* fixup docs and examples

* fix lint
2024-10-10 07:26:13 +00:00
Dániel Buga
c26600f943
Fix first UART print (#2318)
* Fix first UART print

* Add test case

* Explicitly set level to cause problems
2024-10-09 15:16:56 +00:00
Dániel Buga
f93efa73a9
Clean up warnings (#2317) 2024-10-09 14:53:32 +00:00
Dániel Buga
be9dc0e0b7
Fix restoring of CPENABLE (#2315)
* Add tests Cp0Disabled issue

* Fix saving CPENABLE on context switch

* Fix position shift of registers

* Clean up
2024-10-09 10:33:31 +00:00
Dániel Buga
dc88cb13e8
Reimplement SPI DMA operations in terms of transfer (#2308)
* Reimplement SPI DMA operations in terms of transfer

* Deduplicate reset_dma

* Create empty constructors

* Introduce EmptyBuf

* Fix comment

* Undo unnecessary change

* Remove unnecessary slicing
2024-10-08 23:15:21 +00:00
Dániel Buga
b27482df3c
Mention silent esp-hal-embassy breaking change (#2307) 2024-10-08 15:17:38 +00:00
Dániel Buga
7ca1b4376f
Erase DMA type params (#2261)
* Split PdmaChannel into two

* Take &self in PDMA traits

* Implement type-erased PDMA channels

* Remove Degraded assoc type

* Move degrade fns to base trait

* Use PeripheralDmaChannel on constructors only

* Remove WithDmaAes use

* Erase DMA type params

* Clean up examples/tests

* Remove redundant trait bounds

* Remove peripheral-specific DMA traits

* Document i2s change

* Clean up parl_io

* Deduplicate InterruptAccess

* Fix cfg

* Implement runtime compatibility check

* Clean up a bit

* Document changes

* Swap Channel type params, erase dma channel

* Unsplit traits

* Remove redundant cfg

* Fix docs

* Simplify DmaEligible

* Remove unsafe code

* Revert "Swap Channel type params, erase dma channel"

This reverts commit 415e45e44b297fd3cb55b4261c9ce151cca4b9c9.

* Allow different degraded DMA types

* Allow converting into peripheral-specific DMA channel, use it for compat check

* Erase PDMA types without AnyPdmaChannel

* Hide degrade fns for now, remove from MG

* Clean up SPI slave

* Fix QSPI test

* Fix mem2mem, fix S3 peripherals

* Fix S2

* Remove AnyPdmaChannel

* Remove PeripheralDmaChannel

* Remove unnecessary degrade call
2024-10-08 14:09:27 +00:00
Dániel Buga
f26eef646a
Remove current_millis (#2304) 2024-10-08 14:04:59 +00:00
Björn Quentin
81f93698b0
Remove unused dependencies (#2306) 2024-10-08 13:49:49 +00:00
Dániel Buga
3a9abca148
Slight TWAI corrections (#2288)
* Fix ESP32 baud rate prescaler bit

* Explicitly disable CLKOUT

* Fix brp

* Loop example

* Clean up

* Impl traits for BaudRate

* Fix H2 125k

* Avoid self-receiving transmitted frames

* Fix self-reception flag

* De-CAN

* CI, more defmt impls

* Explain raw bit manipulation

* Fix spelling
2024-10-08 13:32:22 +00:00
Scott Mabin
08030d5541
bump all semver compatible deps (#2303) 2024-10-08 12:56:30 +00:00
Björn Quentin
ca5e8560bf
Replace ESP_LOGLEVEL and ESP_LOGFILTERby ESP_LOG (#2291)
* Replace `ESP_LOGLEVEL` and `ESP_LOGFILTER`by `ESP_LOG`

* CHANGELOG.md

* Clippy

* Fail build if using the now unsupported env variables
2024-10-08 08:53:42 +00:00
Björn Quentin
038d07f5b6
Use relevant features when building documentation (#2295)
* Use relevant features when building documentation

* CHANGELOG.md and migration guide

* Fix imports
2024-10-08 07:31:56 +00:00
Dániel Buga
16f277915b
Remove redundant feature (#2297) 2024-10-08 07:31:47 +00:00
dimpolo
754d8aa585
Fix typo (#2292)
Sorry 😅
2024-10-07 16:19:24 +00:00
Dániel Buga
af3f892381
ESP32 spi slave mode (#2278)
* Enable test on ESP32

* Enable module on ESP32

* Add ESP32 signal map

* Change pins

* Remove unknown signals

* Return to low level in test

* Fix bitlength

* Merge enable and reset

* Impl debug traits on DMA flags

* Disallow mods 0 and 2

* Docs tweaks

* Changelog

* Undo wait change
2024-10-07 15:00:15 +00:00
Dániel Buga
ba96bac776
Clean up impl_dma_eligible (#2290) 2024-10-07 14:39:26 +00:00
dimpolo
f4540a5508
add Rtc::disable_rom_message_printing (#2280) 2024-10-07 14:07:04 +00:00
Dominic Fischer
897a67808c
Add DMA buffer view support to I8080 driver (#2268)
* Add DMA buffer view support to I8080 driver

* reconstruct buffer before dropping

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-10-07 11:53:53 +00:00
Dániel Buga
3e16c5c623
Avoid moving inside SpiDmaBus, abort dropped transfers (#2216)
* Drop State from DMA

* Simplify Error paths

* Cancel dropped transfers, fix and test

* Fix C6

* Avoid cancelling a completed transaction

* Do not implement DmaTxRxBuf for references

* Remove unnecessary import

* Merge BufferRef structs

* Move wait impl to the peripheral

* Allow the current byte to complete

* Restore SpiDmaTransfer::is_done

* Explain cancel code

* Fix test formatting

* Changelog

* Simplify implementation

* Make sure everything gets dropped

* Remove unnecessary PhantomData

* Remove OptionalFuture

* Adjust test to a more realistic clock frequency
2024-10-07 10:04:50 +00:00
Björn Quentin
e5bc63916f
Change debug! to trace! to reduce logging noise (#2284) 2024-10-07 09:29:41 +00:00
Dániel Buga
efe58e94a2
I2C: clean up and remove stop condition from the middle of write_read (#2276)
* Remove I2COperation

* Clean up peripheral reset/enable

* Remove match on peripheral number

* Remove seemingly duplicate register write

* Clippy

* Restore compatibility with slices, publish async transaction

* Maybe with a stop between?

* Add missing inlines

* Read from the correct address

* write_read: don't generate stop after write
2024-10-07 07:29:23 +00:00
Dominic Fischer
62e991d749
Add GPIO Matrix support to Camera driver (#2279)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-10-07 06:20:06 +00:00
Dániel Buga
d3f03042f3
Clean up a bit (#2275) 2024-10-04 12:18:11 +00:00
Kirill Mikhailov
a4fe5e6e63
Adding a way to deinitialize the WiFi stack. (#2187)
* WIP

* cleanup

* WIP (BLE)

* WIP (BLE)

* c2 ble deinit doesn't work with ble alone, works in coex (WIP)

* fmt

* cleanup

* changelog entry

changelog entry

* WIP (do not check it)

 it's just to save things before weekend!

* polishing, refactor

* cleanup

* lint

* Addressing reviews

* address reviews

* utilize `EspWifiInitialization` in deinit

* example -> description

* reviews

* reviews

* fix memory leak + rebase

* typo

* fix

* init -> initialize

screwed up after rebase

* make esp32c6/h2 buildable again

* edit safety comment
2024-10-04 12:16:52 +00:00
Björn Quentin
00ad9b5eed
I2c: Inherent transaction function, lift size limits (#2262)
* I2c: Inherent transaction function, lift size limits

* CHANGELOG.md

* Simplify

* Fix

* Remove unnecessary lifetime

* Remove unused lifetime
2024-10-04 11:53:35 +00:00
Björn Quentin
18da679d8a
esp-wifi: Align default settings (#2251)
* Align esp-wifi defaults with ESP-IDF

* Check we assume the correct wifi-config defaults

* No WIFI-CONFIG for ESP32-H2
2024-10-04 09:34:42 +00:00
Dániel Buga
5a993fed38
Fix Rx/Tx order in SPI slave driver (#2272)
* Add basic test and fix SPI slave dma_transfer arg order

* Reset peripheral

* Add safe way to read signal value
2024-10-04 06:56:34 +00:00
Dániel Buga
c7a2368845
Print test panics using semihosting (#2257)
* Print panic messages using semihosting

* Don't use defmt's asserts

* Make RA_OFFSET available without panic-handler

* Re-add defmt imports where missing

* Revert unintended test change

* Initialise hal in critical-section test

* Disable defmt in tests by default
2024-10-04 06:31:39 +00:00
Dominic Fischer
3e9a506c00
Move DMA buffers to a different file (#2267)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-10-03 11:12:20 +00:00
Dániel Buga
e033162ffd
Clean up (#2266) 2024-10-03 07:02:34 +00:00
Dominic Fischer
30aef580e3
Migrate Camera to a move based API (#2242)
* Migrate Camera to a move based API

* update

* update

* ManuallyDrop

* Add default channel to transfer struct

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-10-02 13:23:14 +00:00
Dominic Fischer
8789ca3c3d
Migrate I8080 driver to a move based API (#2191)
* Migrate I8080 driver to a move based API

* fmt

* comments

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-10-02 13:23:10 +00:00
Björn Quentin
a3304c6cff
Fix eh0.2 set_high/set_low (#2265) 2024-10-02 12:45:11 +00:00
Dániel Buga
f5b8e4b914
Remove SPI slave prelude (#2260)
* Remove SPI slave prelude

* Changelog

* Update esp-hal/src/spi/slave.rs
2024-10-02 06:23:54 +00:00
Dominic Fischer
8e9f6b5015
Erase DMA channel type from Camera and AesDma drivers (#2258)
* Provide AnyDmaChannel

* Erase channel in Camera and Aes

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-10-01 08:11:49 +00:00
Dániel Buga
ed51cd8c35
Only read value types from efuses (#2259)
* Only read value types from efuses

* Changelog

* Clean up remaining bool reads
2024-10-01 08:09:28 +00:00
Dominic Fischer
f1bedbe3dc
Split DMA RegisterAccess trait into RX/TX (#2249)
* Reduce macro usage in PDMA

* Split DMA RegisterAccess trait into RX/TX

* Move set_isr to Ext trait

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-30 13:32:18 +00:00
Dániel Buga
487de0ff22
Round up in delay_nanos (#2256) 2024-09-30 13:23:31 +00:00
Dániel Buga
fcc6375ba5
TWAI: Return error instead of crashing (#2255)
* TWAI: Return error instead of crashing

* Deduplicate interrupt handler
2024-09-30 12:51:27 +00:00
Björn Quentin
b8a4d5f9ff
Remove unused functions (#2254) 2024-09-30 12:07:41 +00:00
Juraj Sadel
11c73caf89
esp-wifi: Remove log feature from default features (#2253)
* esp-wifi: Remove log feature from default features

* changelog
2024-09-30 11:10:58 +00:00
Björn Quentin
fa66a43949
Update drivers (#2239)
* Update drivers

* Fixes

* Changelogs

* Actually remove timers when we should

* Have one waker for all events

* Prefer `swap_remove` over `remove`

* Really implement new coex fucntions for C3/S3

* Real implementation for `coex_schm_flexible_period_set` and `coex_schm_flexible_period_get`

* Mute warnings
2024-09-30 08:40:44 +00:00
Dániel Buga
0981c1b619
SPI peripheral signal cleanup (#2245)
* Compact peripheral description a bit

* Enable QSPI on ESP32 SPI3

* Remove SPI4 from ESP32S2

* Changelog

* Remove inaccurate comment
2024-09-27 17:03:18 +00:00
Dániel Buga
4422ed3ccf
DMA: Deduplicate descriptor operations (#2219)
* Deduplicate descriptor operations

* Reuse constructor

* Reuse linked list construction logic

* Extract count calculations into DescriptorSet

* Reuse more code in DescriptorChain

* Refactor DescriptorChain

* Move DescriptorSet next to DescriptorChain

* Restore comment

* Merge fns

* Implement error conversion

* Further cleanup

* Rearrange some code

* Add some docs

* Clippy

* Restore macro behaviour when requesting 0 descriptors

* Restore the buffer directly, instead of tracking where we read from

* Move validation back into the buffers

* Revert use in dma_tx_buffer

* Rename iterator methods

* Outline eof logic

* Don't set up descriptor flags before time, rename methods

* Hide DescriptorSet

* Remove block size from DescriptorSet

* Move comment

* Fix renamed references

* Address review comments

* Simplify received_data fns
2024-09-27 09:33:26 +00:00
Dániel Buga
f50c6fc071
Only lock once in is_slice_in_psram, use usize (#2241) 2024-09-27 08:06:46 +00:00
Dominic Fischer
66f6737697
Mark DMA buffer traits as unsafe to implement (#2213)
* Mark DMA buffer traits as unsafe to implement

* update doc

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-27 08:02:35 +00:00
Dominic Fischer
00d892b214
Add stop_transfer method to DMA driver (#2236)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-26 16:22:57 +00:00
Dániel Buga
c481c49888
Fix incorrect QSPI setup (#2231)
* Fix QSPI mode on non-ESP32

* Update tests to count pulses on pins separately

* Fix ESP32 addressing phase issue

* Use defmt's assert

* Set fastrd bit

* Apply pulldowns to define signal level when not driven

* Transfer address bits in data phase on ESP32

* Changelog

* Use a separate buffer for the address, make the workaround configurable

* Remove now-unnecessary additions

* Force SpiDma to remain Send

* Clarify wording, remove prefix

* Clean up manual register manipulation

* Fix byte order
2024-09-26 15:28:18 +00:00
Dominic Fischer
4377ec083f
Make DmaDescriptor methods public (#2237)
* Make DmaDescriptor methods public

* clippy

* comments

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-26 13:40:54 +00:00
Sergio Gasquez Arcos
fd57488ce3
Remove embedded-svc traits and feature (#2235)
* feat: Remove embedded-svc traits and feature

* docs: Changelog entry
2024-09-26 11:14:42 +00:00
Scott Mabin
6d96810c56
Allow building docs from different tags (#2218) 2024-09-26 08:55:54 +00:00
Björn Quentin
9321a34dbe
Reduce (unnecessary) rebuilds (#2232)
* Reduce (unnecessary) rebuilds

* Avoid redundant clone

* Prefer `.display()` over `.to_str().unwrap()`
2024-09-26 08:15:41 +00:00
Dániel Buga
feaf66847c
Fix warning: 'creating a shared reference to mutable static is discouraged' (#2230)
* Fix warning: 'creating a shared reference to mutable static is discouraged'

* Shorten lifetime of Clocks reference
2024-09-25 15:31:24 +00:00
Dominic Fischer
3bb49b049a
Deduplicate half duplex SPI setup (#2223)
* Deduplicate half duplex SPI setup

* clippy

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-25 10:03:20 +00:00
Dániel Buga
5076d1ee8f
DMA macro cleanup (#2226)
* Fix typo

* Deduplicate dma macro implementations

* Remove accidental defmt

* Extract count macro, use const block
2024-09-25 07:16:48 +00:00
Dániel Buga
fc924bf929
Remove TxPrivate and RxPrivate (#2225) 2024-09-25 06:27:43 +00:00
Dániel Buga
04f43d28c3
Prevent reentry on single-core, add basic tests (#2209) 2024-09-24 20:17:27 +00:00
liebman
cf9050d5d7
Support PSRAM in DmaTxBuf (#2161)
* support psram in DmaTxBuf

* add example that sometimes works :-(

* fmt

* cleanups

* allow chunk_size upto (including) 4095

* this test is passing for me now

* remove chunk_size and compute based on block_size

* return error in `prepare_transfer` if psram is found on non-esp32s3
add `dma_tx_buffer` macro

* missing parens

* changelog

* default 4092 for esp32 & fmt

* no errors anymode

* use block_size is_some to flag invalid psram in prepare_transfer

* drop block_size from macro, the buffer allocation was not being aligned - its not needed for dram anyway.

* missed macro example

* use defmt::Format that decodes owner like Debug

* fix typo

* DmaTxBuf: its an error if buffer is in psram and block_size is none

* DmaTxBuf: its an error if buffer is in psram and block_size is none

* update for PSRAM feature changes

* address alignment comments
add simple test

* fmt

* better alignment test

* revert alignment test

---------

Co-authored-by: Juraj Sadel <juraj.sadel@espressif.com>
2024-09-24 15:21:58 +00:00
Dominic Fischer
826754c482
Remove ChannelTypes trait (#2220)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-24 15:01:11 +00:00
Jesse Braham
4534ee13ae
Implement embedded_hal_async::delay::DelayNs for TIMGx timers (#2084)
* Update `hil-test` package dependencies, add simple test for async delay with `SYSTIMER`

* Implement `embedded_hal_async::delay::DelayNs` for the `TIMGx` timers

* Improve tests slightly

* Update `CHANGELOG.md`

* Enable `delay` and `delay_async` tests for the ESP32-H2

* Fix error in `delay_async` test after rebasing

* ESP32 does not have `SYSTIMER`, so don't try to test it :)

* Protect int_ena modifications with INT_ENA_LOCK, clear int_clr in ISRs, move interrupt binds from Future constructor into new_async constructor

* Fix wrong imports

* Address reviews: Remove duplicated/useless code and add HIL test for delay_us and delay_ms

* Implement DelayNs on Target instead of Periodic

* clean dead code

* fix after rebase

* fix build errors

* More accurate nanos to ticks calculation

* Fix wrong handler passed to set_interrupt_handler()

* Update esp-hal/src/timer/timg.rs

Co-authored-by: Dániel Buga <bugadani@gmail.com>

* cleanup left over

---------

Co-authored-by: Juraj Sadel <juraj.sadel@espressif.com>
Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>
Co-authored-by: Dániel Buga <bugadani@gmail.com>
2024-09-24 08:50:06 +00:00
Scott Mabin
117327e206
esp-config: allow negative values (#2204)
* esp-config: allow negative values

* Add small test for parsing erroneous negative values

* split Value::Number into signed and unsigned
2024-09-24 07:07:06 +00:00
Dominic Fischer
26fc8871db
Simplify DMA interrupt handlers (#2215)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-23 16:55:54 +00:00
Dániel Buga
02d221ee52
Fix TWAI on ESP32 (#2207)
* Some more gpio cleanup

* Allow TWAI loopback using the same pin, enable ESP32

* Impl Format for ErrorKind

* Generic frame constructors

* More TWAI cleanups

* Fix signals

* Set self-reception bit

* Teach users to use const blocks

* Fix resetting TWAI

* Set opmode when starting

* Apply errata workaround

* Fix ESP32 baudrate

* Clean up read_frame a bit

* Changelog

* Clean up clippy

* Fix compile errors

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-09-23 15:24:27 +00:00
Dániel Buga
f2c473d3bc
Remove DMA RegisterAccess::init_channel (#2205) 2024-09-23 14:48:20 +00:00
Dániel Buga
d971d65c98
Add chip-specific features for tests/examples (#2175)
* Refactor metadata parsing to allow spaces in keys

* Emit separate examples per chip

* Allow setting features for specific chips
2024-09-23 11:42:11 +00:00
liebman
987f00bb1d
PARL_IO: fix for garbage output at the start of some TX operations (#2211)
* per TRM the TX clock should only be re-enabled after tx_start

* CHANGELOG

* added tests to check the for the correct number of clocks during valid

* parl_io: fix test for esp32h2

* tests: parl_io: h2 PCNT does not like 20MHz
2024-09-23 10:27:43 +00:00
Dominic Fischer
794cdb0af4
Use enumset for DMA interrupts instead of countless functions (#2196)
* [1/x] Use enumset for DMA interrupts instead of countless functions

* [2/x] Remove the countless functions from RegisterAccess

* Use Into

* [3/3] Use enums everywhere in the DMA module

* Remove redundant enum_set!

* Remove `available_` prefix

* Use `pending_` prefix

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-23 08:43:56 +00:00
Dániel Buga
89d9de67eb
Enable QSPI tests on ESP32 and clean up (#2198)
* Clean up qspi test cfgs, enable on ESP32

* Correct comments

* Clean up init_spi_data_mode

* Fix qspi_write on ESP32

* Further cleanup in SPI driver

* Clean up qspi_read

* Fix qspi_write_read test on ESP32

* Merge QSPI tests

* Clean up test

* Attempt to fix test GPIO assingment

* Update esp-hal/src/spi/master.rs

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

* Update esp-hal/src/spi/master.rs

* Make sure pins have no internal pullups

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-09-23 08:37:35 +00:00
Dániel Buga
3ee8fa61ee
Apply rustfmt fix (#2210) 2024-09-23 08:19:29 +00:00
Björn Quentin
37fa662fe7
Remove most PSRAM features (#2178)
* Make most of PSRAM features into run-time configs

* Make CI green again

* Make CI green again

* Update esp-hal/MIGRATING-0.20.md

Co-authored-by: Scott Mabin <scott@mabez.dev>

* Use Range

* CI

* Rebase fixes

* Update esp-hal/src/lock.rs

Co-authored-by: Scott Mabin <scott@mabez.dev>

---------

Co-authored-by: Scott Mabin <scott@mabez.dev>
2024-09-20 16:43:25 +00:00
Dániel Buga
d4e463b3ff
Slight general cleanup, enable dma-macros test, allow using virtual mem2mem channel on c2 (#2200)
* Cfg features, not devices

* Remove InterruptBinder

* Clean up allow(declare_interior_mutable_const)

* Small embassy cleanup

* Enable dma-macros for 32 and S2

* Use MEM2MEM1 on C2

* Remove esp32-specific code from test
2024-09-20 15:04:18 +00:00
Sergio Gasquez Arcos
3d0a1998fa
Allow configuring the watchdogs in the init config (#2180)
* feat: Allow configuring the watchdogs in the init config

* docs: Update changelog

* refactor: Remove unnecesary unsafe

* feat: Add a config module

* test: Add some init tests

* style: Rename all ocurrences to esp_hal::config::Config::default()

* style: Fix format

* fix: Doc errors

* revert: Move Config struct to lib.rs

* tests: Add default config test

* test: Add a test with CpuClock::max()

* test: Add timg1 test

* feat: Move Config struct to config module and reexport it in lib.rs

* fix: Fix init compilation for C2

* revert: Move Config struct to config module and reexport it in lib.rs

* fix: Use proper timergroup
2024-09-20 13:51:35 +00:00
Björn Quentin
370f54119f
Create mutexes in heap memory (#2202)
* Create mutexes in heap memory

* CHANGELOG.md

* Remove unnecessary CS usage
2024-09-20 12:45:57 +00:00
Dániel Buga
5324bce815
Rework locks (#2197)
* Move lock impls out of lib.rs

* Reimplement Lock using ReentrantMutex

* Reimplement Lock using ReentrantMutex

* Refactor away some duplicate lock logic

* Return owner from try_lock

* Rework critical section to avoid spinning in irq-free context

* Fail compilation on unknown architectures

* Explain what RESERVED_MASK is

* Create one lock per timer group
2024-09-20 11:05:37 +00:00
Dániel Buga
d5afeeddc8
H2: enable TWAI, enable delay test (#2199)
* Add TWAI support for H2

* Enable delay test on h2

* Also enable example

* Changelog

* De-CAN the example
2024-09-20 07:04:52 +00:00
Dániel Buga
5de267ab09
Fix known SPI issues (#2179)
* Re-enable tests

* Clean up

* Pass two lengths to configure_datalen

* Add Dominic's test changes

* Ensure DMA buffers are properly aligned

* Impl Format on DmaDescriptor

* Fix waiting for transaction to complete

* Fix DMA transfers

* Changelog

* Avoid explicit panic in test case

* Remove redundant test case

* Reintroduce wait for ESP32
2024-09-19 18:00:50 +00:00
Scott Mabin
ba63beb3b2
Move binary logging to sys crate (#2183)
* Move binary logging to sys crate

* make ieee take radio clks by value

* rename wifi-logs to binary-logs and fix compilation

* update sys to use correct size types

* move rtc_clk_xtal_freq_get to esp-hal

* changelogs and migration guide

* s/wifi-logs/sys-logs/g

* activate log features for esp-wifi-sys

* ble log fix c2

* fix logs using latest sys rev

* fix warning
2024-09-19 15:19:54 +00:00
Dániel Buga
25eff6a255
Enable I2S tests on ESP32 and work around first sample issue (#2194)
* Enable I2S tests on ESP32 and work around first sample issue

* Fix sample->channel assignment inconsistency

* Add to changelog
2024-09-19 15:13:25 +00:00
Scott Mabin
d9d771706f
esp-config (#2156)
* Initial esp-config poc, replacing the place-spi-driver-in-ram feature

* Allow documentation generation for configuration options

* add `Value::Number` and a macro to parse

* Add Value::String and replace esp-wifi's config

* repo maint

* make bool parsing stricter and number parsing more flexible

* use hand rolled const str to int

* Collect unknown config options

* friendly errors

* also batch invalid values

* dump msrv to 1.79

* Mention perf boost from disabling logging

* review suggestions

* output selected config

* changelogs and migration guides

* review feedback

* avoid multiple case conversions where possible

* refactor generate, fix bug, add full test

* run host tests in CI

* add more esp-config tests

* review comments

* add cargo env workaround
2024-09-19 08:58:29 +00:00
Dániel Buga
46be3b19b5
Some minor I2S cleanups (#2190)
* Clean up rx_start

* Improve readability of register manipulation

* Enable failing tests on ESP32

* Improve consistency

* Merge tests

* Disable ESP32 for now

* Clean up some cfgs

* Avoid as pointer-casts

* Inline wait_for_dma_done

* Remove a level of indirection

* Fix typos

* Resolve questionmarks
2024-09-19 07:33:52 +00:00
Dániel Buga
f765a6b094
Remove Debug2Format from esp-hal (#2184) 2024-09-18 19:53:19 +00:00
Dániel Buga
c0a9934e62
Pass --verify when running HIL tests (#2188) 2024-09-18 14:39:35 +00:00
Dániel Buga
b1ca30e404
Disable problematic ESP32 test (#2185) 2024-09-18 13:58:54 +00:00
Dániel Buga
d9532bbba7
Fix and enable I2S tests on ESP32-S2 (#2181)
* Fix PDMA channels, use peripheral signal instead of external connection

* Fix i2s test setup for esp32s2
2024-09-18 09:43:37 +00:00
Dániel Buga
344ee133bc
Move SPI tests into the same file (#2177)
* Implement Peripheral for Level

* Move SPI tests into the same file

* Fix test on H2

* Also fix C6 signal numbers
2024-09-18 07:08:51 +00:00
Dániel Buga
fc92beebe6
Guide: Clarify that Level can be used as an output signal (#2176)
* Clarify that Level can be used as an output signal

* Implement Peripheral for Level
2024-09-18 07:01:16 +00:00
Dominic Fischer
5ae76d727e
Remove pin generics from I8080 (#2171)
* Remove pin generics from I8080

* Doc example

* temp

* More docs

* doc fix

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-17 13:56:01 +00:00
Anthony Grondin
a787a13441
Implement TryFrom<u32> for ledc::timer::config::Duty (#1984)
* feat(buzzer): Add `esp-hal-buzzer` to drive a piezo-electric buzzer.

Provides a driver for a piezo-electric buzzer by abstracting LEDC and offering a user-friendly API for a buzzer

* Move songs into example and refactor songs module.

* Move `esp-hal-buzzer` to https://github.com/esp-rs/esp-hal-community/

* Update `CHANGELOG.md`

---------

Co-authored-by: Jesse Braham <jesse@beta7.io>
2024-09-17 13:44:12 +00:00
Dominic Fischer
9de459c663
Add more thorough I8080 HIL tests (#2173)
* Add I8080 HIL test

* add fixme comment

* fmt

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-17 12:01:27 +00:00
Dániel Buga
cc4c6e1a8e
Tweak xtensa interrupt handling (#2148)
* Tweak xtensa interrupt handling

* Deduplicate peripheral interrupt handling
2024-09-17 08:10:21 +00:00
Scott Mabin
45806dfba0
use esp types in peripheral docs (#2172) 2024-09-16 20:49:07 +00:00
Dániel Buga
65396dda1f
Fix UART when using RcFast clock source (#2170)
* Refactor test_send_receive_different_baud_rates_and_clock_sources

* Don't rely on external connections for UART test

* Enable (failing) RcFast for C2/C3

* Make sure fast clock is enabled
2024-09-16 20:48:25 +00:00
Dániel Buga
87c2741305
Migration guide fixes (#2168)
* Fix use of Input in guide

* Add AnyPin change to guide
2024-09-16 17:47:06 +00:00
Jesse Braham
f496579c3b
Remove the esp-hal-smartled package (#2169) 2024-09-16 17:17:26 +00:00
Dominic Fischer
d44affcbf5
Prevent screen tearing in I8080 example (#2167)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-16 14:36:21 +00:00
Dániel Buga
2971c08ed4
Fix double writes (#2159)
* Fix double writes

* Only flush if we need to read
2024-09-16 11:22:14 +00:00
Dániel Buga
c9c7aa9253
Slight timer cleanup (#2158) 2024-09-16 11:21:33 +00:00
Björn Quentin
831df5a83c
Be more clear about the esp-alloc feature in esp-wifi's migration guide (#2165) 2024-09-16 11:21:11 +00:00
Dániel Buga
dfb40c0416
Fix overflowing subtraction (#2164) 2024-09-16 10:47:16 +00:00
Dániel Buga
b5dd5aed17
Gpio cleanup (#2157)
* InterruptStatusRegisterAccess

* GpioRegisterAccess

* Remove GpioProperties

* Hide private methods

* Simplify the analog macro

* Fix typo

* Remove unused NMI status read

* Hide ISRA

* Fix macro syntax

* Simplify rtc_pins macro

* Fix type name
2024-09-16 10:14:34 +00:00
Dániel Buga
f48415e717
Fix esp_alloc doc (#2163) 2024-09-16 08:59:21 +00:00
Dániel Buga
2a74addee0
Fix DMA starving SPI (#2152)
* Fix DMA starving SPI

* Simplify cfgs

* Trigger an update before starting transaction

* Do not update after enable_dma, use start_operation
2024-09-13 08:51:31 +00:00
Demo for summer'23
351a64937b
one typo; one misleading comment fixed (#2153)
* one typo; one misleading comment fixed

* agreed simplification
2024-09-12 20:31:24 +00:00
Dániel Buga
562c891ef9
SPI pins are no longer optional (#2133)
* SPI pins are no longer optional, rename DummyPin

* Swap QSPI test expected levels

* Tweak documentation around Level, implement PeripheralOutput

* Fmt
2024-09-12 10:59:12 +00:00
Dániel Buga
515e67092b
Remove PcntSource (#2134) 2024-09-12 08:30:16 +00:00
Danila Gornushko
b5152dcae5
Add esp-alloc to trouble ble example (#2149)
* add esp-alloc to trouble ble example

* rustfmt
2024-09-12 07:11:54 +00:00
Dániel Buga
f8e2341116
Fix pin collision in I2S tests (#2147) 2024-09-12 06:34:31 +00:00
Dániel Buga
e7dab298f5
Rename and wrap ErasedTimer (#2144)
* Rename and wrap ErasedTimer

* Also rename conversion trait
2024-09-11 20:29:21 +00:00
Björn Quentin
24c545db4a
I2C error recovery (#2141)
* Recover from I2C errors (the hard way)

* Adjust test to cover the problematic case

* Replace macro-usage

* CHANGELOG.md entry

* Appease Clippy

* TIL: `Result::inspect_err` exists

* Turn public `recover` into private `internal_recover`
2024-09-11 15:50:25 +00:00
Dániel Buga
7a733a75db
GPIO interconnect (#2128)
* Allow accessing signal list via ErasedPin

* Replace AnyPin with more flexible signal config

* Update tests and examples

* Fix enable_from_gpio value

* Access signals from pin drivers

* DummyPin is not a pin

* Remove redundant public fns

* Various fixes, rename ErasedPin

* Changelog

* rustfmt

* Update i8080

* Typos and endless recursion

* Drop Pin suffix from traits

* Extract AF conversion

* Touch up changelog

* Clean up spi tests

* Refactor pull resistor handling

* Don't disable configured output functionality

* Clean up TODO

* Tweak docs

* Clean up examples
2024-09-11 15:15:55 +00:00
Dániel Buga
f2e0211c1b
Use AtomicPtr, explain caveats (#2110) 2024-09-11 10:39:29 +00:00
Dominic Fischer
127df3c311
Introduce traits for the DMA buffer objects (#1976)
* Introduce traits for the DMA buffer objects

* Move preparation to DMA module for reuse

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-11 10:31:29 +00:00
Juraj Sadel
f374d6a102
Enable SPI_DMA_XX_ASYNC and _PCNT tests on ESP32 and S2, remove GPIO usage from description (#2140) 2024-09-11 10:23:07 +00:00
Björn Quentin
312746fb14
Fix I2S examples (#2139)
* Fix I2S examples

* Fix remaining examples

* Mention asymmetric variant of the `dma_buffers!` macro in the migration guide
2024-09-11 09:11:42 +00:00
Dániel Buga
9f5a57d819
Clean up UART (#2132)
* Clean up

* Add note to significant order of ops
2024-09-10 16:11:00 +00:00
Dániel Buga
dafad9b487
Allow conjuring private::Internal (#2118)
* Allow conjuring private::Internal

* Hide reexport
2024-09-10 14:25:21 +00:00
Björn Quentin
7332f5834a
Fix SPI DMA write/read for ESP32, ESP32-S2 (#2131)
* Fix SPI DMA write/read for ESP32, ESP32-S2

* CHANGELOG.md

* Review comments
2024-09-10 13:23:52 +00:00
Sergio Gasquez Arcos
208339ddeb
fix: Matrix link (#2130) 2024-09-10 11:05:14 +00:00
Sergio Gasquez Arcos
6f40dc2cca
Add issue templates (#2124)
* feat: Add issue templates

* feat: Address review comments

* feat: Add GH discussion link
2024-09-10 10:32:55 +00:00
Alexandra Clifford
e1c27f1b22
Some minor esp-ieee802154 updates (#2114)
* Use default CCA threshold value (per esp-idf)

* apply different consts for h2 versus c6 in tx power convert func

* Fix compile error when building with binary-logs feature

* Fix possible integer underflow error
2024-09-09 17:15:57 +00:00
Björn Quentin
ddf4ff7e9d
Make sure we can compile with defmt (#2126)
* Set DEFMT_LOG in CI

* Set DEFMT_LOG in CI

* Set DEFMT_LOG in CI

* Fix BLE vs DEFMT issue

* Fix ESP32 defmt problems in psram.rs

* Use `defmt` feature on `bt-hci`
2024-09-09 16:40:30 +00:00
Dániel Buga
be82a6521a
Allow pin drivers as wakeup sources (#2095)
Co-authored-by: Scott Mabin <scott@mabez.dev>
2024-09-09 10:45:46 +00:00
Dominic Fischer
3ea95bd0d8
Faster SHA (#2112)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-09 10:18:38 +00:00
Björn Quentin
6295c5f9da
Esp wifi/fix wifi logs (#2117)
* Fix `wifi-logs` feature

* Some clarifications in the esp-wifi migration guide

* CHANGELOG.md

* Review comments

* Check more features
2024-09-09 10:15:52 +00:00
Dániel Buga
05941ccc37
Touch pin definition overhaul (#2109)
* Merge touch macros

* Add missing touch pins, remove trait impl indirection

* Remove unused stuff

---------

Co-authored-by: Juraj Sadel <juraj.sadel@espressif.com>
2024-09-09 10:05:43 +00:00
amsam0
82a9abfff8
Allow setting RTC time (#1883)
* Initial WIP RTC set implementation

* Deprecate get_time_raw and add docs + some cleanup

* Update rtc time example

* Format

* Update changelog

* Add some comments linking the PR

* Small compilation fixes

* C6 and H2 fixes

* Remove parantheses from if statement lol

* Remove accidental changelog change

* Implement boot time wrapping to avoid overflows

* Remove unused get_rtc_time_ms and get_rtc_time_us functions

* Make get_rtc_time_us public and re-add get_rtc_time_ms as public

* Update changelog

* Remove get_time_raw and replace with public get_rtc_time_raw

* Changelog reordering

* Function renaming

* Use fugit and update changelog

* Small typo fix

* Fix changelog addition from merging

* Use chrono for current_time and set_current_time

* Fix changelog

* Update example

* Fix merge errors

* Rename `time::current_time` to `time::uptime`

* Revert "Rename `time::current_time` to `time::uptime`"

This reverts commit fe8446899747c88d5b9f945f319e1133b90773ee.

* Format

* Add info to migration guide

* Fix compilation for esp32c2

* Remove information about setting RTC time from migration guide since it isn't really relevant

---------

Co-authored-by: naturecodevoid <44983869+naturecodevoid@users.noreply.github.com>
2024-09-09 08:32:15 +00:00
Björn Quentin
d71434adfb
esp-wifi uses global allocator, esp-alloc supports multiple regions (#2099)
* esp-wifi uses global allocator, esp-alloc supports multiple regions

* CHANGELOG.md

* Apply suggestions

* Use `alloc` when linting esp-wifi

* Make coex example build for ESP32

* Re-enable some wifi examples for ESP32-S2

* Optionally depend on `esp-alloc` (by default)

* Rename INSTANCE -> HEAP
2024-09-06 15:42:19 +00:00
Björn Quentin
b3d2aaddd0
Prepare esp-backtrace 0.14.1 (#2107) 2024-09-06 14:47:09 +00:00
Scott Mabin
a3f734028a
ensure that clock init happens after rtc domain is initialized (#2104) 2024-09-06 13:58:35 +00:00
Ulf Lilleengen
93f1012663
Add integration with bt-hci crate (#1971)
* Add integration with bt-hci crate

Implementing traits from bt-hci allows the BleConnector to
be used with the Trouble BLE stack.

* use packed based read interface

* Improve example to allow another connection after disconnect

* update trouble version

* Workaround for spurious command complete events

* fix formatting

* ignore notify errors in example

* fix clippy warnings

* remove async feature from hal dependency

* remove deprecated feature from example

* Adopt to api changes

* Api fix for esp32

* Set rust-version of esp-wifi

* bump MSRV to 1.77 for CI and esp-hal

* Add changelog entry
2024-09-06 13:08:25 +00:00
Szybet
e6da89627b
Update esp-println version in usage section (#2100) 2024-09-06 11:48:21 +00:00
Björn Quentin
598212a020
Make additional memory available as dram2_uninit (#2079)
* Make additional memory available as `dram2_uninit`

* CHANGELOG.md
2024-09-06 10:55:33 +00:00
Dániel Buga
d6813a4bf0
Random additional GPIO cleanups, implement Peripheral for drivers (#2094)
* Reuse enable_iomux_clk_gate

* Remove public functions

* Remove set_to_input

* Deduplicate constructor

* Deduplicate is_listening

* Hide PinFuture better

* Deduplicate set_int_enable

* Align macro indentation

* Typo

* Slightly simplify the touch_into macro

* Implement the AnalogPin trait directly

* Provide default impls for simple forwarding methods

* Newtype ErasedPin

* Merge rtc_pin macros

* Fmt

* Changelog

* Fix migration guide

* Fix example

* Fix ETM
2024-09-06 10:26:23 +00:00
Sergio Gasquez Arcos
b5f0246129
Reordered RX-TX pairs to be consistent (#2074)
* feat: Update rx-tx order in i2s

* feat: Update rx-tx order in dma macros

* feat: Update rx-tx order in spi

* feat: Update rx-tx order in aes

* feat: Update rx-tx order in mem2mem

* feat: Update rx-tx order in twai and split methods

* feat: Update rx-tx order in twai

* feat: Update rx-tx order in twai and uart docs

* docs: Add sentence about order

* docs: Update changelog

* feat: Update rx-tx order in embassy_interrupt_spi_dma tests

* style: Rustfmt

* docs: Migrating guide

* fix: Typo

Co-authored-by: Dániel Buga <bugadani@gmail.com>

* fix: Diff

Co-authored-by: Dániel Buga <bugadani@gmail.com>

* fix: Tests rx-tx order

* fix: Update new_with_default_pins order

* feat: Update rx/tx order in hil_test::common_test_pins!

* feat: Update dma_extmem2mem example

* fix: Revert deleted input arg

* style: rustfmt

* feat: Disable test_asymmetric_dma_transfer for S2

---------

Co-authored-by: Dániel Buga <bugadani@gmail.com>
2024-09-06 09:56:10 +00:00
liebman
492e35aa74
esp-wifi: other crates also provide strchr (littlefs2-sys) (#2096)
* esp-wifi: other crates also provide strchr (littlefs2-sys)

* esp-wifi: other crates also provide strchr (littlefs2-sys)

* changelog

* fmt :-(
2024-09-06 09:22:33 +00:00
Juraj Sadel
17daa464ba
Enable ESP32 HIL (#1977)
* Enable ESP32 HIL

* RMT fixed

* SPI DMA partially works, _pcnt tests not working

* bckup

* finish

* readme and cleanup

* rebase + cleanup

* RMT S2 pin typo + clean forgotten comments

* review comments

* update 10000

* indentation

* replace cfg gate with cfg_if
2024-09-06 08:53:27 +00:00
Anthony Grondin
fba475ee40
Add missing #[doc(hidden)] in xtensa-lx-rt-proc-macros (#2097) 2024-09-06 06:36:54 +00:00
Scott Mabin
70126c8149
Rename esp_hal::time::current_time to esp_hal::time::now (#2091)
* rename esp_hal::time::current_time to esp_hal::time::uptime

* changelog

* move more things to init

* s/uptime/now/g
2024-09-05 14:57:56 +00:00
Dániel Buga
f11c18a6b9
Optionally type-erased GPIO drivers (#2075)
* Remove type erased gpio structs

* Implement Peripheral for ErasedPin

* Simpler type erasing, accept ErasedPin in pin drivers, remove type erased drivers

* Reformulate pin drivers using Flex

* Erase gpio types by default

* Accept any pin in AnyPin

* Add changelog and migration guide

* Fix tests and examples

* Undo rename of clone_unchecked
2024-09-05 14:14:51 +00:00
liebman
a5ab73959e
i2c: fix embedded-hal transactions (#2028)
* i2c: fix embedded-hal transactions

* changelog+fmt

* small naming cleanup

* i2c: fix 1 byte reads

* typo

* small cleanup and add a few internal docs

* update changelog

* rebase & CHANGELOG

* extract next op conversion

* fix `setup_read()` logic for 0 length reads.

* return error for 0 length reads and 0 length  writes where start=false

* comment about max_len in setup_write()

* filter out 0 length read operations in `transaction()`

* Short circuit for problematic 0 lengths in read_operation and write_operation

* don't short circuit a 0 length write operation if stop=true

* handle write_read when the read bufer is empty
2024-09-05 14:05:00 +00:00
M4tsuri
4f97befdde
Implement sleep and wakeup functionalities for ESP32C2 #1920 (#1922) 2024-09-05 13:39:46 +00:00
liebman
a2af2ac65e
lcd_cam: fix wrong buffer length used if 16bit and len<=8192 (#2085)
* lcd_cam: fix wrong buffer length used if 16bit and len<=8192

* changelog
2024-09-05 13:07:00 +00:00
Gnome!
4d9ea52eae
[esp-hal-procmacros] Update to proc-macro-error2 (#2090) 2024-09-05 11:40:52 +00:00
Dominic Fischer
b6aceb1de8
Improve SHA driver API (#2049)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-05 11:39:46 +00:00
Dániel Buga
5370afb1eb
Build examples in debug mode (#2078)
* Build examples in debug mode

* Allow building psram examples in debug mode in CI

* Don't rebuild tests, try to avoid rebuilding dependencies
2024-09-05 10:04:07 +00:00
Dániel Buga
42a0417fba
Fix nightly warnings (#2082) 2024-09-05 07:40:22 +00:00
Scott Mabin
80c0a81718
fix issue handler, don't rebuild on main the merge queue checks this for us (#2077) 2024-09-04 16:02:47 +00:00
Dániel Buga
fb694110d2
Accept ErasedPin in AnyPin (#2072)
Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-09-04 15:17:39 +00:00
Dániel Buga
e898e89f60
Remove AnyInputOnlyPin (#2071)
* Remove AnyInputOnlyPin

* Add section to migration guide

* Remove unnecessary enum

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-09-04 15:11:08 +00:00
Dániel Buga
39109a4a05
Remove gpio dispatch macro-defining proc macro (#2069)
* Keep a single PinType trait

* Merge impl blocks

* Deduplicate usb pad workaround

* Deduplicate some bit manipulation

* Remove gpio dispatch proc macro

* Inline PinType into GpioProperties
2024-09-04 14:47:24 +00:00
Dániel Buga
99bf346898
Remove the need to manually pass clocks around (#1999)
* Clean up passing clocks to drivers

* Update changelog

* Initialise Clocks in a critical section

* Fix calling now() before init

* Fix doc

* Fix esp-wifi migration guide

* Add safety comment

* Update tests
2024-09-04 14:13:51 +00:00
Dániel Buga
7688504289
Remove Gpio type aliasses (#2073)
* Remove Gpio type aliasses

* Clean up examples
2024-09-04 13:37:56 +00:00
Kirill Mikhailov
9bec6a1806
Adding I2C HIL test (#2023)
* i2c hil test

* pin

* fmt

* Test

* WIP (gpio test left)

* Finalize the CODE part (to be cleaned up)

fmt

* Smaller cleanup

* cleanup

* rebase

* fix

* getting last chips ready

* Addressing reviews
2024-09-04 12:45:58 +00:00
Jesse Braham
b7b916f03a
Remove most trait implementation features from esp-hal (#2070)
* Eliminate esp-hal's `ufmt` feature

* Eliminate esp-hal's `embedded-hal-02` feature

* Eliminate esp-hal's `embedded-hal` feature

* Eliminate esp-hal's `embedded-io` feature

* Eliminate esp-hal's `async` feature

* Update `CHANGELOG.md`

* Remove `async` from required features for HIL tests

* Update migration guide
2024-09-04 06:15:27 +00:00
Gnome!
49e14b7ccb
Remove lazy_static in favor of OnceLock (#2063)
* [esp-metadata] Remove lazy_static in favor of OnceLock

* [esp-wifishark] Remove lazy_static in favor of normal initialisation

* [ieee802154-sniffer] Shorten SelectorConfig initialisation

* [ieee802154-sniffer] Remove lazy_static in favor of normal initialisation
2024-09-03 14:43:35 +00:00
Björn Quentin
0cf7abfc47
Make esp-wifi build on stable, again. Bump to 0.9.1 (#2067)
* Make esp-wifi build on stable, again. Bump to 0.9.1

* CHANGELOG.md

* MSRV check esp-wifi

* ESP32-S2 doesn't support Bluetooth
2024-09-03 16:10:20 +02:00
Dániel Buga
647e34f401
Remove NoPinType (#2068) 2024-09-03 13:36:14 +00:00
Björn Quentin
9c3b17166f
Bump to esp-wifi 0.9.0 (#2066) 2024-09-03 13:30:28 +01:00
Björn Quentin
5420ce0959
WPA2 ENTERPRISE (#2004)
* WPA2 ENTERPRISE

* Defmt, Clippy, Changelog

* Defmt, again

* Clippy, again

* Mention corresponding JIRA ticket

* Rename

* fmt

* Use Mutex in scheduler

* Adapt wifi_delete_queue

* Adapt log level
2024-09-03 11:22:39 +00:00
Dániel Buga
9465244e0d
Fix various SPI/DMA issues (#2065)
* Add failing test

* Fix enabled interrupt

* Fix using the correct waker

* Changelog

* Enable test on more devices that have SPI3
2024-09-03 10:02:21 +00:00
Dániel Buga
08d406ee2b
storage: Clean up ROM function declarations (#2058)
* Clean up external function declarations

* Tweak syntax
2024-09-02 15:24:41 +00:00
Dániel Buga
c21287a5ef
Provide ehal impls for DummyPin (#2019)
Co-authored-by: Scott Mabin <scott@mabez.dev>
2024-09-02 15:16:26 +00:00
Gnome!
671003ace6
[esp-metadata] Make clap dependency optional (#2055) 2024-09-02 14:31:23 +00:00
Dániel Buga
580222758e
Fix hil-test xtask instruction (#2062)
* Fix hil-test xtask instruction

* Fix another mention
2024-09-02 14:08:17 +00:00
Dániel Buga
447411fb58
Rework hal initialization (#1970)
* Rework hal initialization

* Turn sw interrupt control into a virtual peripheral

* Return a tuple instead of a named struct

* Fix docs

* Remove SystemClockControl

* Move software interrupts under interrupt

* Re-document what's left in system

* Update time docs

* Update sw int docs

* Introduce Config

* Fix tests

* Remove redundant inits

* Doc

* Clean up examples&tests

* Update tests

* Add changelog entry

* Start migration guide

* Restore some convenience-imports

* Remove Config from prelude
2024-09-02 13:38:46 +00:00
Björn Quentin
d60bafbf05
Improve CP0-disabled error message (#2061)
* Improve CP0-disabled error message

* CHANGELOG.md
2024-09-02 13:38:10 +00:00
Scott Mabin
b620e35ebe
automatically apply status:needs-attention to new esp-hal issues (#2030) 2024-09-02 11:43:36 +00:00
Dominic Fischer
11f90b9e8b
Protect SYSTIMER/TIMG shared registers (#2051)
* Protect SYSTIMER/TIMG shared registers

* some review comments

* more review comments

* more review comments

* bring back portable_atomic

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-09-02 11:40:25 +00:00
Scott Mabin
6b4079be3a
release prep xtensa-lx-rt@0.17.1 (#2060) 2024-09-02 11:11:36 +00:00
Dániel Buga
44567f6687
Save/restore coprocessor state on stack (#2057)
* Whitespace

* Save and restore coprocessor enable state
2024-09-02 09:45:11 +00:00
Dániel Buga
c5e342a7a7
Clean up gigantic GPIO eyesore (#2048) 2024-09-02 08:58:54 +00:00
Björn Quentin
2dc285a947
QSPI tests (#2015)
* Add QSPI tests

* Simplify

* Add qspi_write_read test
2024-09-02 07:52:20 +00:00
Dániel Buga
8e6411bd31
Random cleanups in non-checked packages (#2034)
* Deduplicate feature check macros

* Re-enable rust-analyzer for most of the workspace

* Cargo fix

* Turn off defmt

* Only build xtask

* Clippy pls

* Fix CI

* Fix paths

* Always create doc directory first

* Revert r-a

* Update esp-hal-procmacros/src/lp_core.rs

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>

---------

Co-authored-by: Dominic Fischer <14130965+Dominaezzz@users.noreply.github.com>
2024-08-30 14:45:54 +00:00
Dániel Buga
fce510f50a
Disable object's unnecessary features in proc macro that loads LP code (#2018)
* Disable object/decompress

* Only enable elf support in object
2024-08-30 14:37:27 +00:00
Sergio Gasquez Arcos
f9ab55c38f
fix: Fix nightly errors (#1934) 2024-08-30 14:08:06 +00:00
Jesse Braham
533288d351
Begin next release cycle (#2039)
Co-authored-by: Scott Mabin <scott@mabez.dev>
2024-08-30 12:28:14 +00:00
Dániel Buga
897c92e389
Try to be more helpful (#2044) 2024-08-30 11:46:25 +00:00
Scott Mabin
aacc001e5d
Prepare v0.20.1 release (#2046) 2024-08-30 11:10:35 +00:00
Dániel Buga
28b5cd0158
Fix before_snippet failing in release (#2040)
* Fix before_snippet failing in release

* Fix esp-hal-embassy comment
2024-08-30 10:06:11 +00:00
Jesse Braham
5917275108
Version 0.20.0 (#2038)
* Update package dependencies and bump version numbers

* Update `CHANGELOG.md` for each package to be published

* Remember to update `xtensa-lx-rt` too :)

* Add and use TrapFrame::new() in esp-wifi

* Bump `xtensa-lx-rt` by minor instead of patch, as there are breaking changes

---------

Co-authored-by: Dániel Buga <bugadani@gmail.com>
2024-08-29 19:29:33 +00:00
Jesse Braham
bac6bfd1b4
Use newly published versions of all PACs in esp-hal (#2025)
* Use newly published versions of all PACs in `esp-hal`

* Address additional review comments
2024-08-29 13:55:59 +00:00
Dániel Buga
99c238d19d
HIL: Don't skip cleanup (#2024)
* Don't skip cleanup

* Make sure the power is off for a short while
2024-08-28 20:17:10 +00:00
Scott Mabin
6fb636be89
Remove unneeded logs (#2022) 2024-08-28 15:06:33 +00:00
Dániel Buga
84a060013d
Fix defmt compatibility (#2017)
* Fix defmt compatibility

* Update tests to cover macros
2024-08-28 14:07:09 +00:00
Scott Mabin
61bb240166
forward spi methods to SpiDmaBus (#2016)
* forward spi methods to SpiDmaBus

* changelog
2024-08-28 11:18:20 +00:00
Dániel Buga
16abd3d318
Only reserve the interrupt when executors are needed (#2014) 2024-08-28 09:56:22 +00:00
Dániel Buga
6abbc72e11
Test and fix async RSA (#2002)
* RSA cleanup & API consistency change, part 2

* RSA cleanup & API consistency change, part 3

* Add async tests

* Fix async for ESP32

* Merge impl blocks

* Backtrack on some mutability changes

* Use Acquire/Release ordering

* Fwd to write_multi_start instead of duplicating impl
2024-08-28 09:56:05 +00:00
Dániel Buga
c7a7760b51
Implement timer conversion for some arrays (#2012) 2024-08-28 09:54:58 +00:00
Björn Quentin
fbee4e5e4f
Fix (#2013) 2024-08-28 09:42:00 +00:00
Dániel Buga
5dcde78ccc
Re-add feature gate for software_interrupt3 (#2011) 2024-08-27 17:16:19 +00:00
Scott Mabin
65c5dc1781
SPI DMA: use State for both blocking and async operations (#1985)
* use `State` for both blocking and async operations, remove async version of SpiDmaBus in favour of being generic over the mode

* reuse wait_for_idle more

* changelog

* rename generic params for consistency

* Add duplex mode to SpiDmaBus

* implement HalfDuplexReadWrite for SpiDmaBus

* Docs on new async APIs

* Limit half duplex transfers to the capacity of the DmaBuf

* docs

* rebase tests

* address review comments

* remove duplex traits from spi

* fix tests

* spi docs rejig

* s/InUse/TemporarilyRemoved/g
2024-08-27 16:15:59 +00:00
Dániel Buga
8aa1a88a23
Prefer cfg_if (#2003) 2024-08-27 11:53:55 +00:00
Dániel Buga
1003ce0c0f
Clean up SHA, RSA, mandate #[must_use] on Futures (#2000)
* Janitor go brr

* Clean up SHA

* Use max CPU speed

* RSA cleanup part 1

* Clean up nonsense comments

* Mark all futures as must_use
2024-08-27 10:43:58 +00:00
Priit Laes
a41bc4cb3d
gpio: Make AnyPin, AnyInputOnlyPin, DummyPin available from gpio module (#1918)
Making these available straight from `gpio` aligns it with other Embassy
implementations (mainly nrf and stm32).

Signed-off-by: Priit Laes <plaes@plaes.org>
2024-08-26 18:30:24 +00:00
Dániel Buga
e1697310f6
Refactor SPI tests & re-enable S3 and some S2 (#1990)
* Deduplicate spi_full_duplex_dma_async

* Refactor SPI tests

* Separate out PCNT tests

* Re-enable test on S3

* Re-enable some S2 tests
2024-08-26 14:22:19 +00:00
Dániel Buga
d0f98b6c1f
Remove files after test (#1993) 2024-08-26 13:50:40 +00:00
Dániel Buga
341db16874
Use uhubctl to disable and enable usb ports (#1997) 2024-08-26 13:46:32 +00:00
liebman
5f0dc148ed
parl_io: use ReadBuffer/WriteBuffer for async DMA (#1996)
* parl_io: use ReadBuffer/WriteBuffer for async DMA

* CHANGELOG
2024-08-26 13:10:56 +00:00
Dániel Buga
b4ccb359ef
HIL: Multiple featuresets & conditionally enable generic-queue feature (#1989)
* Conditionally enable generic-queue feature

* Allow specifying multiple feature sets and run all of them
2024-08-26 06:19:03 +00:00
Scott Mabin
0e333f7aa2
tell cargo about all our custom cfgs (#1988)
* tell cargo about all our custom lints

* fixup the unexpected cfg lints, including remove clic
2024-08-23 12:56:00 +00:00
Scott Mabin
d610ee83db
Add tests to ensure that we don't reset current_time drivers (#1978) 2024-08-23 11:24:03 +00:00
Kirill Mikhailov
19db509403
Get rid of missing docs in a number of modules (#1967)
* Get rid of missing docs in a number of modules

* address reviews

* Address the rest of reviews

* remove all remaining `allows`

* are you serious?
2024-08-23 09:22:37 +00:00
Dániel Buga
f829c8f2ac
Fix C2 delays (#1981)
* Re-enable delay tests on S2 and C2

* Systimer: use fn instead of constant to retrieve tick freq

* Reformulate delay using current_time

* Take actual XTAL into account

* Re-enable tests

* Fix changelog

* Disable defmt

* Remove unused esp32 code

* Update esp-hal/src/delay.rs

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-08-21 17:33:46 +00:00
Dániel Buga
69cf454a5a
Fix S2 systimers (#1979)
* Add basic systimer interrupt tests

* Remove unnecessary condition

* Fix edge interrupt bitmasks

* Modify target_conf in critical section

* Remove unnecessary fn call

* Fix test

* Add failing test case

* Fix S2 systimer interrupts being fired unexpectedly

* Add changelog entry

* Format
2024-08-21 13:21:13 +00:00
Dominic Fischer
dc6c53ee47
Remove redundant WithDmaSpi traits (#1975)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-08-21 12:59:55 +00:00
Scott Mabin
7dfaca49ba
correct changelog sections (#1974) 2024-08-21 07:03:56 +00:00
Scott Mabin
a33ebe1ed6
Remove free(self) in HMAC which goes against esp-hal API guidelines (#1972)
* Remove `free(self)` which goes against esp-hal API guidelines

* changelog
2024-08-20 12:13:44 +00:00
Dániel Buga
686037be4d
Run HIL tests as part of PR checks (#1959)
* Run HIL tests as part of PR checks

* Cancel pending HIL runs

* Only run for ready PRs
2024-08-20 11:48:49 +00:00
Dominic Fischer
41f9925e2c
[3/3] DMA Move API: Introduce DMA buffer objects (#1856)
* [3/3] DMA Move API: Introduce DMA buffer objects

* Remove FlashSafeDma

* Add async HIL test

* Handle set_length(0) correctly

* Fix tx/rx booleans

* Unlucky

* Preserve previous blocking semantics

* Add delay between starting DMA TX and SPI driver

* Update CHANGELOG

* merge tidy

* Add with_buffers builder

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-08-20 11:47:55 +00:00
Dániel Buga
05582d3ca9
Fix 1GB elfs (#1962) 2024-08-19 14:46:30 +00:00
Anthony Grondin
70491b9e37
Refactor SHA to use trait. Implement Digest traits for SHA (#1908)
* feat(SHA): Refactor SHA to use trait. Implement Digest traits for SHA

* Fix CI. Fix wrong sha mode for esp32

* Save hash register for interleaving operation

An example (wip) `sha_fuzz.rs` was added to test different functionalities of the SHA driver and to ensure proper functionning under all cases.

* Use random data when testing SHA

* fix(SHA): Buffer words until a full block before writing to memory

This fixes interleaving operations by buffering words into the SHA context until a full block can be processed.

* Fix(SHA): Use correct length padding for SHA384 and SHA512.

- This fixes a long running issue with SHA384 and SHA512, where some digest of specific sizes wouldn't compute correctly, by changing the padding length of the size field.

* Re-export digest for convenience

* Remove completed TODO

* Remove SHA peripheral requirement.

- Document safety of the SHA driver.

---------

Co-authored-by: Scott Mabin <scott@mabez.dev>
2024-08-19 14:43:47 +00:00
Dániel Buga
ec130877b7
Disable RTT polling in HIL tests by default (#1960)
* Disable defmt-rtt by default

* Update i2s test based on changes done to async

* fmt

* Update readme

* Update more tests
2024-08-19 13:47:22 +00:00
Juraj Sadel
6a38053c15
Patch typo in debug assist register name and used patched esp-pacs (#1968) 2024-08-19 13:44:22 +00:00
Juraj Sadel
42bbdaeb4f
Add basic HIL test for GPIO that can be configured as pin for (#1963) 2024-08-19 11:43:59 +00:00
Juraj Sadel
e708dbc777
Add more SPI DMA (full-duplex) HIL tests (blocking and async) (#1952)
* Add more SPI DMA HIL tests (blocking and async)

* move test repetitions into loops instead, add a description about why PCNT is used, import embedded_hal_async::spi

* clean up
2024-08-19 06:59:55 +00:00
Frostie314159
d1acacb757
Implement Sniffer API (#1935)
* Implemented queue_msg_waiting.

* Fmt.

* Adjusted changelog.

* Fixed CI.

* Fixed pointer mutability.

* Implemented experimental sniffer api.

* Fixed CI..

* Added safety comment.

* Featured gated, PromiscuousPkt

* Format.

* Adjusted imports.

* Added injection example.

* Made RxControlInfo::from_raw public.

* Format.

* Added sniffer example.
2024-08-19 06:51:18 +00:00
Dániel Buga
59728c523f
Some xtask/metadata cleanups (#1965)
* Clean up almost all clippy violations

* Remove redundant variable from context

* Do not clone configs

* Do not collect all config symbols into a vec needlessly

* Do not allocate so many strings
2024-08-19 06:49:05 +00:00
Dániel Buga
f95ab0def5
Simplify initialization APIs (#1957)
* Accept more types in embassy::init

* Apply the same treatment to esp-wifi

* Changelog

* Clean up

* Add doc examples

* Fix Alarm generic parameters
2024-08-16 16:33:29 +00:00
Dominic Fischer
6e706c5f11
Improve SYSTIMER API (#1871)
* Improve SYSTIMER API

* Remove config object

* fix things

* Allow erasure of unit and comparator numbers

* Merge fail

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-08-16 14:59:34 +00:00
Dániel Buga
eb1b295116
Do not reset UsbSerialJtag peripheral (#1961)
* Fix typos

* Add a function to detect debugger connection

* Do not reset USB peripheral

* Changelog

* Fix different register names

* Reuse xtensa_lx::is_debugger_attached
2024-08-16 14:51:34 +00:00
Fan Jiang
f6e69b06d0
Fix GPIO Touch pin I/O (#1956) 2024-08-16 12:39:20 +00:00
Dániel Buga
6127f5df11
Further clean up timers/executors test (#1953)
* Further clean up embassy_timers_executors

* Do not delay for so long

* Print timer values on assert failure

* Clean up some more

* Retry test a few times to counteract probe-rs halting us

* Fix formatting
2024-08-16 06:08:32 +00:00
Dániel Buga
a10f86dbaa
Clean up i2s_async test, add option to repeat (#1951)
* Simplify I2S async test

* Allow running tests repeatedly

* Fail at the first mismatch

* Clean up
2024-08-15 11:48:23 +00:00
Scott Mabin
361a6c58b7
make contribution docs more visible (#1947) 2024-08-15 07:58:06 +00:00
Kirill Mikhailov
f1ec4a2ac9
Removing raw addresses manipulations - part 3 (#1892)
* WIP state

* More fixes

* Roll back `esp-storage` changes

* Small fixes

Will not work, needs another patch for PACs

* update pacs dep

* Lint

* Get rid of unnecessary if-else

fix

* New pacs version
2024-08-14 16:38:00 +00:00
Dániel Buga
9e87792fb9
Update probe-rs, prebuild xtask for HIL tests (#1939)
* Update probe-rs

* Differentiate jobs

* Explicitly print that probe-rs's execution failed

* Do not capture stdin/stderr

* Pre-build xtask binary

* Use current_directory

* Print more info when a file can't be read

* Do not erase flash after a failure

* get_time: fail faster

* Make xtask runnable
2024-08-14 15:47:52 +00:00
Kirill Mikhailov
460eaa254a
Adding TWAI HIL test (#1946)
* Adding `TWAI` HIL test

* add `Frame` trait

* mutability
2024-08-14 14:06:08 +00:00
Kirill Mikhailov
945f8b3a19
ESP32C6: Make ADC usable after TRNG deinitialization (#1945)
* Make `ADC` usable after `TRNG` deinicialization (esp32c6)

* Changelog entry
2024-08-14 12:46:28 +00:00
Sycrosity
c83d1de974
Update to latest release (0.6.0) for embassy-executor in esp-embassy-hal (fixes #1941) (#1942)
* Updated to latest release (`0.6.0`) for `embassy-executor`

* update changelog

* update hil-test version of embassy-executor to 0.6.0

* update embassy-executor in `examples`

* reflect esp_hal change in `OneShotTimer` to not have a lifetime.

* update changelog

* revert OneShotTimer changes
2024-08-14 12:45:46 +00:00
Frostie314159
1173aac945
Implemented queue_msg_waiting. (#1925)
* Implemented queue_msg_waiting.

* Fmt.

* Adjusted changelog.

* Fixed CI.

* Fixed pointer mutability.
2024-08-14 12:44:48 +00:00
Dániel Buga
6b6e628940
Slightly clean up embassy HIL tests (#1937) 2024-08-13 19:39:36 +00:00
Kirill Mikhailov
c53ba38c43
Fix i2c + get rid of unused constants/enums (#1940) 2024-08-13 19:17:55 +00:00
Dániel Buga
352879abce
Fix an infinite loop in interrupt executors (#1936)
* Add failing test

Fix the name of the test fn

* Fix interrupt executor looping

* Fix formatting

* Fix changelog reference

* Move changelog to the right crate

* Remove dead code
2024-08-13 12:51:26 +00:00
Jesse Braham
a6e14067ae
Deny missing docs at the package level, adding exceptions for relevant modules (#1931) 2024-08-13 12:46:17 +00:00
Juraj Sadel
64a7d49a29
Reset peripherals on driver construction (where missing) (#1893)
* Reset peripherals on driver contruction (where missing)

* Don't enable and reset SHA in HMAC ctor

* changelog

* Don't reset the TIMG0
2024-08-13 12:09:04 +00:00
liebman
23f76b0bea
DMA: Don't require implementors of Read/WriteBuffer to be Sealed (#1921)
* DMA: Don't require implementors of Read/WriteBuffer to be Sealed

* CHANGELOG

* mark dma::ReadBuffer and dma::WriteBuffer traits unsafe
2024-08-13 11:48:43 +00:00
Kirill Mikhailov
a3a3ef12e4
Add self-testing mode for TWAI peripheral. (#1929)
* Add self-testing mode for `TWAI` peripheral

* changelog entry

* fix docs build

* fix async example

* Restore example to original state

fix comment

* `NoAck` -> `SelfTest`
2024-08-12 15:22:27 +00:00
KashunCheng
888e9425a4
chore: Update TimerClockConfig to support period updating method (#1898)
* chore: Update `TimerClockConfig` to support period updating method

* docs: added a change log entry
2024-08-12 13:20:02 +00:00
Dániel Buga
63a2d407ee
Fix some typos (#1930) 2024-08-12 12:20:58 +00:00
Alexandra Clifford
1371b11f32
More bandaid fixes for invalid range index and other array access panics (#1923) 2024-08-12 08:28:51 +00:00
Sergio Gasquez Arcos
2e8937a90f
Update probe-rs version (#1914)
* docs: Update probe-rs version

* feat: Simplify probe-rs args

* ci: Update the checkout action to use the fork
2024-08-09 14:11:29 +00:00
Kirill Mikhailov
cb0016aa43
Removing raw address manipulations - PSRAM (#1854)
* WIP state

* WIP state (PSRAM ESP32)

* Use PAC - PSRAM

* Removing "leftover" debug comments

ooops

* Quick fix in `TRNG`

* remove unnecessary unsafe blocks

* Update `esp-pacs` dependency + small fix

* Update to latest PAC version

* Removing wrong code in a comment
2024-08-08 12:19:11 +00:00
Kirill Mikhailov
1574e53b0e
Make C6 ADC calibration work properly again (#1911)
* Reverting changes which provoke wrong `ADC` behaviour

* Minor example fix

* clocks update
2024-08-08 11:52:08 +00:00
Kirill Mikhailov
bb6e710327
Removing unnecessary bitfield from I2C driver (#1900)
* Getting rid of bitfield usage

fmt

* use `variant` methods for opcode

* update pacs dependency
2024-08-08 09:40:13 +00:00
Sergio Gasquez Arcos
6ac56a25dc
Update channels being used in CI jobs (#1910)
* ci: Use stable to build HIL tests

* ci: Remove useless line

* fix: Avoid setting toolchain based on the target
2024-08-08 08:37:22 +00:00
Fan Jiang
3473dda774
TWAI: GPIO pins are not configured as input and output (#1906)
Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-08-07 14:22:30 +00:00
Sergio Gasquez Arcos
e58b4d8d89
Check packages with nightly for RISC-V devices (#1881)
* ci: Check pacakges with nightly

* ci: Remove duplication

* perf: Nightly clippy fixes

* revert: Revert unsafe changes

* ci: Use an action to remove duplication

* ci: Update trigger conditions

* ci: Update S2 serial port

* ci: Rename action
2024-08-07 13:32:48 +00:00
Juraj Sadel
54ee364130
ESP32(SPI): Disable the write side when reading is being done in DMA … (#1894)
* ESP32(SPI): Disable the write side when reading is being done in DMA mode

* disable and re-enable MISO and MOSI in write and transfer methods

* changelog
2024-08-07 13:23:49 +00:00
Jesse Braham
56d8d58443
Deny Rust 2018 idioms in esp-hal (#1901) 2024-08-06 15:59:41 +00:00
Jonathan
94db708f49
Touch support for ESP32 (#1873)
* Added touch pad support

* touch: Introduced blocking mode

* touch: moved fns out of TouchPad to prepare async code

* touch: added async support and embassy example
2024-08-06 07:19:41 +00:00
Gavin Li
3049f2804a
esp-wifi/ble/npl: increase event queue size (#1891)
With my ESP32-C6 device, I saw the following panic when scanning was
enabled and there were many BLE devices in vicinity:

    unwrap of `EVENT_QUEUE.enqueue((*event).dummy as usize)` failed: 14,

This occurs because the NPL event queue has overflowed. I increased the
queue size from 10 to 16, and the panic went away. I also did some
testing and discovered that there were at most 13 elements on the queue
at any given time, so a queue size of 16 (which allows for 15 elements)
should give us some margin. This also gives a slight overhead reduction
as the heapless crate recommends the queue size to be a power of two.

Co-authored-by: Gavin Li <git@thegavinli.com>
2024-08-05 21:50:41 +00:00
Juraj Sadel
c5ea0e9149
esp-hal: Add HIL test for embassy timer and executor (#1886)
* esp_hal: Add embassy timers and executors HIL test

* Add timeout to each test

* cfg-gate out systimer tests for ESP32
2024-08-05 21:49:57 +00:00
Sergio Gasquez Arcos
0c29c4381c
ci: Use stable channel for RISCV devices (#1896) 2024-08-01 17:42:49 +00:00
Sergio Gasquez Arcos
40d5481edd
ci: Disable test_asymmetric_dma_transfer for S3 (#1888) 2024-07-31 15:47:44 +00:00
Jesse Braham
311f0127de
Implement embedded_io::{ReadReady, WriteReady} traits for WifiStack (#1882)
* implement `ReadReady` and `WriteReady` traits from `embedded-io` for Wi-Fi

* Allow non-static lifetime for `WifiStack`

* Update `CHANGELOG.md`

* clippy
2024-07-31 07:29:10 +00:00
Jesse Braham
81f3776aa7
Deny warnings in CI (#1877)
* Deny warnings when building in CI

* Build RISC-V using `stable` release channel again
2024-07-30 07:38:57 +00:00
liebman
dd2e475f00
lcd_cam: i8080 fix bad len calculation (missed from ReadBuffer update) (#1876) 2024-07-29 15:13:59 +00:00
liebman
67bb6c54bb
Implement async for lcd_cam i8080 (#1834)
* implement async for lcd_cam i8080

* lcd_cam: implement InterruptConfigurable for blocking and improve async

* lcd_cam: use new async interrupt semantics from #1835

* lcd_cam: move interrupt handler binding into `new_async()`

* lcd_cam: Instance::is_listening_lcd_done not used

* i8080: no need for seperate `new_async()`

* i8080: don't use DmaTxFuture, just test for dma error after complete

* add HIL tests for LCD_CAM i8080 in blocking and async.

* lcd_cam_i8080: test channels configured for async as well since teh compiler can't prevent it for now

* fmt :-/

* lcd_cam fix comment

* changelog

* lcd_cam async: no need to enable interrupts until polled

* lcd_cam: i8080 update for ReadBuffer changes
2024-07-29 13:59:52 +00:00
Björn Quentin
56806313bd
Fix time_driver (#1875)
* Fix time_driver

* CHANGELOG.md
2024-07-29 13:48:11 +00:00
Alexandra Clifford
36ed7bdf14
Adds temporary fix for rcv frame panic issue (#1862) 2024-07-29 07:36:39 +00:00
Jesse Braham
237804efb6
Add a new constructor to gpio::Io which does not bind an interrupt handler (#1861)
* Add a new constructor to `gpio::Io` which does not bind an interrupt handler

* Update `CHANGELOG.md`
2024-07-26 13:28:00 +00:00
Dominic Fischer
2744a5dd86
SPI: Clear DMA interrupts before (not after) DMA starts (#1859)
* SPI: Clear DMA interrupts before (not after) DMA starts

* Fix Rust 1.80 doc thingy

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-07-26 08:51:39 +00:00
Björn Quentin
c6207c0f59
Lift static requirement on DMA buffers (#1837)
* Lift `static` requirement on DMA buffers

* Seal `Word`, use `size_of_val`

* Fix

* CHANGELOG.md

* Use Clippy's safety comment style

* Top-level docs regarding mem::forget
2024-07-25 13:55:02 +00:00
Jesse Braham
45db1b55ec
Add #![deny(missing_docs)] to the aes, analog, clock, and dma modules (#1849)
* Deny missing documentation within the `analog` module

* Deny missing documentation in the `dma` module

* Remove unused `ENCRYPT_MODE`/`DECRYPT_MODE` constants from `AesFlavour` trait

* Deny missing documentation in the `aes` module

* Deny missing documentation in the `clock` module

* Update `CHANGELOG.md`
2024-07-25 13:05:59 +00:00
Jesse Braham
3215d93f53
Use peripheral ref pattern for OneShotTimer and PeriodicTimer` (#1855)
* Use the peripheral ref pattern for `OneShotTimer` and `PeriodicTimer`

* Update tests and examples to reflect changes in timer API

* Update `CHANGELOG.md`
2024-07-25 12:52:34 +00:00
liebman
c7218fba2b
Implement DMA to/from psram on esp32s3 (#1827)
* initial non-working attemt for dma from psram on esp32s3

* flush cache - now works for extmem as source but not for extmem as destination

* use cache_invalidate_addr on destination address

* update changelog

* require dma transfers to/from psram to be aligned to dcache line size

* cache_writeback_addr() should suspend/resume dcache autoload

* no need for cfg(esp32s3) in esp32s3 specific module

* dma: document alignment requirements for DMA to/from PSRAM

* fix doc typos
2024-07-25 12:51:02 +00:00
Björn Quentin
7f251b457a
Fix i2c freeze (#1847)
* Check errors while waiting for TXFIFO_WM

* Limit iterations in `wait_for_completion`

* Detect errors in async-I2C

* CHANGELOG.md

* async `wait_for_completion` ESP32 special treatment

* Simplify ESP32 workaround

* Clippy
2024-07-24 15:09:46 +00:00
Dominic Fischer
4ef91c5941
Change semantics of DMA futures (#1835)
* Change semantics of DMA futures

* Only clear specific interrupt bit when listening for an "in progress" interrupt

* Fix PARL_IO Rx

* Only enable interrupts when future is polled

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-07-24 14:26:39 +00:00
Björn Quentin
38f1d28585
Fix async PARL_IO RX (#1851)
* Fix async PARL_IO RX

* CHANGELOG.md
2024-07-24 13:19:19 +00:00
Juraj Sadel
3299348ebc
esp_hal: Warnings in examples cleanup (#1852) 2024-07-24 13:18:50 +00:00
Scott Mabin
e8b0a376eb
Check all features and targets in CI when linting (#1824)
* Check more features and targets in CI when linting

* Address clippy lints

* Address clippy lints for esp-wifi

* Expand println and storage checks

* Remove uneeded clippy lint

* Check every package for each target

* resolve esp-wifi clippy lints

* use defmt when building esp-wifi

* clean up

* fix warning in meta crate

* simplify CI workflow

* split up clippy jobs
2024-07-24 11:45:41 +00:00
BMCG0011
5d6354ccbd
Expose InputPin.is_interrupt_set in implementation of esp-hal::gpio::… (#1839)
* Expose InputPin.is_interrupt_set in implementation of esp-hal::gpio::Input

* Move entry in changelog from changed to added
2024-07-23 19:47:59 +00:00
Björn Quentin
426c8fb0bd
Improve Xtensa backtraces (#1838) 2024-07-23 19:47:46 +00:00
Björn Quentin
8be7f81e34
usb-serial-jtag example: Hint for Windows users (#1845) 2024-07-23 19:23:35 +00:00
Björn Quentin
d5bff95a1b
Fix I2s async-tx (#1833)
* Fix I2s async-tx

* CHANGELOG.md

* Add async i2s test

* Cleanup

* Use `Spawner::for_current_executor()` instead of manually creating the executor
2024-07-23 18:09:58 +00:00
Scott Mabin
c090191afb
try to fix espflash command not found in HIL CI (#1848)
* try to fix espflash command not found in HIL CI

* Specify espflash port

---------

Co-authored-by: Juraj Sadel <juraj.sadel@espressif.com>
2024-07-23 17:38:44 +00:00
Björn Quentin
1424f2a43d
Implement InterruptConfigurable (#1819)
* Implement `InterruptConfigurable`

* Fix doc-tests

* Clippy

* Fix lp_core_uart example

* CHANGELOG.md

* Have DEFAULT_INTERRUPT_HANDLER

* Fix docs

* Clippy

* Add `set_interrupt_handler` for WDT
2024-07-18 13:37:46 +00:00
Juraj Sadel
bc7c53f668
esp-hal: Remove duplicated branch in ESP32 PSRAM (#1830) 2024-07-18 11:22:46 +00:00
Björn Quentin
917756a7bf
Prettier panic message printing (#1823)
* Prettier panic message printing

* CHANGELOG.md
2024-07-18 09:32:53 +00:00
Jesse Braham
776f34cff1
Re-export the esp_hal_procmacros::main macro from esp-hal-embassy instead of esp-hal (#1828)
* Re-export the `main` procmacro from `esp-hal-embassy` rather than `esp-hal`

* Fix documentation warnings

* Flatten the `time_driver` module

* clippy

* Update `CHANGELOG.md`
2024-07-18 09:31:03 +00:00
dimpolo
02c99786f9
esp-backtrace: Add custom-pre-backtrace feature (#1822) 2024-07-18 07:38:40 +00:00
dimpolo
0eb30c5286
make esp_println::Printer::write_bytes public again (#1812) 2024-07-18 06:16:46 +00:00
Sergio Gasquez Arcos
32be53d618
CI Improvements - Part 1 (#1821)
* ci: Fix condition to erase-flash

See https://docs.github.com/en/actions/learn-github-actions/expressions#example-of-failure-with-conditions

* ci: Remove path-ignore attributes to avoid CI not being triggered

* ci: Build documentation

* ci: Install nightly toolchain

* ci: Deny warnings for building docs

* fix: Documentation warnings

* ci: Remove duplicated step
2024-07-17 15:55:27 +00:00
Björn Quentin
2c8bb07be2
Prepare esp-wifi 0.7.1 (#1820)
* Prepare esp-wifi 0.7.1

* CHANGELOG.md
2024-07-17 10:57:15 +00:00
Juraj Sadel
884db5aa32
esp-hal: Add (where missing) used GPIOs to example descriptions (#1810)
* esp-hal: Add (where missing) used GPIOs to example descriptions

* review comments
2024-07-17 08:34:13 +00:00
Jesse Braham
e33b060734
Add xtensa-lx and xtensa-lx-rt packages (#1813)
* Add the `xtensa-lx` package

* Add the `xtensa-lx-rt` and `xtensa-lx-rt-proc-macros` packages

* Exclude new packages from workspace, add to `xtask::Package`

* rustfmt

* clippy
2024-07-17 08:32:52 +00:00
Kirill Mikhailov
14baad4625
Remove raw addresses usage (part 1) (#1795) 2024-07-16 14:11:05 +00:00
Björn Quentin
37299237cb
esp-wifi: Check no password given for AuthMethod::None (#1806)
* esp-wifi: Check no password given for AuthMethod::None

* CHANGELOG.md
2024-07-16 13:46:22 +00:00
Scott Mabin
04cad71926
bump esp-backtrace to 0.13.0 (#1804)
* bump esp-backtrace to 0.13.0

* disable spi_half_duplex_write for esp32s2
2024-07-16 13:19:16 +00:00
Dominic Fischer
31a135c0f1
Add SPI Half Duplex Write HIL test (#1801)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-07-16 10:19:16 +00:00
Dominic Fischer
6fd9443c13
Allow users to easily name DMA channels (#1771)
* Introduce public DmaChannel trait

* Use DmaChannel trait in all peripherals

* Simplify ChannelTypes trait

* changelog

* Rename things

* missed a spot

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-07-16 08:52:48 +00:00
Jesse Braham
af1febfb8c Begin next release cycle 2024-07-15 22:56:31 +00:00
Jesse Braham
eddcb7354f
Actually bump the esp-hal version number (oops) (#1802) 2024-07-15 22:17:15 +00:00
Jesse Braham
77b6cb8615
New package releases (#1800)
* Use published versions of all dependencies, update dependencies as needed

* Fix `embassy_usb_serial` example build errors after updating `embassy-usb`

* New package releases
2024-07-15 20:23:13 +00:00
Sergio Gasquez Arcos
7ea471c1ac
Remove unnecessary delay (#1794)
* fix: Remove unnecesary delay

* docs: Update changelog

* fix: Remove unused variable

* fix: Remove clippy warning from examples
2024-07-15 13:09:47 +00:00
liebman
10c900a53f
gpio: DummyPin + hub75_i8080 example (#1769)
* gpio: DummyPin + hub75_i8080 example

* changelog

* cmall cleanup in the example

* reduce memory usage by 50% by using i8080 pixel clock

* updated to latest git hal version

* remove complex hub75 example

* remove complex hub75 example dep
2024-07-15 12:39:14 +00:00
liebman
1631f22083
support dma chunk sizes other than 4092 (#1758)
* support dma chunk sizes other than 4092

* fmt

* update CHANGELOG

* fix 0 size static assert

* review changes:
- `.div_ceil()`
- return errors for bad chunk size and buffer sizes in Mem2Mem constructors
- correct 0 chunk size check in descripter macros

* dma: clear the mem2mem bit when channel is configured instead of in Drop
2024-07-15 12:00:33 +00:00
Björn Quentin
7e981a5376
Fix reading/writing small buffers (#1760)
* Fix reading/writing small buffers

* CHANGELOG.md
2024-07-15 11:06:03 +00:00
Juraj Sadel
45c8107ecd
esp-hal: remove warnings in PCNT example and HIL test (#1793) 2024-07-15 10:49:39 +00:00
Dominic Fischer
0cae79b4cc
Improve PCNT API (with HIL tests) (#1765)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-07-15 09:31:35 +00:00
Jesse Braham
0363169084
Remove unnecessary build dependency from esp-backtrace (#1788) 2024-07-12 15:07:37 +00:00
Jesse Braham
bc74e2bb61
Add additional public functions to esp-lp-hal for Delay and UART, deny missing documentation (#1789)
* Add `Delay.delay_millis` function

* Provide basic UART functionality without requiring `embedded-hal`/`embedded-io` traits

* Deny missing documentation

* Update `CHANGELOG.md`
2024-07-12 14:56:34 +00:00
Sergio Gasquez Arcos
7e9f9c7528
Update module documentation - Part 2 (#1777)
* docs: Update assist debug mod documentation

* docs: Update delay  mod documentation

* docs: Update ecc  mod documentation

* docs: Update hmac mod documentation

* docs: Update i2c mod documentation

* docs: Update i2s mod documentation

* docs: Update usb otg mod documentation

* docs: Update parl_io mod documentation

* docs: Update peripheral mod documentation

* docs: Update prelude mod documentation

* docs: Update reset mod documentation

* docs: Update rmt mod documentation

* docs: Update rng mod documentation

* docs: Update sha mod documentation

* docs: Update system, time and trace mod documentation

* docs: Update uart mod documentation

* docs: Update usb_serial_jtag mod documentation

* docs: Add modules documentation format

* docs: Address feedback

* style: Format documentation
2024-07-12 09:48:45 +00:00
Jesse Braham
dcc6c896de
Housekeeping: fix warnings, rename some examples, etc. (#1786)
* Build HIL tests for ESP32 in CI, fix resulting build errors

* Fix some warnings in the `hil-test` package

* Fix warnings in examples

* Remove "esp_" prefix from Wi-Fi example file names

* Resolve the last of the known warnings
2024-07-12 09:35:55 +00:00
Dominic Fischer
bb8660d3c5
Add SPI Half Duplex Read HIL test (#1782)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-07-11 12:55:59 +00:00
Scott Mabin
6c3ccb6043
Add read_bytes method to uart (#1784)
* Add read_bytes method to uart

* Changelog
2024-07-11 12:55:42 +00:00
W Etheredge
a2883ac318
Take 2 on #[ram] soundness (#1677)
* Improve `#[ram]` soundness

* Allow `Atomic*` in `#[ram(persistent)]`

---------

Co-authored-by: Scott Mabin <scott@mabez.dev>
2024-07-10 13:30:48 +00:00
Jesse Braham
2bef914e7c
Update and improve esp-lp-hal (#1754)
* Fix warning in `esp-hal-procmacros` when building for `esp-lp-hal`

* Document cargo features, use `embedded-hal@1.x.x` by default

* Derive more traits on public types, assorted cleanup and improvements

* Implement `embedded-hal-nb` and `embedded-io` traits for UART

* Update `CHANGELOG.md`

* Silence `clippy` for now...

* Module documentation for UART

* Update module documentation format
2024-07-09 17:06:54 +00:00
Jesse Braham
eb9bfd52b1
Fix clippy warning in esp-wifi, remove Cargo patch and update semihosting dependency (#1778)
* Update `semihosting` dependency and remove Cargo patch

* Fix clippy error in `esp-wifi`
2024-07-09 09:50:09 -07:00
Björn Quentin
a5be31fadc
Improve and use timer abstractions (#1753)
* Make esp-wifi timer agnostic

* Use timer-abstractions in embassy time driver

* Refactor

* Fix

* Fix

* Docs

* Adapt examples

* Adapt tests

* Refactoring

* Changelogs

* Fix example

* Adapt xtask

* Make CI pass

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-07-09 15:59:38 +00:00
Sergio Gasquez Arcos
8e0a2012dc
Update module documentation (#1763)
* docs: Update GPIO docs

* docs: Update other GPIO modules docs

* docs: Update AES mod documentation

* docs: Update Analog and ADC mod documentation

* docs: Update DAC mod documentation

* docs: Update lib docs

* docs: Update clock  mod documentation

* docs: Update dma  mod documentation

* docs: Update interrupt  mod documentation

* docs: Update lcd_cam  mod documentation

* docs: Update ledc  mod documentation

* docs: Update mcpwm mod documentation

* docs: Update pcnt mod documentation

* docs: Update rom mod documentation

* docs: Update rsa mod documentation

* docs: Update rtc_cntl mod documentation

* docs: Update spi mod documentation

* docs: Update timer mod documentation

* docs: Update twai mod documentation

* docs: Format headers

* style: Fix fmt

* refactor: Change visibility instead of hidding docs

* style: Fix header

* Fix typo

Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>

* Fix typo

Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>

* Fix typo

Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>

* Fix typo

Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>

* Fix typo

Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>

* docs: Add tracking issue

* docs: Remove architecture and simplify sentence

* fix: Update visibilities remove hidden docs

* Fix type

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>

* docs: Improve wording

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>

---------

Co-authored-by: Juraj Sadel <jurajsadel@gmail.com>
Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-07-09 15:40:31 +00:00
Juraj Sadel
d5b6c850f9
esp-hal: ESP32 typo in cfg-gate in embassy_i2s_read example (#1775) 2024-07-09 13:48:08 +00:00
Scott Mabin
e75d43d3f0
Fix new clippy lints introduced in 1.78 & 1.79 (#1776)
* Fix new clippy lints introduced in 1.78 & 1.79

* Patch semihosting
2024-07-09 13:23:19 +00:00
Kirill Mikhailov
eb54168228
Update CONTRIBUTING.md (#1311) 2024-07-09 14:37:44 +02:00
Grant Moyer
dfe628c53d
Fix UsbDm and UsbDp for Gpio19 and Gpio20 (#1764)
GPIO pins 19 and 20 had USB D- and D+ swapped. This change fixes which pin is which USB data line according to the pin descriptions in the ESP32-S2 and ESP32-S3 data sheets (sections 2.2 and 2.3.2 respectively). Since these GpioPins are only used by Usb for lifetime tracking, and UsbDp and UsbDm are always used as a pair, this change is only semantic and doesn't affect functionality.
2024-07-08 13:37:57 +00:00
Kirill Mikhailov
253b013c2a run-doc-test README entry 2024-07-08 13:34:09 +00:00
Sergio Gasquez Arcos
ea34196d8d
Properly update the Uart config in examples (#1759)
* fix: Properly update the config

* feat: Make rx_timeout optional

* docs: Update changelog
2024-07-08 09:30:45 +00:00
Jesse Braham
967c478846 Update CHANGELOG.md 2024-07-05 13:09:09 +00:00
Jesse Braham
bb4321838e Prevent multiple versions of esp-println from being included in the dependency tree 2024-07-05 13:09:09 +00:00
Nathan Henrie
dc4ddcb3fe
Fix broken link to embassy book (#1756) 2024-07-05 08:27:00 +00:00
Kirill Mikhailov
163f45076e
Enable i2s HIL test for esp32h2 (#1755)
Delete invalid comment
2024-07-04 15:28:37 +00:00
Jonas Spinner
c4ad9d37ab Fix docs.rs link in esp-wifi/README.md 2024-07-04 12:37:52 +00:00
Kirill Mikhailov
921ecc4d56
Feature: correct TRNG mechanism (#1538)
* interstate

* Use type-state over creating new struct

* Getting revert_trng function into the driver

* Finish revert functions

* More progress

* Adjust for new driver release

* Small fixes

fmt

* Fmt + clippy + changelog

* Comments, `RngCore` trait for `Trng`

* fmt

* Make ADC work correctly on TRNG drop, PAC functions instead of raw regs

* Get docs buildable

rustfmt

* Doc comments fix

fmt

* Fix docs for esp32

* Small fixes + exclude `downgrade` and `drop` for `esp32c6`

Downgrade for `esp32c6` is not implemented so far

* TRNG/ADC on `esp32c6` warning comment
2024-07-04 09:03:53 +00:00
Sergio Gasquez Arcos
786682c0b2
HIL: Erase flash on failure (#1748)
* ci: Erase flash on failure

* docs: Add espflash install instructions and fix format
2024-07-04 07:50:40 +00:00
Dominic Fischer
c62bd8b332
Add PCNT HIL test (#1746)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-07-04 06:23:14 +00:00
liebman
cc7077624c
dma: add Mem2Mem to support memory to memory transfer (#1738)
* dma: add Mem2Mem to support memory to memory transfer

* fmt

* update CHANGELOG

* removed some debugging

* use "gdma" as the selector for support

* fix empty else

* clippy

* Mem2Mem::new now accepts the peripheral to use

* mark Mem2Mem::new() unsafe

* fmt :-/

* add Mem2MemN values for gdma on non-esp32s3
tested on esp32c3,esp32c6 (will have an esp32h2 in a few days)

* support the esp32c2 (esp8684)

* DmaEligible trait providing dma peripheral value & safe constructor for Mem2Mem dma.

* added hil-test for Mem2Mem

* fmt dma_mem2mem test

* remove `debug!()`

* reset the mem2mem bit (mem_trans_en) in in_conf0 on drop
2024-07-03 17:56:37 +00:00
Björn Quentin
4f9dc960c6
Improve xtensa interrupt latency (#1735)
* Avoid U128

* Avoid unnecessary calls

* CHANGELOG.md

* Simplify

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-07-03 15:43:01 +00:00
Kirill Mikhailov
cd0272ee81 Make links be in the same format 2024-07-03 12:53:17 +02:00
Kirill Mikhailov
f177b945b7 docs: Add missing link to HIL README 2024-07-03 12:53:17 +02:00
Björn Quentin
63ef16fae6
Fix set_protocol (#1742)
* Fix `set_protocol`

* CHANGELOG.md

* Clippy
2024-07-03 08:16:00 +00:00
Björn Quentin
cc08da2ad8
Improve the top level crate documentation (#1733)
* Improve the top level crate documentation

* More detailed PeripheralRef explanation
2024-07-03 07:37:33 +00:00
Dominic Fischer
fc826caf18
Expose optional HSYNC input in LCD_CAM (#1707)
* Expose optional HSYNC input in LCD_CAM

* Fix DMA wait check in LCD_CAM

---------

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-07-02 16:56:53 +00:00
Kirill Mikhailov
bdd3e93de2
Fix regi2c_* functions for esp32h2 (#1737)
* Fix `regi2c_*` functions for `esp32h2`

* Changelog entry
2024-07-01 13:26:10 +00:00
Björn Quentin
40810a5c1d
Add UART wakeup source (#1727)
* Add UART wakeup source

* CHANGELOG.md
2024-07-01 06:43:36 +00:00
Sergio Gasquez Arcos
3af45a2ed0
Update changelog CI (#1725)
* docs: Add missing changelogs and unify format

* ci: Check changelog update for all the packages

* ci: Update actions/checkout version
2024-06-28 14:15:01 +00:00
Sergio Gasquez Arcos
60b9d5c704
fix: Update probe-rs arguments for run-elfs subcommand (#1734) 2024-06-28 13:42:30 +00:00
Björn Quentin
8cb921f73b
Add GPIO as wake-up source (#1724)
* Add GPIO as wake-up source

* CHANGELOG.md

* Clippy

* Doc fix
2024-06-28 11:14:29 +00:00
Björn Quentin
347ef5188b
ESP32-C6: Support wake-up from lp-core (#1723)
* ESP32-C6: Add wake from lp-core

* lp-hal PAC update

* Update PAC dependency for lp-hal

* CHANGELOG.md

* CHANGELOG.md

* Clippy
2024-06-28 07:11:31 +00:00
Jesse Braham
4ca2398bc1
Documentation and housekeeping for esp-ieee802154 (#1730)
* Derive more traits on public types

* Document cargo features

* Minor documentation updates, remove an unused struct field
2024-06-28 07:00:15 +00:00
Sergio Gasquez Arcos
d0cd890e51
Update some modules documentation (#1726)
* docs: Add inverting documentation and examples

* docs: Update I2C mod docs

* docs: Update LEDC documentation

* docs: FIx format

* Fix a typo in docstring in `esp-hal/src/uart.rs`

---------

Co-authored-by: Jesse Braham <jessebraham@users.noreply.github.com>
2024-06-27 16:50:30 +00:00
Fan Jiang
565faf723b
Fix ESP32-S3 ROM address of ets_update_cpu_frequency_rom (#1722)
Co-authored-by: Sergio Gasquez Arcos <sergio.gasquez@gmail.com>
2024-06-26 15:59:57 +00:00
Björn Quentin
891d476de1
ESP32-C6: make basic light sleep work (#1720)
* ESP32-C6: make basic light sleep work

* CHANGELOG.md
2024-06-26 15:30:27 +00:00
Dominic Fischer
7753551671
[2/3] DMA Move API: Move DMA descriptors to peripheral drivers (#1719)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-06-26 14:31:41 +00:00
Sergio Gasquez Arcos
e46e80b8c1
Enable C2 HIL (#1680)
* ci: Enable c2 hil

* docs: Update pins and add C2

* feat: Update C2 probe-rs args

* test: Update pins and disable failing tests

* docs: Update S3 wires

* ci: Enable C2 hil tests
2024-06-26 14:17:40 +00:00
Jesse Braham
c9925b7f6d
Don't include dependencies in generated documentation when building with xtask (#1713) 2024-06-26 07:43:25 +00:00
Dominic Fischer
0b5eb1f00e
[1/3] DMA Move API: Pull out driver specific state in DMA driver into separate structs (#1716)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-06-25 13:14:54 +00:00
Dominic Fischer
9d5fb31c4b
TIMG: Fix interrupt handler setup (#1715)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-06-25 13:01:40 +00:00
Alex Vinyals
d4ec063cec
esp-wifi(initialize): no longer requires maximum CPU clock (#1688)
This patch replaces a CPU clock check that enforced running the MCU
at maximum clock speed during WiFi radio initialization. The previous
was incompatible for low power settings.

Now, the check ensures the CPU runs with at *at least* 80MHz, which
is the minimum required clock speed for proper WiFi radio functionality.

For `esp32s3` MCUs, the call to `ets_update_cpu_frequency_rom` has been
moved to the `esp-hal` clocks module. This call is now only made when
configuring CPU to a non-default setting.
2024-06-25 07:42:11 +00:00
Björn Quentin
fd467c2f07
Fix wifi-logs feature (#1709) 2024-06-24 13:45:46 +00:00
Demo for summer'23
c864c8a982
Fix: allow defmt-espflash + auto configuration @ esp-println (#1687)
* esp-println: Fix 'defmt-espflash,auto' feature combination

* formatted according to instructions

* restructure, compiles also on 'esp32'

* Added CI check for compiling with 'dfm-espflash' feature

---------

Co-authored-by: Asko Kauppi <akauppi@gmail.com>
2024-06-24 13:26:08 +00:00
Felix Wirth
9691141fed
implement embedded_io::ReadReady for Uart & UartRx (#1702)
* implement `embedded_io::ReadReady` for `Uart` & `UartRx`

* update CHANGELOG.md
2024-06-21 16:01:40 +00:00
Dominic Fischer
eee20de116
Patch up LCD_CAM example (#1701)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-06-20 13:27:50 +00:00
Björn Quentin
13d6b517d8
Improve RISC-V interrupt latency (#1679)
* Improve RISC-V interrupt latency

* CHANGELOG.md

* Clippy
2024-06-19 16:36:28 +00:00
Dominic Fischer
bb806d35e0
Add remaining GPIO pins for ESP32-S2/S3 ULP (#1695)
Co-authored-by: Dominic Fischer <git@dominicfischer.me>
2024-06-19 15:17:48 +00:00
Sergio Gasquez Arcos
2c03266061
Prepare esp-backtrace@0.12.1 release (#1696)
* build: Bump version

* docs: Update changelog
2024-06-19 14:42:49 +00:00
Björn Quentin
d34a872230
Additional move base dma api (#1672)
* Additional owning DMA transfers for SPI half-duplex

* CHANGELOG.md

* CHANGELOG.md

* Clippy
2024-06-19 13:17:22 +00:00
Björn Quentin
1630868d06
Improve DMA pop implementation (#1664)
* Improve DMA `pop` implementation

* CHANGELOG.md

* Minor Fixes

* Cover more edge-cases in DMA pop, make sure the test is testing these

* Fixes

* Working available/pop

* Remove misleading `last_in_dscr_address`

* Remove unnecessary check from `available`

* Remove now-unused function

* Remove duplicate change-log entry
2024-06-19 12:51:24 +00:00
Jesse Braham
2d90fa3021
Make esp-wifi build when using the defmt feature with +stable toolchain (#1691) 2024-06-18 15:50:46 +00:00
Scott Mabin
0d418fe837
esp-bracktrace: only print float registers on chips that have them (#1690)
* only print float registers on chips that have them

* Add CHANGELOG.md
2024-06-18 15:01:53 +00:00
Kaspar Schleiser
152c0180df
esp-hal-wifi: make executors optional (again) (#1683)
* esp-hal-wifi: make executors optional (again)

* esp-wifi: don't use default-features of `esp-hal-embassy`
2024-06-17 10:23:31 +00:00
Björn Quentin
bd711517f3
esp-backtrace: Fix for nightly after 2024-06-12 (#1681)
* esp-backtrace: Fix for nightly after 2024-06-12

* Fix

* Fix defmt
2024-06-17 08:55:54 +00:00
Björn Quentin
65b956d6a8
Fix mk_static macro (#1674) 2024-06-12 15:09:43 +00:00
Andres O. Vela
05076697ec
Rename PSRAM examples for better discoverability (#1675) 2024-06-12 14:23:55 +00:00
Andres O. Vela
fb90fe780c
esp-hal: fix esp32-s3 psram docs (#1673) 2024-06-12 13:52:50 +00:00
Sergio Gasquez Arcos
e7f8f50e82
Update embedded-tests and wiring docs (#1652)
* build: Update embedded-test

* docs: Update probe-rs version

* docs: Revert probe-rs update

* docs: Update wiring

* docs: Update source command
2024-06-12 10:12:04 +00:00
Sergio Gasquez Arcos
d2a93894f5
feat: Avoid using a macro for default pins (#1671) 2024-06-11 15:49:44 +00:00
Björn Quentin
1122df15e2
Check DMA descriptors and buffers addresses (#1670)
* Check DMA descriptors and buffers addresses

* Add PR id

* Add test for the memory region check

* Clippy
2024-06-11 14:42:46 +00:00
Sergio Gasquez Arcos
a33159a021
Rework Uart constructors, add UartTx and UartRx constuctors. (#1592)
* feat: Add with_pins methods for UART

* feat: Remove configure_pin methods

* docs: Update changelog

* fix: Update tests and examples

* style: Fix format

* Add UartTx/Rx constructors

* feat: Add new_with_default_pins methods

* docs: Update changelog

* feat: Remove optional cts/rts arguments

* feat: Add UartTx/Rx::new_async methods

* fix: Attach interrupt handler to new_ascyn UartRx/Tx

* style: Avoid long module paths

* feat: Make flush_tx public

* test: Use Uart async instead of UartTx/Rx async

* test: Add tests for UartTx/UartRx

* feat: Add configuration method to constuctors

* feat: Move set_rx_fifo_full_threshold and set_rx_timeout to UartRx

* docs: Fix changelog

* test: Fix executor

* feat: Configure UartRx threshold and timeout

* docs: Update changelog

* test: Update uart instance

* feat: Add default_uart0_pins macro to simplify examples

* feat: Address feedback pt1

* feat: Address feedback pt2 - Make constructors fallible

* fix: Doctest
2024-06-11 13:07:17 +00:00
Juraj Sadel
4c5e493b1b
esp-hal: Add runnable doctests to peripheral drivers (#1663)
* Check docs examples II

* rebase and update

* fix root crate macro expansion in doctest snippets

* clean up and fmt

* add xtask run-doc-test subcommand and check in CI

* address review comments

* remove commented printlns

* fix the host target check

* rebase and update

* hide docs for before_snippet macro and remove commented block code in twai
2024-06-11 10:18:09 +00:00
Björn Quentin
b8af24071e
Add Flex/AnyFlex pin drivers (#1659)
* Add Flex/AnyFlex pin drivers

* CHANGELOG.md
2024-06-10 15:23:55 +00:00
Jesse Braham
dc8e0a6496
Refactor Dac1/Dac2 drivers into a single Dac driver (#1661)
* Refactor `Dac1`/`Dac2` drivers into a single `Dac` driver

* Fix unrelated build errors resulting from updated PACs

* Add new `Instance` trait to `prelude` module, update `dac` example

* Update `CHANGELOG.md`

* Fix example in module documentation

* Turns out these are 0-indexed after all
2024-06-10 13:52:00 +00:00
Björn Quentin
fd4676d434
Add RMT hil-test (#1665)
* Add RMT hil-test

* Fix compilation error on ESP32/ESP32-S2
2024-06-07 10:31:42 +00:00
Björn Quentin
e680900f50
esp-backtrace: Fix warning when using semihosting feature (#1667) 2024-06-07 09:49:59 +00:00
Dominic Fischer
a20054c90c
Fix misuse of INT_CLR (#1651)
* Fix misuse of INT_CLR

* Use LCD_START instead of interrupt to check for completion
2024-06-05 13:40:55 +00:00
Björn Quentin
f125c20cf2
Add auto-detection feature to esp-println (#1658)
* Add auto-detection feature to esp-println

* CHANGELOG.md

* Minor README change

* Build `esp-println` in CI
2024-06-05 10:44:17 +00:00
Jesse Braham
8a47e4254f Begin next release cycle 2024-06-04 16:48:59 +00:00
665 changed files with 88313 additions and 45114 deletions

View File

@ -1,2 +1,4 @@
[alias]
xtask = "run --package xtask --"
xfmt = "xtask fmt-packages"
qa = "xtask run-example qa-test"

31
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,31 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ["bug", "status:needs-attention"]
assignees: ''
---
## Bug description
<!-- A clear and concise description of what the bug is. -->
## To Reproduce
<!-- Steps to reproduce the behavior. -->
1. ...
2. ...
<!-- Please share the minimal repro of the issue where the bug can be reproduced. -->
<!-- Make sure you are able to reproduce the bug in the `main` branch, too. -->
## Expected behavior
<!-- A clear and concise description of what you expected to happen. Attach screenshots if needed. -->
## Environment
- Target device: [e.g. ESP32-S3] <!-- Use `espflash board-info` to get the target device iformation. -->
- Crate name and version: [e.g. esp-hal 0.20.0]

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Ask questions in Matrix channel (Recommended)
url: https://matrix.to/#/#esp-rs:matrix.org
about: Ask any questions directly in our Matrix channel.
- name: Ask questions in GitHub Discussions
url: https://github.com/esp-rs/esp-hal/discussions/new
about: Post your questions and engage in discussions via GitHub.

View File

@ -0,0 +1,24 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ["enhancement", "status:needs-attention"]
assignees: ''
---
## Motivations
<!-- If your feature request is related to a problem, please describe it. -->
## Solution
<!-- Describe the solution you'd like. -->
## Alternatives
<!-- Describe any alternative solutions or features you've considered. -->
## Additional context
<!-- Add any other context or screenshots about the feature request here. -->

View File

@ -7,10 +7,11 @@ To help us review it efficiently, please ensure you've gone through the followin
- [ ] I have updated existing examples or added new ones (if applicable).
- [ ] I have used `cargo xtask fmt-packages` command to ensure that all changed code is formatted correctly.
- [ ] My changes were added to the [`CHANGELOG.md`](https://github.com/esp-rs/esp-hal/blob/main/esp-hal/CHANGELOG.md) in the **_proper_** section.
- [ ] My changes are in accordance to the [esp-rs API guidelines](https://github.com/esp-rs/esp-hal/blob/main/API-GUIDELINES.md)
- [ ] I have added necessary changes to user code to the [Migration Guide](https://github.com/esp-rs/esp-hal/blob/main/esp-hal/MIGRATING-0.21.md).
- [ ] My changes are in accordance to the [esp-rs API guidelines](https://github.com/esp-rs/esp-hal/blob/main/documentation/API-GUIDELINES.md)
#### Extra:
- [ ] I have read the [CONTRIBUTING.md guide](https://github.com/esp-rs/esp-hal/blob/main/CONTRIBUTING.md) and followed its instructions.
- [ ] I have read the [CONTRIBUTING.md guide](https://github.com/esp-rs/esp-hal/blob/main/documentation/CONTRIBUTING.md) and followed its instructions.
### Pull Request Details 📖

View File

@ -0,0 +1,68 @@
name: Build and Check
description: Build and check the esp-hal and esp-lp-hal pacakges for a specified device
inputs:
device:
description: "Device SOC"
required: true
target:
description: "Target"
required: true
toolchain:
description: "Toolchain channel"
required: true
runs:
using: "composite"
steps:
- name: Set up cargo environment
shell: bash
run: |
# Convert the target triple from kebab-case to SCREAMING_SNAKE_CASE:
big_target=$(echo "${{ matrix.device.target }}" | tr [:lower:] [:upper:] | tr '-' '_')
# Set the *target specific* RUSTFLAGS for the current device:
echo "CARGO_TARGET_${big_target}_RUSTFLAGS=-Dwarnings" >> $GITHUB_ENV
# Linting toolchain (stable cant build documentation)
if [ "${{ inputs.toolchain }}" == "nightly" ]; then
echo "LINTING_TOOLCHAIN=+nightly" >> $GITHUB_ENV
else
echo "LINTING_TOOLCHAIN=+esp" >> $GITHUB_ENV
fi
# Clippy and docs checks
- name: Clippy
shell: bash
run: cargo $LINTING_TOOLCHAIN xtask lint-packages --chips ${{ inputs.device }}
- name: Check doc-tests
shell: bash
run: cargo $LINTING_TOOLCHAIN xtask run-doc-test esp-hal ${{ inputs.device }}
- name: Check documentation
shell: bash
run: cargo $LINTING_TOOLCHAIN xtask build-documentation --packages esp-hal --chips ${{ inputs.device }}
# Build all supported examples for the low-power core first (if present):
- name: Build prerequisite examples (esp-lp-hal)
shell: bash
if: contains(fromJson('["esp32c6", "esp32s2", "esp32s3"]'), inputs.device)
run: cargo +${{ inputs.toolchain }} xtask build-examples esp-lp-hal ${{ inputs.device }}
- name: Check esp-lp-hal documentation
shell: bash
if: contains(fromJson('["esp32c6", "esp32s2", "esp32s3"]'), inputs.device)
run: cargo $LINTING_TOOLCHAIN xtask build-documentation --packages esp-lp-hal --chips ${{ inputs.device }}
# Make sure we're able to build the HAL without the default features
# enabled:
- name: Build (no features)
shell: bash
run: |
cargo xtask build-package \
--no-default-features \
--toolchain=${{ inputs.toolchain }} \
--features=${{ inputs.device }} \
--target=${{ inputs.target }} \
esp-hal
- name: Build (examples)
env:
CI: 1
shell: bash
run: cargo +${{ inputs.toolchain }} xtask build-examples esp-hal ${{ inputs.device }} --debug
- name: Build (qa-test)
env:
CI: 1
shell: bash
run: cargo +${{ inputs.toolchain }} xtask build-examples qa-test ${{ inputs.device }} --debug

View File

@ -2,8 +2,12 @@ name: Changelog check
on:
pull_request:
# We will not track changes for the `xtask` package.
# We will not track changes for the following packages/directories.
paths-ignore:
- "/examples/"
- "/extras/"
- "/hil-tests/"
- "/resources/"
- "/xtask/"
# Run on labeled/unlabeled in addition to defaults to detect
# adding/removing skip-changelog labels.
@ -15,10 +19,162 @@ jobs:
steps:
- name: Checkout sources
uses: actions/checkout@v3
uses: actions/checkout@v4
- uses: dangoslen/changelog-enforcer@v3
- name: Check which package is modified
uses: dorny/paths-filter@v3
id: changes
with:
filters: |
esp-alloc:
- 'esp-alloc/**'
esp-backtrace:
- 'esp-backtrace/**'
esp-build:
- 'esp-build/**'
esp-config:
- 'esp-config/**'
esp-hal:
- 'esp-hal/**'
esp-hal-embassy:
- 'esp-hal-embassy/**'
esp-hal-procmacros:
- 'esp-hal-procmacros/**'
esp-ieee802154:
- 'esp-ieee802154/**'
esp-lp-hal:
- 'esp-lp-hal/**'
esp-metadata:
- 'esp-metadata/**'
esp-println:
- 'esp-println/**'
esp-riscv-rt:
- 'esp-riscv-rt/**'
esp-storage:
- 'esp-storage/**'
esp-wifi:
- 'esp-wifi/**'
xtensa-lx:
- 'xtensa-lx/**'
xtensa-lx-rt:
- 'xtensa-lx-rt/**'
- name: Check that changelog updated (esp-alloc)
if: steps.changes.outputs.esp-alloc == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-alloc/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-alloc/CHANGELOG.md file."
- name: Check that changelog updated (esp-backtrace)
if: steps.changes.outputs.esp-backtrace == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-backtrace/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-backtrace/CHANGELOG.md file."
- name: Check that changelog updated (esp-build)
if: steps.changes.outputs.esp-build == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-build/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-build/CHANGELOG.md file."
- name: Check that changelog updated (esp-config)
if: steps.changes.outputs.esp-config == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-config/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-config/CHANGELOG.md file."
- name: Check that changelog updated (esp-hal)
if: steps.changes.outputs.esp-hal == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-hal/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the CHANGELOG.md file."
missingUpdateErrorMessage: "Please add a changelog entry in the esp-hal/CHANGELOG.md file."
- name: Check that changelog updated (esp-hal-embassy)
if: steps.changes.outputs.esp-hal-embassy == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-hal-embassy/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-hal-embassy/CHANGELOG.md file."
- name: Check that changelog updated (esp-hal-procmacros)
if: steps.changes.outputs.esp-hal-procmacros == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-hal-procmacros/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-hal-procmacros/CHANGELOG.md file."
- name: Check that changelog updated (esp-ieee802154)
if: steps.changes.outputs.esp-ieee802154 == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-ieee802154/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-ieee802154/CHANGELOG.md file."
- name: Check that changelog updated (esp-lp-hal)
if: steps.changes.outputs.esp-lp-hal == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-lp-hal/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-lp-hal/CHANGELOG.md file."
- name: Check that changelog updated (esp-println)
if: steps.changes.outputs.esp-println == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-println/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-println/CHANGELOG.md file."
- name: Check that changelog updated (esp-riscv-rt)
if: steps.changes.outputs.esp-riscv-rt == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-riscv-rt/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-riscv-rt/CHANGELOG.md file."
- name: Check that changelog updated (esp-storage)
if: steps.changes.outputs.esp-storage == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-storage/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-storage/CHANGELOG.md file."
- name: Check that changelog updated (esp-wifi)
if: steps.changes.outputs.esp-wifi == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: esp-wifi/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the esp-wifi/CHANGELOG.md file."
- name: Check that changelog updated (xtensa-lx)
if: steps.changes.outputs.xtensa-lx == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: xtensa-lx/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the xtensa-lx/CHANGELOG.md file."
- name: Check that changelog updated (xtensa-lx-rt)
if: steps.changes.outputs.xtensa-lx-rt == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: xtensa-lx-rt/CHANGELOG.md
skipLabels: "skip-changelog"
missingUpdateErrorMessage: "Please add a changelog entry in the xtensa-lx-rt/CHANGELOG.md file."

View File

@ -7,28 +7,25 @@
# 1.) In the 'esp-hal' job, add the name of the chip to the `matrix.soc` array.
# 1a.) If the device has a low-power core (which is supported in
# `esp-lp-hal`), then update the `if` condition to build prerequisites.
# 2.) In the 'msrv-riscv' job, add checks as needed for the new chip.
# 2.) In the 'msrv' job, add checks as needed for the new chip.
name: CI
on:
pull_request:
paths-ignore:
- "**/CHANGELOG.md"
- "**/README.md"
push:
branches-ignore:
- "gh-readonly-queue/**"
paths-ignore:
- "**/CHANGELOG.md"
- "**/README.md"
- "main"
merge_group:
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MSRV: "1.76.0"
MSRV: "1.83.0"
RUSTDOCFLAGS: -Dwarnings
DEFMT_LOG: trace
# Cancel any currently running workflows from the same PR, branch, or
# tag when a new workflow is triggered.
@ -57,66 +54,24 @@ jobs:
matrix:
device: [
# RISC-V devices:
{ soc: "esp32c2", target: "riscv32imc-unknown-none-elf" },
{ soc: "esp32c3", target: "riscv32imc-unknown-none-elf" },
{ soc: "esp32c6", target: "riscv32imac-unknown-none-elf" },
{ soc: "esp32h2", target: "riscv32imac-unknown-none-elf" },
{ soc: "esp32c2", target: "riscv32imc-unknown-none-elf", toolchain: "stable" },
{ soc: "esp32c3", target: "riscv32imc-unknown-none-elf", toolchain: "stable" },
{ soc: "esp32c6", target: "riscv32imac-unknown-none-elf", toolchain: "stable" },
{ soc: "esp32h2", target: "riscv32imac-unknown-none-elf", toolchain: "stable" },
# Xtensa devices:
{ soc: "esp32", target: "xtensa-esp32-none-elf" },
{ soc: "esp32s2", target: "xtensa-esp32s2-none-elf" },
{ soc: "esp32s3", target: "xtensa-esp32s3-none-elf" },
{ soc: "esp32", target: "xtensa-esp32-none-elf", toolchain: "esp" },
{ soc: "esp32s2", target: "xtensa-esp32s2-none-elf", toolchain: "esp" },
{ soc: "esp32s3", target: "xtensa-esp32s3-none-elf", toolchain: "esp" },
]
steps:
- uses: actions/checkout@v4
# Install the Rust toolchain for RISC-V devices:
- if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) }}
uses: dtolnay/rust-toolchain@v1
with:
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf
toolchain: stable
components: rust-src
# Install the Rust toolchain for Xtensa devices:
- if: contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc)
uses: esp-rs/xtensa-toolchain@v1.5
- uses: esp-rs/xtensa-toolchain@v1.5
with:
buildtargets: ${{ matrix.device.soc }}
default: true
ldproxy: false
- uses: Swatinem/rust-cache@v2
# Build all supported examples for the low-power core first (if present):
- if: contains(fromJson('["esp32c6", "esp32s2", "esp32s3"]'), matrix.device.soc)
name: Build prerequisites (esp-lp-hal)
run: cargo xtask build-examples esp-lp-hal ${{ matrix.device.soc }}
# Make sure we're able to build the HAL without the default features
# enabled:
- name: Build (no features)
run: |
cargo xtask build-package \
--no-default-features \
--features=${{ matrix.device.soc }} \
--target=${{ matrix.device.target }} \
esp-hal
# Build all supported examples for the specified device:
- name: Build (examples)
run: cargo xtask build-examples esp-hal ${{ matrix.device.soc }}
esp-lp-hal:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
soc: ["esp32c6", "esp32s2", "esp32s3"]
steps:
- uses: actions/checkout@v4
# Install the Rust toolchain for RISC-V devices:
version: 1.83.0.1
# Install the Rust stable toolchain for RISC-V devices:
- uses: dtolnay/rust-toolchain@v1
with:
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf
@ -125,32 +80,12 @@ jobs:
- uses: Swatinem/rust-cache@v2
# Build all supported examples for the specified device:
- name: Build examples
run: cargo xtask build-examples esp-lp-hal ${{ matrix.soc }}
esp-riscv-rt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@v1
- name: Build and Check
uses: ./.github/actions/check-esp-hal
with:
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf
toolchain: stable
components: rust-src
- uses: Swatinem/rust-cache@v2
# Build for all RISC-V targets (no features):
- name: Build esp-riscv-rt (riscv32imc, no features)
run: cd esp-riscv-rt/ && cargo build --target=riscv32imc-unknown-none-elf
- name: Build esp-riscv-rt (riscv32imac, no features)
run: cd esp-riscv-rt/ && cargo build --target=riscv32imac-unknown-none-elf
# Build for all RISC-V targets (all features):
- name: Build esp-riscv-rt (riscv32imc, all features)
run: cd esp-riscv-rt/ && cargo build --target=riscv32imc-unknown-none-elf --features=ci
- name: Build esp-riscv-rt (riscv32imac, all features)
run: cd esp-riscv-rt/ && cargo build --target=riscv32imac-unknown-none-elf --features=ci
device: ${{ matrix.device.soc }}
target: ${{ matrix.device.target }}
toolchain: ${{ matrix.device.toolchain }}
extras:
runs-on: ubuntu-latest
@ -175,34 +110,7 @@ jobs:
# --------------------------------------------------------------------------
# MSRV
msrv-riscv:
runs-on: ubuntu-latest
env:
RUSTC_BOOTSTRAP: 1
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@v1
with:
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf
toolchain: ${{ env.MSRV }}
components: rust-src
- uses: Swatinem/rust-cache@v2
# Verify the MSRV for all RISC-V chips.
- name: msrv (esp-hal)
run: |
cargo xtask build-package --features=esp32c2,ci --target=riscv32imc-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32c3,ci --target=riscv32imc-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32c6,ci --target=riscv32imac-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32h2,ci --target=riscv32imac-unknown-none-elf esp-hal
- name: msrv (esp-lp-hal)
run: |
cargo xtask build-package --features=esp32c6 --target=riscv32imac-unknown-none-elf esp-lp-hal
cargo xtask build-package --features=esp32s2 --target=riscv32imc-unknown-none-elf esp-lp-hal
cargo xtask build-package --features=esp32s3 --target=riscv32imc-unknown-none-elf esp-lp-hal
msrv-xtensa:
msrv:
runs-on: ubuntu-latest
env:
RUSTC_BOOTSTRAP: 1
@ -213,33 +121,49 @@ jobs:
with:
ldproxy: false
version: ${{ env.MSRV }}
- uses: dtolnay/rust-toolchain@v1
with:
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf
toolchain: ${{ env.MSRV }}
components: rust-src
- uses: Swatinem/rust-cache@v2
# Verify the MSRV for all Xtensa chips:
- name: msrv (esp-hal)
# Verify the MSRV for all RISC-V chips.
- name: msrv RISCV (esp-hal)
run: |
cargo xtask build-package --features=esp32c2,ci --target=riscv32imc-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32c3,ci --target=riscv32imc-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32c6,ci --target=riscv32imac-unknown-none-elf esp-hal
cargo xtask build-package --features=esp32h2,ci --target=riscv32imac-unknown-none-elf esp-hal
- name: msrv RISCV (esp-wifi)
run: |
cargo xtask build-package --features=esp32c2,wifi,ble,esp-hal/unstable --target=riscv32imc-unknown-none-elf esp-wifi
cargo xtask build-package --features=esp32c3,wifi,ble,esp-hal/unstable --target=riscv32imc-unknown-none-elf esp-wifi
cargo xtask build-package --features=esp32c6,wifi,ble,esp-hal/unstable --target=riscv32imac-unknown-none-elf esp-wifi
cargo xtask build-package --features=esp32h2,ble,esp-hal/unstable --target=riscv32imac-unknown-none-elf esp-wifi
# Verify the MSRV for all Xtensa chips:
- name: msrv Xtensa (esp-hal)
run: |
cargo xtask build-package --toolchain=esp --features=esp32,ci --target=xtensa-esp32-none-elf esp-hal
cargo xtask build-package --toolchain=esp --features=esp32s2,ci --target=xtensa-esp32s2-none-elf esp-hal
cargo xtask build-package --toolchain=esp --features=esp32s3,ci --target=xtensa-esp32s3-none-elf esp-hal
- name: msrv Xtensa (esp-wifi)
run: |
cargo xtask build-package --toolchain=esp --features=esp32,wifi,ble,esp-hal/unstable --target=xtensa-esp32-none-elf esp-wifi
cargo xtask build-package --toolchain=esp --features=esp32s2,wifi,esp-hal/unstable --target=xtensa-esp32s2-none-elf esp-wifi
cargo xtask build-package --toolchain=esp --features=esp32s3,wifi,ble,esp-hal/unstable --target=xtensa-esp32s3-none-elf esp-wifi
- name: msrv (esp-lp-hal)
run: |
cargo xtask build-package --features=esp32c6 --target=riscv32imac-unknown-none-elf esp-lp-hal
cargo xtask build-package --features=esp32s2 --target=riscv32imc-unknown-none-elf esp-lp-hal
cargo xtask build-package --features=esp32s3 --target=riscv32imc-unknown-none-elf esp-lp-hal
# --------------------------------------------------------------------------
# Lint & Format
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# We use the 'esp' toolchain for *all* targets, in order to get a
# semi-stable and consistent set of lints for all targets:
- uses: esp-rs/xtensa-toolchain@v1.5
with:
default: true
ldproxy: false
- uses: Swatinem/rust-cache@v2
# Lint all packages:
- run: cargo xtask lint-packages
# Format
rustfmt:
runs-on: ubuntu-latest
@ -258,44 +182,17 @@ jobs:
- run: cargo xtask fmt-packages --check
# --------------------------------------------------------------------------
# Tests
# host tests
hil:
name: HIL Test | ${{ matrix.target.soc }}
host-tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
# RISC-V devices:
- soc: esp32c3
rust-target: riscv32imc-unknown-none-elf
- soc: esp32c6
rust-target: riscv32imac-unknown-none-elf
- soc: esp32h2
rust-target: riscv32imac-unknown-none-elf
# Xtensa devices:
- soc: esp32s2
- soc: esp32s3
steps:
- uses: actions/checkout@v4
# Install the Rust toolchain for RISC-V devices:
- if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.target.soc) }}
uses: dtolnay/rust-toolchain@v1
- uses: dtolnay/rust-toolchain@v1
with:
target: ${{ matrix.target.rust-target }}
toolchain: nightly
components: rust-src
# Install the Rust toolchain for Xtensa devices:
- if: contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.target.soc)
uses: esp-rs/xtensa-toolchain@v1.5
with:
buildtargets: ${{ matrix.target.soc }}
default: true
ldproxy: false
toolchain: stable
- uses: Swatinem/rust-cache@v2
- run: cargo xtask build-tests ${{ matrix.target.soc }}
# Check the formatting of all packages:
- run: cd esp-config && cargo test --features build

53
.github/workflows/ci_nightly.yml vendored Normal file
View File

@ -0,0 +1,53 @@
name: CI - nightly
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
env:
CARGO_TERM_COLOR: always
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUSTDOCFLAGS: -Dwarnings
DEFMT_LOG: trace
jobs:
esp-hal-nightly:
name: esp-hal | nightly (${{ matrix.device.soc }})
runs-on: ubuntu-latest
env:
SSID: SSID
PASSWORD: PASSWORD
STATIC_IP: 1.1.1.1
GATEWAY_IP: 1.1.1.1
HOST_IP: 1.1.1.1
strategy:
fail-fast: false
matrix:
device: [
# RISC-V devices:
{ soc: "esp32c2", target: "riscv32imc-unknown-none-elf" },
{ soc: "esp32c3", target: "riscv32imc-unknown-none-elf" },
{ soc: "esp32c6", target: "riscv32imac-unknown-none-elf" },
{ soc: "esp32h2", target: "riscv32imac-unknown-none-elf" },
]
steps:
- uses: actions/checkout@v4
# Install the Rust nightly toolchain for RISC-V devices:
- uses: dtolnay/rust-toolchain@v1
with:
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf
toolchain: nightly
components: rust-src, clippy, rustfmt
- uses: Swatinem/rust-cache@v2
- name: Build and Check
uses: ./.github/actions/check-esp-hal
with:
device: ${{ matrix.device.soc }}
target: ${{ matrix.device.target }}
toolchain: nightly

View File

@ -2,12 +2,33 @@ name: Documentation
on:
workflow_dispatch:
inputs:
esp-hal:
description: "esp-hal tag"
required: true
esp-wifi:
description: "esp-wifi tag"
required: true
env:
CARGO_TERM_COLOR: always
jobs:
setup:
runs-on: ubuntu-latest
outputs:
packages: '[
{ "name": "esp-hal", "tag": "${{ github.event.inputs.esp-hal }}" },
{ "name": "esp-wifi", "tag": "esp-wifi-${{ github.event.inputs.esp-wifi }}" }
]'
steps:
- run: echo "Setup complete!"
build:
needs: setup
strategy:
fail-fast: true
matrix:
packages: ${{ fromJson(needs.setup.outputs.packages) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -15,22 +36,50 @@ jobs:
with:
default: true
ldproxy: false
version: 1.83.0.1
- name: Checkout repository
uses: actions/checkout@v4
with:
repository: esp-rs/esp-hal
ref: ${{ matrix.packages.tag }}
- name: Build documentation
run: cargo xtask build-documentation --packages=esp-hal,esp-wifi
run: cargo xtask build-documentation --packages=${{ matrix.packages.name }}
# https://github.com/actions/deploy-pages/issues/303#issuecomment-1951207879
- name: Remove problematic '.lock' files
run: find docs -name ".lock" -exec rm -f {} \;
- name: Upload docs for ${{ matrix.packages.name }}
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.packages.name }}
path: "docs/${{ matrix.packages.name }}"
assemble:
needs: [setup, build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Prepare
run: mkdir docs
- name: Download all docs
uses: actions/download-artifact@v4
with:
path: "docs/"
- name: Create index.html
run: "cargo xtask build-documentation-index --packages=$(echo '${{ needs.setup.outputs.packages }}' | jq -r '[.[].name] | join(\",\")')"
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: "docs"
path: "docs/"
deploy:
# Add a dependency to the build job:
needs: build
# Add a dependency to the assemble job:
needs: assemble
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment:
permissions:

View File

@ -1,6 +1,8 @@
name: HIL
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
merge_group:
workflow_dispatch:
inputs:
@ -13,13 +15,61 @@ on:
required: true
default: "main"
# Cancel any currently running workflows from the same PR, branch, or
# tag when a new workflow is triggered.
#
# https://stackoverflow.com/a/66336834
concurrency:
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
env:
CARGO_TERM_COLOR: always
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build-xtasks:
name: Build xtasks | ${{ matrix.host.arch }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
host:
- arch: armv7
rust-target: armv7-unknown-linux-gnueabihf
- arch: aarch64
rust-target: aarch64-unknown-linux-gnu
steps:
- uses: actions/checkout@v4
if: github.event_name != 'workflow_dispatch'
- uses: actions/checkout@v4
if: github.event_name == 'workflow_dispatch'
with:
repository: ${{ github.event.inputs.repository }}
ref: ${{ github.event.inputs.branch }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
components: rust-src
- name: Install cross
run: cargo install cross
- name: Build xtasks
run: cross build --release --target ${{ matrix.host.rust-target }} -p xtask
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: xtask-${{ matrix.host.arch }}
path: target/${{ matrix.host.rust-target }}/release/xtask
build-tests:
name: HIL Test | ${{ matrix.target.soc }}
name: Build HIL Tests | ${{ matrix.target.soc }}
runs-on: ubuntu-latest
strategy:
@ -27,6 +77,8 @@ jobs:
matrix:
target:
# RISC-V devices:
- soc: esp32c2
rust-target: riscv32imc-unknown-none-elf
- soc: esp32c3
rust-target: riscv32imc-unknown-none-elf
- soc: esp32c6
@ -34,6 +86,8 @@ jobs:
- soc: esp32h2
rust-target: riscv32imac-unknown-none-elf
# # Xtensa devices:
- soc: esp32
rust-target: xtensa-esp32-none-elf
- soc: esp32s2
rust-target: xtensa-esp32s2-none-elf
- soc: esp32s3
@ -53,7 +107,7 @@ jobs:
uses: dtolnay/rust-toolchain@v1
with:
target: ${{ matrix.target.rust-target }}
toolchain: nightly
toolchain: stable
components: rust-src
# Install the Rust toolchain for Xtensa devices:
- if: contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.target.soc)
@ -62,36 +116,21 @@ jobs:
buildtargets: ${{ matrix.target.soc }}
default: true
ldproxy: false
version: 1.83.0.1
- name: Build tests
run: cargo xtask build-tests ${{ matrix.target.soc }}
- name: Prepare artifact
run: |
# Create the 'tests' directory if it doesn't exist
mkdir -p tests
# Find ELF files in the specified path and move them to 'tests'
find "hil-test/target/${{ matrix.target.rust-target }}/release/deps/" -type f -exec file {} + | \
grep ELF | \
awk -F: '{print $1}' | \
xargs -I {} mv {} tests
# Rename files in 'tests' by removing everything after the first dash
for file in tests/*-*; do
base_name="$(basename "$file" | cut -d'-' -f1)"
mv "$file" "tests/$base_name"
done
- uses: actions/upload-artifact@v4
with:
name: tests-${{ matrix.target.soc }}
path: /home/runner/work/esp-hal/esp-hal/tests
path: /home/runner/work/esp-hal/esp-hal/target/tests/${{ matrix.target.soc }}
if-no-files-found: error
overwrite: true
hil:
name: HIL Test | ${{ matrix.target.soc }}
needs: build-tests
name: Run HIL Tests | ${{ matrix.target.soc }}
needs: [build-tests, build-xtasks]
runs-on:
labels: [self-hosted, "${{ matrix.target.runner }}"]
strategy:
@ -99,25 +138,49 @@ jobs:
matrix:
target:
# RISC-V devices:
- soc: esp32c2
runner: esp32c2-jtag
host: aarch64
- soc: esp32c3
runner: esp32c3-usb
host: armv7
- soc: esp32c6
runner: esp32c6-usb
host: armv7
- soc: esp32h2
runner: esp32h2-usb
host: armv7
# Xtensa devices:
- soc: esp32
runner: esp32-jtag
host: aarch64
- soc: esp32s2
runner: esp32s2-jtag
host: armv7
- soc: esp32s3
runner: esp32s3-usb
host: armv7
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: tests-${{ matrix.target.soc }}
path: tests-${{ matrix.target.soc }}
- uses: actions/download-artifact@v4
with:
name: xtask-${{ matrix.target.host }}
- name: Run Tests
id: run-tests
run: |
[ -f ~/setup.sh ] && source ~/setup.sh
export PATH=$PATH:/home/espressif/.cargo/bin
cargo xtask run-elfs ${{ matrix.target.soc }} tests-${{ matrix.target.soc }}
chmod +x xtask
./xtask run-elfs ${{ matrix.target.soc }} tests-${{ matrix.target.soc }}
- name: Clean up
if: always()
run: |
rm -rf tests-${{ matrix.target.soc }}
rm -f xtask

View File

@ -13,4 +13,4 @@ jobs:
- uses: actions/add-to-project@v0.5.0
with:
project-url: https://github.com/orgs/esp-rs/projects/2
github-token: ${{ secrets.PAT }}
github-token: ${{ secrets.PAT }}

View File

@ -1,54 +0,0 @@
# esp-rs API Guidelines
## About
This is a living document - make sure to check the latest version of this document.
> [!NOTE]
> Not all of the currently existing code follows this guideline, yet.
In general, the [Rust API Guidelines](https://rust-lang.github.io/api-guidelines) apply to all projects in the ESP-RS GitHub organization where possible. (`C-RW-VALUE` and `C-SERDE` do not apply)
Especially for public API but if possible also for internal APIs.
The following paragraphs contain additional recommendations.
## Construction and Destruction of Drivers
- Drivers take peripherals and pins via the `PeripheralRef` pattern - they don't consume peripherals/pins
- Consider adding a `Drop` implementation resetting the peripheral to idle state
- Consider using a builder-like pattern for configuration which must be done during initialization
## Interoperability
- `cfg` gated `defmt` derives and impls are added to new structs and enums
- see [this example](https://github.com/esp-rs/esp-hal/blob/df2b7bd8472cc1d18db0d9441156575570f59bb3/esp-hal/src/spi/mod.rs#L15)
- e.g. `#[cfg_attr(feature = "defmt", derive(defmt::Format))]`
- Don't use `log::XXX!` macros directly - use the wrappers in `fmt.rs` (e.g. just `info!` instead of `log::info!` or importing `log::*`)
## API Surface
- Add `#[deny(missing_docs)]` to new modules or when reworking a larger part of a module. In the end we will require this for whole crates.
- API documentation shouldn't be an afterthought
- Private details shouldn't leak into the public API, and should be made private where technically possible.
- Implementation details that _need_ to be public should be marked with `#[doc(hidden)]` and a comment as to why it needs to be public.
- Functions which technically need to be public but shouldn't be callable by the user need to be sealed.
- see [this example in Rust's core library](https://github.com/rust-lang/rust/blob/044a28a4091f2e1a5883f7fa990223f8b200a2cd/library/core/src/error.rs#L89-L100)
- Any public traits, that **must not** be implemented downstream need to be `Sealed`
- Prefer compile-time checks over runtime checks where possible, prefer a fallible API over panics.
- Follow naming conventions in order to be consistent across drivers - take inspiration from existing drivers
- Design APIs in a way that they are easy to use.
- Driver API decisions should be assessed individually, don't _not_ just follow embedded-hal or other ecosystem trait crates. Expose the capabilities of the hardware. (Ecosystem traits are implemented on top of the inherent API)
- Avoid type states and extraneous generics whenever possible
- These often lead to usability problems, and tend to just complicate things needlessly - sometimes it can be a good tradeoff to make a type not ZST
- Common cases of useless type info is storing pin information - this is usually not required after configuring the pins and will bloat the complexity of the type massively. When following the `PeripheralRef` pattern it's not needed in order to keep users from re-using the pin while in use
- Avoiding `&mut self` when `&self` is safe to use. `&self` is generally easier to use as an API. Typical applications of this are where the methods just do writes to registers which don't have side effects.
- For example starting a timer is fine for `&self`, worst case a timer will be started twice if two parts of the program call it. You can see a real example of this [here](https://github.com/esp-rs/esp-hal/pull/1500#pullrequestreview-2015911974)
## Maintainability
- Avoid excessive use of macros unless there is no other option; modification of the PAC crates should be considered before resorting to macros.
- Every line of code is a liability. Take some time to see if your implementation can be simplified before opening a PR.
- If your are porting code from ESP-IDF (or anything else), please include a link WITH the commit hash in it, and please highlight the relevant line(s) of code
- If necessary provide further context as comments (consider linking to code, PRs, TRM - make sure to use permanent links, e.g. include the hash when linking to a Git repository, include the revision, page number etc. when linking to TRMs)
- Generally follow common "good practices" and idiomatic Rust style

View File

@ -1,102 +0,0 @@
# Welcome to the `esp-hal` contributing guide
Thank you for investing your time in contributing to our project!
In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR.
Use the table of contents icon (<img src="resources/table-of-contents.png" width="24" height="24" />) in the top right corner of this document to get to a specific section of this guide quickly.
## New Contributor Guide
To get an overview of the project, please read the [README]. Here are some resources to help you get started with open source contributions:
- [Finding ways to contribute to open source on GitHub]
- [Set up Git]
- [GitHub flow]
- [Collaborating with pull requests]
[README]: README.md
[Finding ways to contribute to open source on GitHub]: https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github
[Set up Git]: https://docs.github.com/en/get-started/quickstart/set-up-git
[GitHub flow]: https://docs.github.com/en/get-started/quickstart/github-flow
[Collaborating with pull requests]: https://docs.github.com/en/github/collaborating-with-pull-requests
## Getting Started
Before adding or changing code you might want to review the [esp-rs API guidelines](./API-GUIDELINES.md)
### Issues
#### Create a New Issue
If you spot a problem with the docs, [search if an issue already exists]. If a related issue doesn't exist, you can open a new issue using the [issue form].
[search if an issue already exists]: https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests#search-by-the-title-body-or-comments
[issue form]: https://github.com/esp-rs/esp-hal/issues/new/
#### Solve an Issue
Scan through our [existing issues] to find one that interests you. You can narrow down the search using labels as filters. If you find an issue to work on, you are welcome to open a PR with a fix.
It's recommended that you comment in the relevant issue, mentioning that you are actively working on it, however this is not a requirement.
If somebody is already assigned to an issue, this does not necessarily mean they are actively working on it; don't be afraid to comment in these issues asking if you can take over the work if you're interested.
[existing issues]: https://github.com/esp-rs/esp-hal/issues
### Make Changes
1. Fork the repository.
- Using GitHub Desktop:
- [Getting started with GitHub Desktop] will guide you through setting up Desktop.
- Once Desktop is set up, you can use it to [fork the repo!]
- Using the command line:
- [Fork the repo] so that you can make your changes without affecting the original project until you're ready to merge them.
2. Install or update to the latest version of Rust. See [rustup.rs] for more information.
3. Create a working branch and start with your changes!
[Getting started with GitHub Desktop]: https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop
[fork the repo!]: https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop
[Fork the repo]: https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository
[rustup.rs]: https://rustup.rs/
### Commit Your Update
Commit the changes once you are happy with them. Don't forget to self-review to speed up the review process.
We ask that you ensure all source code files has been properly formatted with `rustfmt`, and that you have linted your changes by running `cargo clippy`. These tools can be installed by running the following commands:
```shell
rustup component add rustfmt
rustup component add clippy
```
We _strongly_ recommend that you format your code before committing to ensure consistency throughout the project.
To format all packages in the workspace, run the following command in a terminal from the root of the repository:
```shell
cargo xtask fmt-workspace
```
This will use `rustfmt` to ensure that all source code is formatted correctly prior to committing.
### Pull Request
When you're finished with the changes, create a pull request, also known as a PR.
- Fill the pull request template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request.
- Don't forget to [link PR to issue] if you are solving one.
- Enable the checkbox to [allow maintainer edits] so the branch can be updated for a merge. Once you submit your PR, a Docs team member will review your proposal. We may ask questions or request additional information.
- We may ask for changes to be made before a PR can be merged, either using [suggested changes] or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
- As you update your PR and apply changes, mark each conversation as [resolved].
- If you run into any merge issues, checkout this [git tutorial] to help you resolve merge conflicts and other issues.
[link PR to issue]: https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue
[allow maintainer edits]: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork
[suggested changes]: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request
[resolved]: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations
[git tutorial]: https://github.com/skills/resolve-merge-conflicts
### Your PR is Merged!
Congratulations! The esp-rs team thanks you for your contributions!

View File

@ -5,10 +5,10 @@ exclude = [
"esp-alloc",
"esp-backtrace",
"esp-build",
"esp-config",
"esp-hal",
"esp-hal-embassy",
"esp-hal-procmacros",
"esp-hal-smartled",
"esp-ieee802154",
"esp-lp-hal",
"esp-metadata",
@ -21,4 +21,8 @@ exclude = [
"extras/esp-wifishark",
"extras/ieee802154-sniffer",
"hil-test",
"qa-test",
"xtensa-lx",
"xtensa-lx-rt",
"xtensa-lx-rt/procmacros",
]

View File

@ -20,7 +20,7 @@ If you have any questions, comments, or concerns, please [open an issue], [start
> [!NOTE]
>
> This project is still in the relatively early stages of development, and as such there should be no expectation of API stability. A significant number of peripherals currently have drivers implemented but have varying levels of functionality. For most basic tasks, this should be usable already, however some more advanced or uncommon features may not yet be implemented.
> This repository includes crates that are at various stages of maturity and stability. While many functionalities have already been implemented and are usable for most tasks, certain advanced or less common features may still be under development. Each crate may offer different levels of functionality and guarantees.
[esp-lp-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp-lp-hal
[esp-idf-svc]: https://github.com/esp-rs/esp-idf-svc
@ -49,6 +49,13 @@ For information about the HAL and how to use it in your own projects, please ref
This repository is home to a number of different packages; for more information regarding a particular package, please refer to its `README.md` and/or documentation.
## Contributing
We have a number of living documents to aid contributing to the project, please give these a read before modifying code:
- [API-GUIDELINES](https://github.com/esp-rs/esp-hal/blob/main/documentation/API-GUIDELINES.md)
- [CONTRIBUTING-GUIDE](https://github.com/esp-rs/esp-hal/blob/main/documentation/CONTRIBUTING.md)
## License
Licensed under either of:
@ -58,10 +65,8 @@ Licensed under either of:
at your option.
### Contribution
### Contribution notice
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without
any additional terms or conditions.
If you consider contributing, please make sure you have read and understood our [contributing guide](./CONTRIBUTING.md) and [API guidelines](https://github.com/esp-rs/esp-hal/blob/main/API-GUIDELINES.md).

View File

@ -0,0 +1,144 @@
# `esp-rs` API Guidelines
## About
This is a living document - make sure to check the latest version of this document.
> [!NOTE]
> Not all of the currently existing code follows this guideline, yet.
In general, the [Rust API Guidelines](https://rust-lang.github.io/api-guidelines) apply to all projects in the ESP-RS GitHub organization where possible.
- Especially for public API but if possible also for internal APIs.
## Amendments to the Rust API Guidelines
- `C-RW-VALUE` and `C-SERDE` do not apply.
- `C-COMMON-TRAITS`:
The set of traits to implement depend on the type and use case. In esp-hal, we can highlight a few such use cases and provide recommendations what should be implemented. If nothing here applies, use your best judgement.
- Driver structures: `Debug`
- Driver configuration: `Default`, `Debug`, `PartialEq/Eq`, `Clone/Copy`, `Hash`
- `Clone/Copy` depends on the size and contents of the structure. They should generally be implemented, unless there is a good reason not to.
- The `Default` configuration needs to make sense for a particular driver, and applying the default configuration must not fail.
- Error types: `Debug`, `PartialEq/Eq`, `Clone/Copy`, `Hash`, `Error`, `Display`
## Construction and Destruction of Drivers
- Drivers must take peripherals via the `PeripheralRef` pattern - they don't consume peripherals directly.
- If a driver requires pins, those pins should be configured using `fn with_signal_name(self, pin: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self` or `fn with_signal_name(self, pin: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self`
- If a driver supports multiple peripheral instances (for example, I2C0 is one such instance):
- The driver should not be generic over the peripheral instance.
- The author must to use `crate::any_peripheral` to define the "any" peripheral instance type.
- The driver must implement a `new` constructor that automatically converts the peripheral instance into the any type.
- If a driver is configurable, configuration options should be implemented as a `Config` struct in the same module where the driver is located.
- The driver's constructor should take the config struct by value, and it should return `Result<Self, ConfigError>`.
- The `ConfigError` enum should be separate from other `Error` enums used by the driver.
- The driver should implement `fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError>`.
- In case the driver's configuration is infallible (all possible combinations of options are supported by the hardware), the `ConfigError` should be implemented as an empty `enum`.
- Configuration structs should derive `procmacros::BuilderLite` in order to automatically implement the Builder Lite pattern for them.
- If a driver implements both blocking and async operations, or only implements blocking operations, but may support asynchronous ones in the future, the driver's type signature must include a `crate::Mode` type parameter.
- By default, constructors must configure the driver for blocking mode. The driver must implement `into_async` (and a matching `into_blocking`) function that reconfigures the driver.
- `into_async` must configure the driver and/or the associated DMA channels. This most often means enabling an interrupt handler.
- `into_blocking` must undo the configuration done by `into_async`.
- The asynchronous driver implementation must also expose the blocking methods (except for interrupt related functions).
- Drivers must have a `Drop` implementation resetting the peripheral to idle state. There are some exceptions to this:
- GPIO where common usage is to "set and drop" so they can't be changed
- Where we don't want to disable the peripheral as it's used internally, for example SYSTIMER is used by `time::now()` API. See `KEEP_ENABLED` in src/system.rs
- A driver doesn't need to do anything special for deinitialization and has a `PeripheralGuard` field which implements the disabling and resetting of the peripheral.
- Consider using a builder-like pattern for driver construction.
## Interoperability
- Don't use `log::XXX!` macros directly - use the wrappers in `fmt.rs` (e.g. just `info!` instead of `log::info!` or importing `log::*`)!
- Consider implementing common ecosystem traits, like the ones in `embedded-hal` or `embassy-embedded-hal`.
- Where the guidelines suggest implementing `Debug`, `defmt::Format` should also be implemented.
- The `defmt::Format` implementation needs to be gated behind the `defmt` feature.
- see [this example](https://github.com/esp-rs/esp-hal/blob/df2b7bd8472cc1d18db0d9441156575570f59bb3/esp-hal/src/spi/mod.rs#L15)
- e.g. `#[cfg_attr(feature = "defmt", derive(defmt::Format))]`
- Implementations of common, but unstable traits (e.g. `embassy_embedded_hal::SetConfig`) need to be gated with the `unstable` feature.
## API Surface
- API documentation must be provided for every new driver and API.
- Private details should not leak into the public API, and should be made private where technically possible.
- Implementation details that _need_ to be public should be marked with `#[doc(hidden)]` and a comment as to why it needs to be public.
- For the time being, this includes any `Instance` traits, and `State` or `Info` structs as well.
- Functions which technically need to be public but shouldn't be callable by the user need to be sealed.
- see [this example in Rust's core library](https://github.com/rust-lang/rust/blob/044a28a4091f2e1a5883f7fa990223f8b200a2cd/library/core/src/error.rs#L89-L100)
- Any public traits, that **must not** be implemented downstream need to be `Sealed`.
- Prefer compile-time checks over runtime checks where possible, prefer a fallible API over panics.
- Follow naming conventions in order to be consistent across drivers - take inspiration from existing drivers.
- Design APIs in a way that they are easy to use.
- Driver API decisions should be assessed individually, don't _not_ just follow embedded-hal or other ecosystem trait crates. Expose the capabilities of the hardware. (Ecosystem traits are implemented on top of the inherent API)
- Avoid type states and extraneous generics whenever possible
- These often lead to usability problems, and tend to just complicate things needlessly - sometimes it can be a good tradeoff to make a type not ZST
- Common cases of useless type info is storing pin information - this is usually not required after configuring the pins and will bloat the complexity of the type massively. When following the `PeripheralRef` pattern it's not needed in order to keep users from re-using the pin while in use
- Avoiding `&mut self` when `&self` is safe to use. `&self` is generally easier to use as an API. Typical applications of this are where the methods just do writes to registers which don't have side effects.
- Maintain order consistency in the API, such as in the case of pairs like RX/TX.
- If your driver provides a way to listen for interrupts, the interrupts should be listed in a `derive(EnumSetType)` enum as opposed to one function per interrupt flag.
- If a driver only implements a subset of a peripheral's capabilities, it should be placed in the `peripheral::subcategory` module.
- For example, if a driver implements the slave-mode I2C driver, it should be placed into `i2c::slave`.
- This helps us reducing the need of introducing breaking changes if we implement additional functionalities.
- Avoid abbreviations and contractions in the API, where possible.
- Saving a few characters may introduce ambiguity, e.g `SpiTransDone`, is it `Transmit` or `Transfer`?
- Common abbreviations, that are well understood such as `Dma` are perfectly fine.
## Maintainability
- Avoid excessive use of macros unless there is no other option; modification of the PAC crates should be considered before resorting to macros.
- Every line of code is a liability. Take some time to see if your implementation can be simplified before opening a PR.
- If you are porting code from ESP-IDF (or anything else), please include a link WITH the commit hash in it, and please highlight the relevant line(s) of code
- If necessary provide further context as comments (consider linking to code, PRs, TRM - make sure to use permanent links, e.g. include the hash when linking to a Git repository, include the revision, page number etc. when linking to TRMs)
- Prefer line comments (//) to block comments (/* ... */)
- Generally, follow common "good practices" and idiomatic Rust style
- All `Future` objects (public or private) must be marked with ``#[must_use = "futures do nothing unless you `.await` or poll them"]``.
- Prefer `cfg_if!` (or, if the branches just pick between separate values of the same variable, `cfg!()`) over multiple exclusive `#[cfg]` attributes. `cfg_if!`/`cfg!()` visually divide the options, often results in simpler conditions and simplifies adding new branches in the future.
## Driver implementation
- If a common `Instance` trait is used for multiple peripherals, those traits should not have any logic implemented in them.
- The `Instance` traits should only be used to access information about a peripheral instance.
- The internal implementation of the driver should be non-generic over the peripheral instance. This helps the compiler produce smaller code.
- The author is encouraged to return a static shared reference to an `Info` and a `State` structure from the `Instance` trait.
- The `Info` struct should describe the peripheral. Do not use any interior mutability.
- The `State` struct should contain counters, wakers and other, mutable state. As this is accessed via a shared reference, interior mutability and atomic variables are preferred.
## Modules Documentation
Modules should have the following documentation format:
```rust
//! # Peripheral Name (Peripheral Acronym)
//!
//! ## Overview
//! Small description of the peripheral, see ESP-IDF docs or TRM
//!
//! ## Configuration
//! Explain how can the peripheral be configured, and which parameters can be configured
//!
//! ## Usage
//! Explain if we implement any external traits
//!
//! ## Examples
//!
//! ### Name of the Example
//! Small description of the example if needed
//! ```rust, no_run
//! ...
//! ```
//!
//! ## Implementation State
//! List unsupported features
```
- If any of the headers is empty, remove it
- When possible, use ESP-IDF docs and TRM as references and include links if possible.
- In case of referencing an ESP-IDF link make it chip-specific, for example:
```
#![doc = concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", crate::soc::chip!(), "/api-reference/peripherals/etm.html)")]
```
- In case of referencing a TRM chapter, use the `crate::trm_markdown_link!()` macro. If you are referring to a particular chapter, you may use `crate::trm_markdown_link!("#chapter_anchor")`.
- Documentation examples must be short
- But must also provide value beyond what the rustdoc generated docs show
- Showing a snippet of a slightly more complex interaction, for example inverting the signals for a driver
- Showing construction if it is more complex, or requires some non-obvious precursor steps. Think about this for drivers that take a generic instance to construct, rustdoc doesn't do a good job of showing what concrete things can be passed into a constructor.
- For more complex scenarios, create an example.
- Use rustdoc syntax for linking to other documentation items instead of markdown links where possible
- https://doc.rust-lang.org/rustdoc/write-documentation/linking-to-items-by-name.html

View File

@ -0,0 +1,143 @@
# Welcome to the `esp-hal` Contributing Guide
Thank you for considering contributing to our project! Your efforts help make `esp-hal` a better ecosystem for everyone.
This guide outlines the contribution workflow, from reporting issues and submitting pull requests, to the review process and eventual merger of contributions.
## Quick Navigation
* [New Contributor Guide]
* [Getting Started]
* [Issues: Reporting and Resolving]
* [Making Changes: Fork, Edit, and Pull Request]
* [Testing Your Contributions]
* [Commit Your Updates]
* [Pull Request: From Submission to Merge]
* [Your PR is merged!]
[New Contributor Guide]: #new-contributor-guide
[Getting Started]: #getting-started
[Issues: Reporting and Resolving]: #issues-reporting-and-resolving
[Making Changes: Fork, Edit, and Pull Request]: #making-changes-fork-edit-and-pull-request
[Testing Your Contributions]: #testing-your-contributions
[Commit your updates]: #commit-your-updates
[Pull Request: From Submission to Merge]: #pull-request-from-submission-to-merge
[Your PR is merged!]: #your-pr-is-merged
## New Contributor Guide
Welcome aboard! If you're new to `esp-hal` or open-source contribution, here are some resources to get you started:
* [Understanding the Project]: A high-level overview of `esp-hal`.
* Intro to Open Source Contribution: [GitHub's Guide]
* [Setting Up Git]
* Workflow Insights: [GitHub Flow]
* Collaborating via [Pull Requests]
Before adding or changing code, review the [esp-rs API guidelines].
[Understanding the Project]: README.md
[GitHub's Guide]: https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github
[Setting Up Git]: https://docs.github.com/en/get-started/quickstart/set-up-git
[GitHub Flow]: https://docs.github.com/en/get-started/quickstart/github-flow
[Pull Requests]: https://docs.github.com/en/github/collaborating-with-pull-requests
[esp-rs API guidelines]: ./documentation/API-GUIDELINES.md
## Getting Started
### Issues: Reporting and Resolving
#### Reporting a New Issue
Encountered a problem or have an idea? First, [check existing issues] to avoid duplicates. If your concern is new, use our [issue form] to submit it.
[check existing issues]: https://github.com/esp-rs/esp-hal/issues
[issue form]: https://github.com/esp-rs/esp-hal/issues/new/
#### Working on an Issue
Browse [existing issues] to find one that resonates with you. Use labels for easier filtering. If you decide to tackle an issue, it's courteous (but not mandatory) to let others know by commenting.
[existing issues]: https://github.com/esp-rs/esp-hal/issues
#### Making Changes: Fork, Edit, and Pull Request
1. **Fork**: Start by [forking the repository]. This keeps the main project safe while you make your changes.
2. **Setup**: Ensure you have the latest Rust toolchain via [rustup.rs].
3. **Branch**: Create a branch in your fork for your changes. Keep your changes focused and limited to a single issue or feature.
[forking the repository]: https://docs.github.com/en/github/getting-started-with-github/fork-a-repo
[rustup.rs]: https://rustup.rs/
#### What You Should Do:
* **API changes**: If your contribution changes the API, please adapt the driver (including module level documentation) and examples accordingly and update the [HIL] (Hardware-in-the-Loop) tests.
* **Run Related Examples**: After making changes, run any affected examples to ensure they build successfully and perform as expected.
* **Manual Testing**: For hardware-related changes, manually test your changes on the actual devices when possible. If not, please note it in the corresponding issue, and someone from our team will assist with testing. This is crucial because hardware behavior can sometimes differ from what's simulated or expected.
* **HIL Tests**: Ensure that any changes to the API or hardware interaction logic are reflected in the HIL tests located in the `hil-test` directory. This helps verify the real-world applicability of your changes.
By taking these extra steps to test your contributions, you help maintain the high quality and reliability of `esp-hal`, ensuring it remains a robust platform for everyone.
[HIL]: https://github.com/esp-rs/esp-hal/tree/main/hil-test
### Testing Your Contributions
Ensuring the quality and reliability of `esp-hal` is a shared responsibility, and testing plays a critical role in this process. Our GitHub CI automatically checks the buildability of all examples and drivers within the project. However, automated tests can't catch everything, especially when it comes to the nuanced behavior of hardware interactions. So make sure that the example affected by your change works as expected.
Further steps that can (or should) be taken in testing:
* Using [xtask], build examples for the specified chip.
* Build the documentation and run the doctests if they have been modified using the `build-documentation` and `run-doc-test` commands in [xtask].
* Run the [HIL] tests locally if changes have been made to them.
[xtask]: https://github.com/esp-rs/esp-hal/tree/main/xtask
### Commit Your Updates
Commit your changes once you're satisfied. Review your own work to streamline the review process later. Use `rustfmt` and `cargo clippy` to ensure your code adheres to Rust's conventions.
```shell
rustup component add rustfmt
rustup component add clippy
```
We _strongly_ recommend that you format your code before committing to ensure consistency throughout the project.
To format all packages in the workspace, run the following command in a terminal from the root of the repository:
```shell
cargo xtask fmt-packages
```
We also recommend using the `lint-packages` subcommand, which uses `cargo clippy` and will lint the entire driver in order to catch common mistakes in the code.
```shell
cargo xtask lint-packages
```
This will use `rustfmt` to ensure that all source code is formatted correctly prior to committing.
## Pull Request: From Submission to Merge
* Fill the pull request template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request.
* [Link your PR] to any relevant issues it addresses.
* [Allow edits from maintainers] so the branch can be updated for a merge. Once you submit your PR, a Docs team member will review your proposal. We may ask questions or request additional information.
* Make sure you add an entry with your changes to the [Changelog]. Also make sure that it is in the appropriate section of the document.
* Make sure you add your changes to the current [migration guide].
* We may ask for changes to be made before a PR can be merged, either using [suggested changes] or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
* As you update your PR and apply changes, mark each conversation as [resolved].
* Resolve merge conflicts if they arise, using resources like [this git tutorial] for help.
[Link your PR]: https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue
[Allow edits from maintainers]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-forkmember
[Changelog]: esp-hal/CHANGELOG.md
[migration guide]: esp-hal/MIGRATING-0.20.md
[suggested changes]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request
[resolved]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/commenting-on-a-pull-request#resolving-conversations
[this git tutorial]: https://github.com/skills/resolve-merge-conflicts
## Your PR is Merged!
Congratulations! The `esp-rs` team thanks you for your contributions!
Contributing to open source extends beyond just code! Each contribution, regardless of size, plays a significant role. We appreciate your involvement in this collective endeavor.

1
esp-alloc/.clippy.toml Normal file
View File

@ -0,0 +1 @@
avoid-breaking-exported-api = false

36
esp-alloc/CHANGELOG.md Normal file
View File

@ -0,0 +1,36 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- `esp_alloc::HEAP.stats()` can now be used to get heap usage informations (#2137)
### Changed
### Fixed
### Removed
## 0.5.0 - 2024-10-10
### Changed
- a global allocator is created in esp-alloc, now you need to add individual memory regions (up to 3) to the allocator (#2099)
## 0.4.0 - 2024-06-04
## 0.3.0 - 2023-04-25
## 0.2.1 - 2023-04-21
## 0.2.0 - 2023-02-22
## 0.1.0 - 2022-07-25
[Unreleased]: https://github.com/esp-rs/esp-hal/commits/main/esp-alloc?since=2024-10-10

View File

@ -1,31 +1,37 @@
[package]
name = "esp-alloc"
version = "0.4.0"
version = "0.5.0"
edition = "2021"
rust-version = "1.68"
description = "A heap allocator for Espressif devices"
keywords = ["allocator", "embedded", "embedded-hal", "esp32", "espressif", "memory"]
categories = ["embedded", "memory-management", "no-std"]
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
keywords = [
"allocator",
"esp32",
"riscv",
"xtensa",
]
categories = [
"memory-management",
"no-std",
]
[package.metadata.docs.rs]
default-target = "riscv32imc-unknown-none-elf"
features = ["nightly"]
[dependencies]
critical-section = "1.1.2"
defmt = { version = "0.3.8", optional = true }
cfg-if = "1.0.0"
critical-section = "1.1.3"
enumset = "1.1.5"
linked_list_allocator = { version = "0.10.5", default-features = false, features = ["const_mut_refs"] }
document-features = "0.2.10"
[features]
default = []
nightly = []
## Implement `defmt::Format` on certain types.
defmt = ["dep:defmt"]
## Enable this feature if you want to keep stats about the internal heap usage such as:
## - Max memory usage since initialization of the heap
## - Total allocated memory since initialization of the heap
## - Total freed memory since initialization of the heap
##
## ⚠️ Note: Enabling this feature will require extra computation every time alloc/dealloc is called.
internal-heap-stats = []

View File

@ -1,33 +1,35 @@
//! A simple `no_std` heap allocator for RISC-V and Xtensa processors from
//! A `no_std` heap allocator for RISC-V and Xtensa processors from
//! Espressif. Supports all currently available ESP32 devices.
//!
//! **NOTE:** using this as your global allocator requires using Rust 1.68 or
//! greater, or the `nightly` release channel.
//!
//! # Using this as your Global Allocator
//! To use EspHeap as your global allocator, you need at least Rust 1.68 or
//! nightly.
//!
//! ```rust
//! #[global_allocator]
//! static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
//! use esp_alloc as _;
//!
//! fn init_heap() {
//! const HEAP_SIZE: usize = 32 * 1024;
//! static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit();
//!
//! unsafe {
//! ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE);
//! esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new(
//! HEAP.as_mut_ptr() as *mut u8,
//! HEAP_SIZE,
//! esp_alloc::MemoryCapability::Internal.into(),
//! ));
//! }
//! }
//! ```
//!
//! # Using this with the nightly `allocator_api`-feature
//! Sometimes you want to have single allocations in PSRAM, instead of an esp's
//! DRAM. For that, it's convenient to use the nightly `allocator_api`-feature,
//! Sometimes you want to have more control over allocations.
//!
//! For that, it's convenient to use the nightly `allocator_api`-feature,
//! which allows you to specify an allocator for single allocations.
//!
//! **NOTE:** To use this, you have to enable the create's `nightly` feature
//! **NOTE:** To use this, you have to enable the crate's `nightly` feature
//! flag.
//!
//! Create and initialize an allocator to use in single allocations:
@ -36,7 +38,11 @@
//!
//! fn init_psram_heap() {
//! unsafe {
//! PSRAM_ALLOCATOR.init(psram::psram_vaddr_start() as *mut u8, psram::PSRAM_BYTES);
//! PSRAM_ALLOCATOR.add_region(esp_alloc::HeapRegion::new(
//! psram::psram_vaddr_start() as *mut u8,
//! psram::PSRAM_BYTES,
//! esp_alloc::MemoryCapability::Internal.into(),
//! ));
//! }
//! }
//! ```
@ -45,51 +51,309 @@
//! ```rust
//! let large_buffer: Vec<u8, _> = Vec::with_capacity_in(1048576, &PSRAM_ALLOCATOR);
//! ```
//!
//! You can also get stats about the heap usage at anytime with:
//! ```rust
//! let stats: HeapStats = esp_alloc::HEAP.stats();
//! // HeapStats implements the Display and defmt::Format traits, so you can pretty-print the heap stats.
//! println!("{}", stats);
//! ```
//!
//! ```txt
//! HEAP INFO
//! Size: 131068
//! Current usage: 46148
//! Max usage: 46148
//! Total freed: 0
//! Total allocated: 46148
//! Memory Layout:
//! Internal | ████████████░░░░░░░░░░░░░░░░░░░░░░░ | Used: 35% (Used 46148 of 131068, free: 84920)
//! Unused | ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ |
//! Unused | ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ |
//! ```
//! ## Feature Flags
#![doc = document_features::document_features!()]
#![no_std]
#![cfg_attr(feature = "nightly", feature(allocator_api))]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
pub mod macros;
mod macros;
#[cfg(feature = "nightly")]
use core::alloc::{AllocError, Allocator};
use core::{
alloc::{GlobalAlloc, Layout},
cell::RefCell,
fmt::Display,
ptr::{self, NonNull},
};
use critical_section::Mutex;
use enumset::{EnumSet, EnumSetType};
use linked_list_allocator::Heap;
/// The global allocator instance
#[global_allocator]
pub static HEAP: EspHeap = EspHeap::empty();
const NON_REGION: Option<HeapRegion> = None;
const BAR_WIDTH: usize = 35;
fn write_bar(f: &mut core::fmt::Formatter<'_>, usage_percent: usize) -> core::fmt::Result {
let used_blocks = BAR_WIDTH * usage_percent / 100;
(0..used_blocks).try_for_each(|_| write!(f, ""))?;
(used_blocks..BAR_WIDTH).try_for_each(|_| write!(f, ""))
}
#[cfg(feature = "defmt")]
fn write_bar_defmt(fmt: defmt::Formatter, usage_percent: usize) {
let used_blocks = BAR_WIDTH * usage_percent / 100;
(0..used_blocks).for_each(|_| defmt::write!(fmt, ""));
(used_blocks..BAR_WIDTH).for_each(|_| defmt::write!(fmt, ""));
}
#[derive(EnumSetType, Debug)]
/// Describes the properties of a memory region
pub enum MemoryCapability {
/// Memory must be internal; specifically it should not disappear when
/// flash/spiram cache is switched off
Internal,
/// Memory must be in SPI RAM
External,
}
/// Stats for a heap region
#[derive(Debug)]
pub struct RegionStats {
/// Total usable size of the heap region in bytes.
size: usize,
/// Currently used size of the heap region in bytes.
used: usize,
/// Free size of the heap region in bytes.
free: usize,
/// Capabilities of the memory region.
capabilities: EnumSet<MemoryCapability>,
}
impl Display for RegionStats {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let usage_percent = self.used * 100 / self.size;
// Display Memory type
if self.capabilities.contains(MemoryCapability::Internal) {
write!(f, "Internal")?;
} else if self.capabilities.contains(MemoryCapability::External) {
write!(f, "External")?;
} else {
write!(f, "Unknown")?;
}
write!(f, " | ")?;
write_bar(f, usage_percent)?;
write!(
f,
" | Used: {}% (Used {} of {}, free: {})",
usage_percent, self.used, self.size, self.free
)
}
}
#[cfg(feature = "defmt")]
impl defmt::Format for RegionStats {
fn format(&self, fmt: defmt::Formatter) {
let usage_percent = self.used * 100 / self.size;
if self.capabilities.contains(MemoryCapability::Internal) {
defmt::write!(fmt, "Internal");
} else if self.capabilities.contains(MemoryCapability::External) {
defmt::write!(fmt, "External");
} else {
defmt::write!(fmt, "Unknown");
}
defmt::write!(fmt, " | ");
write_bar_defmt(fmt, usage_percent);
defmt::write!(
fmt,
" | Used: {}% (Used {} of {}, free: {})",
usage_percent,
self.used,
self.size,
self.free
);
}
}
/// A memory region to be used as heap memory
pub struct HeapRegion {
heap: Heap,
capabilities: EnumSet<MemoryCapability>,
}
impl HeapRegion {
/// Create a new [HeapRegion] with the given capabilities
///
/// # Safety
///
/// - The supplied memory region must be available for the entire program
/// (`'static`).
/// - The supplied memory region must be exclusively available to the heap
/// only, no aliasing.
/// - `size > 0`.
pub unsafe fn new(
heap_bottom: *mut u8,
size: usize,
capabilities: EnumSet<MemoryCapability>,
) -> Self {
let mut heap = Heap::empty();
heap.init(heap_bottom, size);
Self { heap, capabilities }
}
/// Return stats for the current memory region
pub fn stats(&self) -> RegionStats {
RegionStats {
size: self.heap.size(),
used: self.heap.used(),
free: self.heap.free(),
capabilities: self.capabilities,
}
}
}
/// Stats for a heap allocator
///
/// Enable the "internal-heap-stats" feature if you want collect additional heap
/// informations at the cost of extra cpu time during every alloc/dealloc.
#[derive(Debug)]
pub struct HeapStats {
/// Granular stats for all the configured memory regions.
region_stats: [Option<RegionStats>; 3],
/// Total size of all combined heap regions in bytes.
size: usize,
/// Current usage of the heap across all configured regions in bytes.
current_usage: usize,
/// Estimation of the max used heap in bytes.
#[cfg(feature = "internal-heap-stats")]
max_usage: usize,
/// Estimation of the total allocated bytes since initialization.
#[cfg(feature = "internal-heap-stats")]
total_allocated: usize,
/// Estimation of the total freed bytes since initialization.
#[cfg(feature = "internal-heap-stats")]
total_freed: usize,
}
impl Display for HeapStats {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "HEAP INFO")?;
writeln!(f, "Size: {}", self.size)?;
writeln!(f, "Current usage: {}", self.current_usage)?;
#[cfg(feature = "internal-heap-stats")]
{
writeln!(f, "Max usage: {}", self.max_usage)?;
writeln!(f, "Total freed: {}", self.total_freed)?;
writeln!(f, "Total allocated: {}", self.total_allocated)?;
}
writeln!(f, "Memory Layout: ")?;
for region in self.region_stats.iter() {
if let Some(region) = region.as_ref() {
region.fmt(f)?;
writeln!(f)?;
} else {
// Display unused memory regions
write!(f, "Unused | ")?;
write_bar(f, 0)?;
writeln!(f, " |")?;
}
}
Ok(())
}
}
#[cfg(feature = "defmt")]
impl defmt::Format for HeapStats {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "HEAP INFO\n");
defmt::write!(fmt, "Size: {}\n", self.size);
defmt::write!(fmt, "Current usage: {}\n", self.current_usage);
#[cfg(feature = "internal-heap-stats")]
{
defmt::write!(fmt, "Max usage: {}\n", self.max_usage);
defmt::write!(fmt, "Total freed: {}\n", self.total_freed);
defmt::write!(fmt, "Total allocated: {}\n", self.total_allocated);
}
defmt::write!(fmt, "Memory Layout:\n");
for region in self.region_stats.iter() {
if let Some(region) = region.as_ref() {
defmt::write!(fmt, "{}\n", region);
} else {
defmt::write!(fmt, "Unused | ");
write_bar_defmt(fmt, 0);
defmt::write!(fmt, " |\n");
}
}
}
}
/// Internal stats to keep track across multiple regions.
#[cfg(feature = "internal-heap-stats")]
struct InternalHeapStats {
max_usage: usize,
total_allocated: usize,
total_freed: usize,
}
/// A memory allocator
///
/// In addition to what Rust's memory allocator can do it allows to allocate
/// memory in regions satisfying specific needs.
pub struct EspHeap {
heap: Mutex<RefCell<Heap>>,
heap: Mutex<RefCell<[Option<HeapRegion>; 3]>>,
#[cfg(feature = "internal-heap-stats")]
internal_heap_stats: Mutex<RefCell<InternalHeapStats>>,
}
impl EspHeap {
/// Crate a new UNINITIALIZED heap allocator
///
/// You must initialize this heap using the
/// [`init`](struct.EspHeap.html#method.init) method before using the
/// allocator.
pub const fn empty() -> EspHeap {
pub const fn empty() -> Self {
EspHeap {
heap: Mutex::new(RefCell::new(Heap::empty())),
heap: Mutex::new(RefCell::new([NON_REGION; 3])),
#[cfg(feature = "internal-heap-stats")]
internal_heap_stats: Mutex::new(RefCell::new(InternalHeapStats {
max_usage: 0,
total_allocated: 0,
total_freed: 0,
})),
}
}
/// Initializes the heap
///
/// This function must be called BEFORE you run any code that makes use of
/// the allocator.
/// Add a memory region to the heap
///
/// `heap_bottom` is a pointer to the location of the bottom of the heap.
///
/// `size` is the size of the heap in bytes.
///
/// You can add up to three regions per allocator.
///
/// Note that:
///
/// - Memory is allocated from the first suitable memory region first
///
/// - The heap grows "upwards", towards larger addresses. Thus `end_addr`
/// must be larger than `start_addr`
///
@ -102,59 +366,221 @@ impl EspHeap {
/// `'static` lifetime).
/// - The supplied memory region must be exclusively available to the heap
/// only, no aliasing.
/// - This function must be called exactly ONCE.
/// - `size > 0`.
pub unsafe fn init(&self, heap_bottom: *mut u8, size: usize) {
critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().init(heap_bottom, size));
pub unsafe fn add_region(&self, region: HeapRegion) {
critical_section::with(|cs| {
let mut regions = self.heap.borrow_ref_mut(cs);
let free = regions
.iter()
.enumerate()
.find(|v| v.1.is_none())
.map(|v| v.0);
if let Some(free) = free {
regions[free] = Some(region);
} else {
panic!(
"Exceeded the maximum of {} heap memory regions",
regions.len()
);
}
});
}
/// Returns an estimate of the amount of bytes in use.
/// Returns an estimate of the amount of bytes in use in all memory regions.
pub fn used(&self) -> usize {
critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().used())
critical_section::with(|cs| {
let regions = self.heap.borrow_ref(cs);
let mut used = 0;
for region in regions.iter() {
if let Some(region) = region.as_ref() {
used += region.heap.used();
}
}
used
})
}
/// Return usage stats for the [Heap].
///
/// Note:
/// [HeapStats] directly implements [Display], so this function can be
/// called from within `println!()` to pretty-print the usage of the
/// heap.
pub fn stats(&self) -> HeapStats {
const EMPTY_REGION_STAT: Option<RegionStats> = None;
let mut region_stats: [Option<RegionStats>; 3] = [EMPTY_REGION_STAT; 3];
critical_section::with(|cs| {
let mut used = 0;
let mut free = 0;
let regions = self.heap.borrow_ref(cs);
for (id, region) in regions.iter().enumerate() {
if let Some(region) = region.as_ref() {
let stats = region.stats();
free += stats.free;
used += stats.used;
region_stats[id] = Some(region.stats());
}
}
cfg_if::cfg_if! {
if #[cfg(feature = "internal-heap-stats")] {
let internal_heap_stats = self.internal_heap_stats.borrow_ref(cs);
HeapStats {
region_stats,
size: free + used,
current_usage: used,
max_usage: internal_heap_stats.max_usage,
total_allocated: internal_heap_stats.total_allocated,
total_freed: internal_heap_stats.total_freed,
}
} else {
HeapStats {
region_stats,
size: free + used,
current_usage: used,
}
}
}
})
}
/// Returns an estimate of the amount of bytes available.
pub fn free(&self) -> usize {
critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().free())
self.free_caps(EnumSet::empty())
}
/// The free heap satisfying the given requirements
pub fn free_caps(&self, capabilities: EnumSet<MemoryCapability>) -> usize {
critical_section::with(|cs| {
let regions = self.heap.borrow_ref(cs);
let mut free = 0;
for region in regions.iter().filter(|region| {
if region.is_some() {
region
.as_ref()
.unwrap()
.capabilities
.is_superset(capabilities)
} else {
false
}
}) {
if let Some(region) = region.as_ref() {
free += region.heap.free();
}
}
free
})
}
/// Allocate memory in a region satisfying the given requirements.
///
/// # Safety
///
/// This function is unsafe because undefined behavior can result
/// if the caller does not ensure that `layout` has non-zero size.
///
/// The allocated block of memory may or may not be initialized.
pub unsafe fn alloc_caps(
&self,
capabilities: EnumSet<MemoryCapability>,
layout: Layout,
) -> *mut u8 {
critical_section::with(|cs| {
#[cfg(feature = "internal-heap-stats")]
let before = self.used();
let mut regions = self.heap.borrow_ref_mut(cs);
let mut iter = (*regions).iter_mut().filter(|region| {
if region.is_some() {
region
.as_ref()
.unwrap()
.capabilities
.is_superset(capabilities)
} else {
false
}
});
let res = loop {
if let Some(Some(region)) = iter.next() {
let res = region.heap.allocate_first_fit(layout);
if let Ok(res) = res {
break Some(res);
}
} else {
break None;
}
};
res.map_or(ptr::null_mut(), |allocation| {
#[cfg(feature = "internal-heap-stats")]
{
let mut internal_heap_stats = self.internal_heap_stats.borrow_ref_mut(cs);
drop(regions);
// We need to call used because [linked_list_allocator::Heap] does internal size
// alignment so we cannot use the size provided by the layout.
let used = self.used();
internal_heap_stats.total_allocated += used - before;
internal_heap_stats.max_usage =
core::cmp::max(internal_heap_stats.max_usage, used);
}
allocation.as_ptr()
})
})
}
}
unsafe impl GlobalAlloc for EspHeap {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
critical_section::with(|cs| {
self.heap
.borrow(cs)
.borrow_mut()
.allocate_first_fit(layout)
.ok()
.map_or(ptr::null_mut(), |allocation| allocation.as_ptr())
})
self.alloc_caps(EnumSet::empty(), layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
if ptr.is_null() {
return;
}
critical_section::with(|cs| {
self.heap
.borrow(cs)
.borrow_mut()
.deallocate(NonNull::new_unchecked(ptr), layout)
});
#[cfg(feature = "internal-heap-stats")]
let before = self.used();
let mut regions = self.heap.borrow_ref_mut(cs);
let mut iter = (*regions).iter_mut();
while let Some(Some(region)) = iter.next() {
if region.heap.bottom() <= ptr && region.heap.top() >= ptr {
region.heap.deallocate(NonNull::new_unchecked(ptr), layout);
}
}
#[cfg(feature = "internal-heap-stats")]
{
let mut internal_heap_stats = self.internal_heap_stats.borrow_ref_mut(cs);
drop(regions);
// We need to call `used()` because [linked_list_allocator::Heap] does internal
// size alignment so we cannot use the size provided by the
// layout.
internal_heap_stats.total_freed += before - self.used();
}
})
}
}
#[cfg(feature = "nightly")]
unsafe impl Allocator for EspHeap {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
critical_section::with(|cs| {
let raw_ptr = self
.heap
.borrow(cs)
.borrow_mut()
.allocate_first_fit(layout)
.map_err(|_| AllocError)?
.as_ptr();
let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
})
let raw_ptr = unsafe { self.alloc(layout) };
if raw_ptr.is_null() {
return Err(AllocError);
}
let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
}
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {

View File

@ -1,41 +1,43 @@
//! Macros provided for convenience
/// Create a heap allocator providing a heap of the given size in bytes
///
/// You can only have ONE allocator at most
/// Initialize a global heap allocator providing a heap of the given size in
/// bytes
#[macro_export]
macro_rules! heap_allocator {
($size:expr) => {{
#[global_allocator]
static ALLOCATOR: $crate::EspHeap = $crate::EspHeap::empty();
static mut HEAP: core::mem::MaybeUninit<[u8; $size]> = core::mem::MaybeUninit::uninit();
unsafe {
ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, $size);
$crate::HEAP.add_region($crate::HeapRegion::new(
HEAP.as_mut_ptr() as *mut u8,
$size,
$crate::MemoryCapability::Internal.into(),
));
}
}};
}
/// Create a heap allocator backed by PSRAM
/// Initialize a global heap allocator backed by PSRAM
///
/// You can only have ONE allocator at most. You need a SoC which supports PSRAM
/// You need a SoC which supports PSRAM
/// and activate the feature to enable it. You need to pass the PSRAM peripheral
/// and the psram module path.
///
/// # Usage
/// ```no_run
/// ```rust, no_run
/// esp_alloc::psram_allocator!(peripherals.PSRAM, hal::psram);
/// ```
#[macro_export]
macro_rules! psram_allocator {
($peripheral:expr,$psram_module:path) => {{
#[global_allocator]
static ALLOCATOR: $crate::EspHeap = $crate::EspHeap::empty();
($peripheral:expr, $psram_module:path) => {{
use $psram_module as _psram;
_psram::init_psram($peripheral);
let (start, size) = _psram::psram_raw_parts(&$peripheral);
unsafe {
ALLOCATOR.init(_psram::psram_vaddr_start() as *mut u8, _psram::PSRAM_BYTES);
$crate::HEAP.add_region($crate::HeapRegion::new(
start,
size,
$crate::MemoryCapability::External.into(),
));
}
}};
}

View File

@ -0,0 +1,63 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
### Changed
### Fixed
### Removed
## 0.14.2 - 2024-10-10
### Fixed
- Fix build when not using `panic-handler` (#2257)
## 0.14.1 - 2024-09-06
### Added
### Changed
- Print a more helpful message in case of a `Cp0Disabled` exception (#2061)
### Fixed
### Removed
## 0.14.0 - 2024-08-29
### Added
- Add custom-pre-backtrace feature (#1822)
### Changed
- Improve panic message printing (#1823)
## 0.13.0 - 2024-07-16
No changes - published to avoid conflicts with `esp-println`
## 0.12.2 - 2024-07-15
### Changed
- Remove build script check for `nightly-2024-06-12` (#1788)
## 0.12.1 - 2024-06-19
### Fixed
- Fix compilation for nightly after 2024-06-12. (#1681)
- Only prints float registers on targets which have them. (#1690)
[Unreleased]: https://github.com/esp-rs/esp-hal/commits/main/esp-backtrace?since=2024-10-10

View File

@ -1,9 +1,11 @@
[package]
name = "esp-backtrace"
version = "0.12.0"
version = "0.14.2"
edition = "2021"
rust-version = "1.76.0"
description = "Bare-metal backtrace support for ESP32"
description = "Bare-metal backtrace support for Espressif devices"
keywords = ["backtrace", "embedded", "esp32", "espressif"]
categories = ["embedded", "hardware-support", "no-std"]
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
@ -13,8 +15,8 @@ features = ["esp32c3", "panic-handler", "exception-handler", "println", "e
[dependencies]
defmt = { version = "0.3.8", optional = true }
esp-println = { version = "0.9.1", optional = true, default-features = false, path = "../esp-println" }
semihosting = { version = "0.1.10", optional = true }
esp-println = { version = "0.12.0", optional = true, default-features = false, path = "../esp-println" }
semihosting = { version = "0.1.15", optional = true }
[build-dependencies]
esp-build = { version = "0.1.0", path = "../esp-build" }
@ -23,14 +25,14 @@ esp-build = { version = "0.1.0", path = "../esp-build" }
default = ["colors"]
# You must enable exactly one of the below features to support the correct chip:
esp32 = ["esp-println?/esp32", "semihosting?/openocd-semihosting"]
esp32 = ["esp-println?/esp32", "semihosting?/openocd-semihosting", "print-float-registers"]
esp32c2 = ["esp-println?/esp32c2"]
esp32c3 = ["esp-println?/esp32c3"]
esp32c6 = ["esp-println?/esp32c6"]
esp32h2 = ["esp-println?/esp32h2"]
esp32p4 = ["esp-println?/esp32p4"]
esp32s2 = ["esp-println?/esp32s2", "semihosting?/openocd-semihosting"]
esp32s3 = ["esp-println?/esp32s3", "semihosting?/openocd-semihosting"]
esp32s3 = ["esp-println?/esp32s3", "semihosting?/openocd-semihosting", "print-float-registers"]
# Use esp-println
println = ["dep:esp-println"]
@ -38,13 +40,16 @@ println = ["dep:esp-println"]
# Use defmt
defmt = ["dep:defmt"]
print-float-registers = [] # TODO support esp32p4
# You may optionally enable one or more of the below features to provide
# additional functionality:
colors = []
custom-halt = []
exception-handler = []
halt-cores = []
panic-handler = []
colors = []
custom-halt = []
custom-pre-backtrace = []
exception-handler = []
halt-cores = []
panic-handler = []
[lints.rust]
unexpected_cfgs = "allow"

View File

@ -17,24 +17,25 @@ When using the panic and/or exception handler make sure to include `use esp_back
## Features
| Feature | Description |
| ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| esp32 | Target ESP32 |
| esp32c2 | Target ESP32-C2 |
| esp32c3 | Target ESP32-C3 |
| esp32c6 | Target ESP32-C6 |
| esp32h2 | Target ESP32-H2 |
| esp32p4 | Target ESP32-P4 |
| esp32s2 | Target ESP32-S2 |
| esp32s3 | Target ESP32-S3 |
| panic-handler | Include a panic handler, will add `esp-println` as a dependency |
| exception-handler | Include an exception handler, will add `esp-println` as a dependency |
| println | Use `esp-println` to print messages |
| defmt | Use `defmt` logging to print messages\* (check [example](https://github.com/playfulFence/backtrace-defmt-example)) |
| colors | Print messages in red\* |
| halt-cores | Halt both CPUs on ESP32 / ESP32-S3 instead of doing a `loop {}` in case of a panic or exception |
| semihosting | Call `semihosting::process::abort()` on panic. |
| custom-halt | Invoke the extern function `custom_halt()` instead of doing a `loop {}` in case of a panic or exception |
| Feature | Description |
|----------------------|--------------------------------------------------------------------------------------------------------------------|
| esp32 | Target ESP32 |
| esp32c2 | Target ESP32-C2 |
| esp32c3 | Target ESP32-C3 |
| esp32c6 | Target ESP32-C6 |
| esp32h2 | Target ESP32-H2 |
| esp32p4 | Target ESP32-P4 |
| esp32s2 | Target ESP32-S2 |
| esp32s3 | Target ESP32-S3 |
| panic-handler | Include a panic handler, will add `esp-println` as a dependency |
| exception-handler | Include an exception handler, will add `esp-println` as a dependency |
| println | Use `esp-println` to print messages |
| defmt | Use `defmt` logging to print messages\* (check [example](https://github.com/playfulFence/backtrace-defmt-example)) |
| colors | Print messages in red\* |
| halt-cores | Halt both CPUs on ESP32 / ESP32-S3 instead of doing a `loop {}` in case of a panic or exception |
| semihosting | Call `semihosting::process::abort()` on panic. |
| custom-halt | Invoke the extern function `custom_halt()` instead of doing a `loop {}` in case of a panic or exception |
| custom-pre-backtrace | Invoke the extern function `custom_pre_backtrace()` before handling a panic or exception |
\* _only used for panic and exception handlers_

View File

@ -12,21 +12,4 @@ fn main() {
if cfg!(feature = "custom-halt") && cfg!(feature = "halt-cores") {
panic!("Only one of `custom-halt` and `halt-cores` can be enabled");
}
if is_nightly() {
println!("cargo:rustc-cfg=nightly");
}
}
fn is_nightly() -> bool {
let version_output = std::process::Command::new(
std::env::var_os("RUSTC").unwrap_or_else(|| std::ffi::OsString::from("rustc")),
)
.arg("-V")
.output()
.unwrap()
.stdout;
let version_string = String::from_utf8_lossy(&version_output);
version_string.contains("nightly")
}

View File

@ -1,5 +1,4 @@
#![allow(rustdoc::bare_urls, unused_macros)]
#![cfg_attr(nightly, feature(panic_info_message))]
#![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))]
#![doc = include_str!("../README.md")]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
@ -49,41 +48,19 @@ pub mod arch;
#[cfg(feature = "panic-handler")]
#[panic_handler]
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
pre_backtrace();
#[cfg(feature = "colors")]
set_color_code(RED);
println!("");
println!("");
println!("====================== PANIC ======================");
if let Some(location) = info.location() {
let (file, line, column) = (location.file(), location.line(), location.column());
println!(
"!! A panic occured in '{}', at line {}, column {}:",
file, line, column
);
} else {
println!("!! A panic occured at an unknown location:");
}
#[cfg(not(feature = "defmt"))]
println!("{}", info);
#[cfg(not(nightly))]
{
#[cfg(not(feature = "defmt"))]
println!("{:#?}", info);
#[cfg(feature = "defmt")]
println!("{:#?}", defmt::Display2Format(info));
}
#[cfg(nightly)]
{
if let Some(message) = info.message() {
#[cfg(not(feature = "defmt"))]
println!("{}", message);
#[cfg(feature = "defmt")]
println!("{}", defmt::Display2Format(message));
}
}
#[cfg(feature = "defmt")]
println!("{}", defmt::Display2Format(info));
println!("");
println!("Backtrace:");
@ -94,14 +71,12 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
if backtrace.iter().filter(|e| e.is_some()).count() == 0 {
println!("No backtrace available - make sure to force frame-pointers. (see https://crates.io/crates/esp-backtrace)");
}
for e in backtrace {
if let Some(addr) = e {
#[cfg(all(feature = "colors", feature = "println"))]
println!("{}0x{:x}", RED, addr - crate::arch::RA_OFFSET);
for addr in backtrace.into_iter().flatten() {
#[cfg(all(feature = "colors", feature = "println"))]
println!("{}0x{:x}", RED, addr - crate::arch::RA_OFFSET);
#[cfg(not(all(feature = "colors", feature = "println")))]
println!("0x{:x}", addr - crate::arch::RA_OFFSET);
}
#[cfg(not(all(feature = "colors", feature = "println")))]
println!("0x{:x}", addr - crate::arch::RA_OFFSET);
}
#[cfg(feature = "colors")]
@ -110,6 +85,7 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
#[cfg(feature = "semihosting")]
semihosting::process::abort();
#[cfg(not(feature = "semihosting"))]
halt();
}
@ -117,15 +93,17 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
#[no_mangle]
#[link_section = ".rwtext"]
unsafe fn __user_exception(cause: arch::ExceptionCause, context: arch::Context) {
pre_backtrace();
#[cfg(feature = "colors")]
set_color_code(RED);
// Unfortunately, a different formatter string is used
#[cfg(not(feature = "defmt"))]
esp_println::println!("\n\nException occured '{:?}'", cause);
esp_println::println!("\n\nException occurred '{}'", cause);
#[cfg(feature = "defmt")]
defmt::error!("\n\nException occured '{}'", cause);
defmt::error!("\n\nException occurred '{}'", cause);
println!("{:?}", context);
@ -145,12 +123,15 @@ unsafe fn __user_exception(cause: arch::ExceptionCause, context: arch::Context)
#[cfg(feature = "semihosting")]
semihosting::process::abort();
#[cfg(not(feature = "semihosting"))]
halt();
}
#[cfg(all(feature = "exception-handler", target_arch = "riscv32"))]
#[export_name = "ExceptionHandler"]
fn exception_handler(context: &arch::TrapFrame) -> ! {
pre_backtrace();
let mepc = context.pc;
let code = context.mcause & 0xff;
let mtval = context.mtval;
@ -200,14 +181,12 @@ fn exception_handler(context: &arch::TrapFrame) -> ! {
if backtrace.iter().filter(|e| e.is_some()).count() == 0 {
println!("No backtrace available - make sure to force frame-pointers. (see https://crates.io/crates/esp-backtrace)");
}
for e in backtrace {
if let Some(addr) = e {
#[cfg(all(feature = "colors", feature = "println"))]
println!("{}0x{:x}", RED, addr - crate::arch::RA_OFFSET);
for addr in backtrace.into_iter().flatten() {
#[cfg(all(feature = "colors", feature = "println"))]
println!("{}0x{:x}", RED, addr - crate::arch::RA_OFFSET);
#[cfg(not(all(feature = "colors", feature = "println")))]
println!("0x{:x}", addr - crate::arch::RA_OFFSET);
}
#[cfg(not(all(feature = "colors", feature = "println")))]
println!("0x{:x}", addr - crate::arch::RA_OFFSET);
}
}
@ -221,6 +200,7 @@ fn exception_handler(context: &arch::TrapFrame) -> ! {
#[cfg(feature = "semihosting")]
semihosting::process::abort();
#[cfg(not(feature = "semihosting"))]
halt();
}
@ -347,3 +327,15 @@ fn halt() -> ! {
loop {}
}
#[cfg(not(feature = "custom-pre-backtrace"))]
#[allow(unused)]
fn pre_backtrace() {}
#[cfg(feature = "custom-pre-backtrace")]
fn pre_backtrace() {
extern "Rust" {
fn custom_pre_backtrace();
}
unsafe { custom_pre_backtrace() }
}

View File

@ -4,56 +4,106 @@ use crate::MAX_BACKTRACE_ADDRESSES;
// subtract 4 from the return address
// the return address is the address following the JALR
// we get better results (especially if the caller was the last function in the
// calling function) if we report the address of the JALR itself
// we get better results (especially if the caller was the last instruction in
// the calling function) if we report the address of the JALR itself
// even if it was a C.JALR we should get good results using RA - 4
#[allow(unused)]
pub(super) const RA_OFFSET: usize = 4;
/// Registers saved in trap handler
#[doc(hidden)]
#[allow(missing_docs)]
#[derive(Default, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(C)]
#[cfg(feature = "exception-handler")]
pub(crate) struct TrapFrame {
/// Return address, stores the address to return to after a function call or
/// interrupt.
pub ra: usize,
/// Temporary register t0, used for intermediate values.
pub t0: usize,
/// Temporary register t1, used for intermediate values.
pub t1: usize,
/// Temporary register t2, used for intermediate values.
pub t2: usize,
/// Temporary register t3, used for intermediate values.
pub t3: usize,
/// Temporary register t4, used for intermediate values.
pub t4: usize,
/// Temporary register t5, used for intermediate values.
pub t5: usize,
/// Temporary register t6, used for intermediate values.
pub t6: usize,
/// Argument register a0, typically used to pass the first argument to a
/// function.
pub a0: usize,
/// Argument register a1, typically used to pass the second argument to a
/// function.
pub a1: usize,
/// Argument register a2, typically used to pass the third argument to a
/// function.
pub a2: usize,
/// Argument register a3, typically used to pass the fourth argument to a
/// function.
pub a3: usize,
/// Argument register a4, typically used to pass the fifth argument to a
/// function.
pub a4: usize,
/// Argument register a5, typically used to pass the sixth argument to a
/// function.
pub a5: usize,
/// Argument register a6, typically used to pass the seventh argument to a
/// function.
pub a6: usize,
/// Argument register a7, typically used to pass the eighth argument to a
/// function.
pub a7: usize,
/// Saved register s0, used to hold values across function calls.
pub s0: usize,
/// Saved register s1, used to hold values across function calls.
pub s1: usize,
/// Saved register s2, used to hold values across function calls.
pub s2: usize,
/// Saved register s3, used to hold values across function calls.
pub s3: usize,
/// Saved register s4, used to hold values across function calls.
pub s4: usize,
/// Saved register s5, used to hold values across function calls.
pub s5: usize,
/// Saved register s6, used to hold values across function calls.
pub s6: usize,
/// Saved register s7, used to hold values across function calls.
pub s7: usize,
/// Saved register s8, used to hold values across function calls.
pub s8: usize,
/// Saved register s9, used to hold values across function calls.
pub s9: usize,
/// Saved register s10, used to hold values across function calls.
pub s10: usize,
/// Saved register s11, used to hold values across function calls.
pub s11: usize,
/// Global pointer register, holds the address of the global data area.
pub gp: usize,
/// Thread pointer register, holds the address of the thread-local storage
/// area.
pub tp: usize,
/// Stack pointer register, holds the address of the top of the stack.
pub sp: usize,
/// Program counter, stores the address of the next instruction to be
/// executed.
pub pc: usize,
/// Machine status register, holds the current status of the processor,
/// including interrupt enable bits and privilege mode.
pub mstatus: usize,
/// Machine cause register, contains the reason for the trap (e.g.,
/// exception or interrupt number).
pub mcause: usize,
/// Machine trap value register, contains additional information about the
/// trap (e.g., faulting address).
pub mtval: usize,
}
#[cfg(feature = "exception-handler")]
impl core::fmt::Debug for TrapFrame {
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
write!(

View File

@ -1,4 +1,4 @@
use core::arch::asm;
use core::{arch::asm, fmt::Display};
use crate::MAX_BACKTRACE_ADDRESSES;
@ -6,11 +6,12 @@ use crate::MAX_BACKTRACE_ADDRESSES;
// the return address is the address following the callxN
// we get better results (especially if the caller was the last function in the
// calling function) if we report the address of callxN itself
#[allow(unused)]
pub(super) const RA_OFFSET: usize = 3;
/// Exception Cause
#[doc(hidden)]
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(C)]
pub enum ExceptionCause {
@ -94,69 +95,176 @@ pub enum ExceptionCause {
Cp6Disabled = 38,
/// Access To Coprocessor 7 When Disabled
Cp7Disabled = 39,
/// None
None = 255,
}
impl Display for ExceptionCause {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if *self == Self::Cp0Disabled {
write!(f, "Cp0Disabled (Access to the floating point coprocessor is not allowed. You may want to enable the `float-save-restore` feature of the `xtensa-lx-rt` crate.)")
} else {
write!(f, "{:?}", self)
}
}
}
#[doc(hidden)]
#[allow(missing_docs, non_snake_case)]
#[allow(non_snake_case)]
#[derive(Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(C)]
pub struct Context {
/// Program counter, stores the address of the next instruction to be
/// executed.
pub PC: u32,
/// Processor status, holds various status flags for the CPU.
pub PS: u32,
/// General-purpose register A0 used for data storage and manipulation.
pub A0: u32,
/// General-purpose register A1 used for data storage and manipulation.
pub A1: u32,
/// General-purpose register A2 used for data storage and manipulation.
pub A2: u32,
/// General-purpose register A3 used for data storage and manipulation.
pub A3: u32,
/// General-purpose register A4 used for data storage and manipulation.
pub A4: u32,
/// General-purpose register A5 used for data storage and manipulation.
pub A5: u32,
/// General-purpose register A6 used for data storage and manipulation.
pub A6: u32,
/// General-purpose register A7 used for data storage and manipulation.
pub A7: u32,
/// General-purpose register A8 used for data storage and manipulation.
pub A8: u32,
/// General-purpose register A9 used for data storage and manipulation.
pub A9: u32,
/// General-purpose register A10 used for data storage and manipulation.
pub A10: u32,
/// General-purpose register A11 used for data storage and manipulation.
pub A11: u32,
/// General-purpose register A12 used for data storage and manipulation.
pub A12: u32,
/// General-purpose register A13 used for data storage and manipulation.
pub A13: u32,
/// General-purpose register A14 used for data storage and manipulation.
pub A14: u32,
/// General-purpose register A15 used for data storage and manipulation.
pub A15: u32,
/// Shift amount register, used for shift and rotate instructions.
pub SAR: u32,
/// Exception cause, indicates the reason for the last exception.
pub EXCCAUSE: u32,
/// Exception address, holds the address related to the exception.
pub EXCVADDR: u32,
/// Loop start address, used in loop instructions.
pub LBEG: u32,
/// Loop end address, used in loop instructions.
pub LEND: u32,
/// Loop counter, used to count iterations in loop instructions.
pub LCOUNT: u32,
/// Thread pointer, used for thread-local storage.
pub THREADPTR: u32,
/// Compare register, used for certain compare instructions.
pub SCOMPARE1: u32,
/// Break register, used for breakpoint-related operations.
pub BR: u32,
/// Accumulator low register, used for extended arithmetic operations.
pub ACCLO: u32,
/// Accumulator high register, used for extended arithmetic operations.
pub ACCHI: u32,
/// Additional register M0 used for special operations.
pub M0: u32,
/// Additional register M1 used for special operations.
pub M1: u32,
/// Additional register M2 used for special operations.
pub M2: u32,
/// Additional register M3 used for special operations.
pub M3: u32,
/// 64-bit floating-point register (low part), available if the
/// `print-float-registers` feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F64R_LO: u32,
/// 64-bit floating-point register (high part), available if the
/// `print-float-registers` feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F64R_HI: u32,
/// Floating-point status register, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F64S: u32,
/// Floating-point control register, available if the
/// `print-float-registers` feature is enabled.
#[cfg(feature = "print-float-registers")]
pub FCR: u32,
/// Floating-point status register, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub FSR: u32,
/// Floating-point register F0, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F0: u32,
/// Floating-point register F1, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F1: u32,
/// Floating-point register F2, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F2: u32,
/// Floating-point register F3, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F3: u32,
/// Floating-point register F4, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F4: u32,
/// Floating-point register F5, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F5: u32,
/// Floating-point register F6, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F6: u32,
/// Floating-point register F7, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F7: u32,
/// Floating-point register F8, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F8: u32,
/// Floating-point register F9, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F9: u32,
/// Floating-point register F10, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F10: u32,
/// Floating-point register F11, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F11: u32,
/// Floating-point register F12, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F12: u32,
/// Floating-point register F13, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F13: u32,
/// Floating-point register F14, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F14: u32,
/// Floating-point register F15, available if the `print-float-registers`
/// feature is enabled.
#[cfg(feature = "print-float-registers")]
pub F15: u32,
}
@ -178,12 +286,6 @@ SCOMPARE1=0x{:08x}
BR=0x{:08x}
ACCLO=0x{:08x} ACCHI=0x{:08x}
M0=0x{:08x} M1=0x{:08x} M2=0x{:08x} M3=0x{:08x}
F64R_LO=0x{:08x} F64R_HI=0x{:08x} F64S=0x{:08x}
FCR=0x{:08x} FSR=0x{:08x}
F0=0x{:08x} F1=0x{:08x} F2=0x{:08x} F3=0x{:08x} F4=0x{:08x}
F5=0x{:08x} F6=0x{:08x} F7=0x{:08x} F8=0x{:08x} F9=0x{:08x}
F10=0x{:08x} F11=0x{:08x} F12=0x{:08x} F13=0x{:08x} F14=0x{:08x}
F15=0x{:08x}
",
self.PC,
self.PS,
@ -218,6 +320,16 @@ F15=0x{:08x}
self.M1,
self.M2,
self.M3,
)?;
#[cfg(feature = "print-float-registers")]
write!(
fmt,
"F64R_LO=0x{:08x} F64R_HI=0x{:08x} F64S=0x{:08x}
FCR=0x{:08x} FSR=0x{:08x}
F0=0x{:08x} F1=0x{:08x} F2=0x{:08x} F3=0x{:08x} F4=0x{:08x}
F5=0x{:08x} F6=0x{:08x} F7=0x{:08x} F8=0x{:08x} F9=0x{:08x}
F10=0x{:08x} F11=0x{:08x} F12=0x{:08x} F13=0x{:08x} F14=0x{:08x}
F15=0x{:08x}",
self.F64R_LO,
self.F64R_HI,
self.F64S,
@ -239,7 +351,9 @@ F15=0x{:08x}
self.F13,
self.F14,
self.F15,
)
)?;
Ok(())
}
}
@ -280,7 +394,8 @@ pub(crate) fn backtrace_internal(
old_address = address;
if address == 0 {
// the address is 0 but we sanitized the address - then 0 becomes 0x40000000
if address == 0x40000000 {
break;
}

24
esp-build/CHANGELOG.md Normal file
View File

@ -0,0 +1,24 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
### Fixed
### Changed
- Use `panic` instead of `process::exit` in esp-build (#2402 )
### Removed
## [0.1.0] - 2024-04-17
- Initial release
[Unreleased]: https://github.com/esp-rs/esp-hal/commits/main/esp-build?since=2024-04-17

View File

@ -11,6 +11,6 @@ license = "MIT OR Apache-2.0"
proc-macro = true
[dependencies]
quote = "1.0.35"
syn = { version = "2.0.52", features = ["fold", "full"] }
quote = "1.0.37"
syn = { version = "2.0.79", features = ["fold", "full"] }
termcolor = "1.4.1"

View File

@ -2,9 +2,10 @@
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
use std::{io::Write as _, process};
use std::io::Write as _;
use proc_macro::TokenStream;
use quote::ToTokens;
use syn::{parse_macro_input, punctuated::Punctuated, LitStr, Token};
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
@ -25,7 +26,7 @@ use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
#[proc_macro]
pub fn error(input: TokenStream) -> TokenStream {
do_alert(Color::Red, input);
process::exit(1);
panic!("Build failed");
}
/// Print a build warning.
@ -58,22 +59,10 @@ pub fn assert_unique_features(input: TokenStream) -> TokenStream {
.into_iter()
.collect::<Vec<_>>();
let pairs = unique_pairs(&features);
let unique_cfgs = pairs
.iter()
.map(|(a, b)| quote::quote! { all(feature = #a, feature = #b) });
let message = format!(
r#"
ERROR: expected exactly zero or one enabled feature from feature group:
{:?}
"#,
features.iter().map(|lit| lit.value()).collect::<Vec<_>>(),
);
let unique = impl_unique_features(&features, "exactly zero or one");
quote::quote! {
#[cfg(any(#(#unique_cfgs),*))]
::esp_build::error! { #message }
#unique
}
.into()
}
@ -91,17 +80,10 @@ pub fn assert_used_features(input: TokenStream) -> TokenStream {
.into_iter()
.collect::<Vec<_>>();
let message = format!(
r#"
ERROR: expected at least one enabled feature from feature group:
{:?}
"#,
features.iter().map(|lit| lit.value()).collect::<Vec<_>>()
);
let used = impl_used_features(&features, "at least one");
quote::quote! {
#[cfg(not(any(#(feature = #features),*)))]
::esp_build::error! { #message }
#used
}
.into()
}
@ -118,22 +100,12 @@ pub fn assert_unique_used_features(input: TokenStream) -> TokenStream {
.into_iter()
.collect::<Vec<_>>();
let pairs = unique_pairs(&features);
let unique_cfgs = pairs
.iter()
.map(|(a, b)| quote::quote! { all(feature = #a, feature = #b) });
let message = format!(
r#"
ERROR: expected exactly one enabled feature from feature group:
{:?}
"#,
features.iter().map(|lit| lit.value()).collect::<Vec<_>>()
);
let unique = impl_unique_features(&features, "exactly one");
let used = impl_used_features(&features, "exactly one");
quote::quote! {
#[cfg(any(any(#(#unique_cfgs),*), not(any(#(feature = #features),*))))]
::esp_build::error! { #message }
#unique
#used
}
.into()
}
@ -141,6 +113,41 @@ ERROR: expected exactly one enabled feature from feature group:
// ----------------------------------------------------------------------------
// Helper Functions
fn impl_unique_features(features: &[LitStr], expectation: &str) -> impl ToTokens {
let pairs = unique_pairs(features);
let unique_cfgs = pairs
.iter()
.map(|(a, b)| quote::quote! { all(feature = #a, feature = #b) });
let message = format!(
r#"
ERROR: expected {expectation} enabled feature from feature group:
{:?}
"#,
features.iter().map(|lit| lit.value()).collect::<Vec<_>>(),
);
quote::quote! {
#[cfg(any(#(#unique_cfgs),*))]
::esp_build::error! { #message }
}
}
fn impl_used_features(features: &[LitStr], expectation: &str) -> impl ToTokens {
let message = format!(
r#"
ERROR: expected {expectation} enabled feature from feature group:
{:?}
"#,
features.iter().map(|lit| lit.value()).collect::<Vec<_>>()
);
quote::quote! {
#[cfg(not(any(#(feature = #features),*)))]
::esp_build::error! { #message }
}
}
// Adapted from:
// https://github.com/dtolnay/build-alert/blob/49d060e/src/lib.rs#L54-L93
fn do_alert(color: Color, input: TokenStream) -> TokenStream {

32
esp-config/CHANGELOG.md Normal file
View File

@ -0,0 +1,32 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
### Fixed
- Users no longer have to manually import `esp_config_int_parse`. (#2630)
### Changed
- Crate prefixes and configuration keys are now separated by `_CONFIG_` (#2848)
### Removed
## 0.2.0 - 2024-11-20
### Added
- Add configuration validation (#2475)
## 0.1.0 - 2024-10-10
- Initial release
[Unreleased]: https://github.com/esp-rs/esp-hal/commits/main/esp-config?since=2024-11-20

18
esp-config/Cargo.toml Normal file
View File

@ -0,0 +1,18 @@
[package]
name = "esp-config"
version = "0.2.0"
edition = "2021"
rust-version = "1.79.0"
description = "Configure projects using esp-hal and related packages"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
[dependencies]
document-features = "0.2.10"
[dev-dependencies]
temp-env = "0.3.6"
[features]
## Enable the generation and parsing of a config
build = []

65
esp-config/README.md Normal file
View File

@ -0,0 +1,65 @@
# esp-config
[![Crates.io](https://img.shields.io/crates/v/esp-config?labelColor=1C2C2E&color=C96329&logo=Rust&style=flat-square)](https://crates.io/crates/esp-config)
[![docs.rs](https://img.shields.io/docsrs/esp-config?labelColor=1C2C2E&color=C96329&logo=rust&style=flat-square)](https://docs.rs/esp-config)
![MSRV](https://img.shields.io/badge/MSRV-1.79-blue?labelColor=1C2C2E&style=flat-square)
![Crates.io](https://img.shields.io/crates/l/esp-config?labelColor=1C2C2E&style=flat-square)
[![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&labelColor=1C2C2E&color=BEC5C9&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org)
## [Documentation](https://docs.rs/crate/esp-config)
## Usage
`esp-config` takes a prefix (usually the crate name) and a set of configuration keys and default values to produce a configuration system that supports:
- Emitting rustc cfg's for boolean keys
- Emitting environment variables for numbers
- Along with decimal parsing, it supports Hex, Octal and Binary with the respective `0x`, `0o` and `0b` prefixes.
- Emitting environment variables string values
### Viewing the configuration
The possible configuration values are output as a markdown table in the crates `OUT_DIR` with the format `{prefix}_config_table.md`, this can then be included into the crates top level documentation. Here is an example of the output:
| Name | Description | Default value |
|------|-------------|---------------|
|**ESP_HAL_PLACE_SPI_DRIVER_IN_RAM**|Places the SPI driver in RAM for better performance|false|
### Setting configuration options
For any available configuration option, the environment variable or cfg is _always_ set based on the default value specified in the table. Users can override this by setting environment variables locally in their shell _or_ the preferred option is to utilize cargo's [`env` section](https://doc.rust-lang.org/cargo/reference/config.html#env).
It's important to note that due to a [bug in cargo](https://github.com/rust-lang/cargo/issues/10358), any modifications to the environment, local or otherwise will only get picked up on a full clean build of the project.
To see the final selected configuration another table is output to the `OUT_DIR` with the format `{prefix}_selected_config.md`.
### Capturing configuration values in the downstream crate
For all supported data types, there are helper macros that emit `const` code for parsing the configuration values.
- Numbers - `esp_config_int!(integer_type, "ENV")`
- Strings - `esp_config_str!("ENV")`
- Bool - `esp_config_bool!("ENV")`
In addition to environment variables, for boolean types rust `cfg`'s are emitted in snake case _without_ the prefix.
## Minimum Supported Rust Version (MSRV)
This crate is guaranteed to compile on stable Rust 1.79 and up. It _might_
compile with older versions but that may change in any new patch release.
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without
any additional terms or conditions.

699
esp-config/src/generate.rs Normal file
View File

@ -0,0 +1,699 @@
use std::{
collections::HashMap,
env,
fmt::{self, Write as _},
fs,
ops::Range,
path::PathBuf,
};
const DOC_TABLE_HEADER: &str = r#"
| Name | Description | Default value |
|------|-------------|---------------|
"#;
const SELECTED_TABLE_HEADER: &str = r#"
| Name | Selected value |
|------|----------------|
"#;
/// Configuration errors.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
/// Parse errors.
Parse(String),
/// Validation errors.
Validation(String),
}
impl Error {
/// Convenience function for creating parse errors.
pub fn parse<S>(message: S) -> Self
where
S: Into<String>,
{
Self::Parse(message.into())
}
/// Convenience function for creating validation errors.
pub fn validation<S>(message: S) -> Self
where
S: Into<String>,
{
Self::Validation(message.into())
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Parse(message) => write!(f, "{message}"),
Error::Validation(message) => write!(f, "{message}"),
}
}
}
/// Supported configuration value types.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Value {
/// Booleans.
Bool(bool),
/// Integers.
Integer(i128),
/// Strings.
String(String),
}
// TODO: Do we want to handle negative values for non-decimal values?
impl Value {
fn parse_in_place(&mut self, s: &str) -> Result<(), Error> {
*self = match self {
Value::Bool(_) => match s {
"true" => Value::Bool(true),
"false" => Value::Bool(false),
_ => {
return Err(Error::parse(format!(
"Expected 'true' or 'false', found: '{s}'"
)))
}
},
Value::Integer(_) => {
let inner = match s.as_bytes() {
[b'0', b'x', ..] => i128::from_str_radix(&s[2..], 16),
[b'0', b'o', ..] => i128::from_str_radix(&s[2..], 8),
[b'0', b'b', ..] => i128::from_str_radix(&s[2..], 2),
_ => i128::from_str_radix(&s, 10),
}
.map_err(|_| Error::parse(format!("Expected valid intger value, found: '{s}'")))?;
Value::Integer(inner)
}
Value::String(_) => Value::String(s.into()),
};
Ok(())
}
/// Convert the value to a [bool].
pub fn as_bool(&self) -> bool {
match self {
Value::Bool(value) => *value,
_ => panic!("attempted to convert non-bool value to a bool"),
}
}
/// Convert the value to an [i128].
pub fn as_integer(&self) -> i128 {
match self {
Value::Integer(value) => *value,
_ => panic!("attempted to convert non-integer value to an integer"),
}
}
/// Convert the value to a [String].
pub fn as_string(&self) -> String {
match self {
Value::String(value) => value.to_owned(),
_ => panic!("attempted to convert non-string value to a string"),
}
}
/// Is the value a bool?
pub fn is_bool(&self) -> bool {
matches!(self, Value::Bool(_))
}
/// Is the value an integer?
pub fn is_integer(&self) -> bool {
matches!(self, Value::Integer(_))
}
/// Is the value a string?
pub fn is_string(&self) -> bool {
matches!(self, Value::String(_))
}
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Value::Bool(b) => write!(f, "{b}"),
Value::Integer(i) => write!(f, "{i}"),
Value::String(s) => write!(f, "{s}"),
}
}
}
/// Configuration value validation functions.
pub enum Validator {
/// Only allow negative integers, i.e. any values less than 0.
NegativeInteger,
/// Only allow non-negative integers, i.e. any values greater than or equal
/// to 0.
NonNegativeInteger,
/// Only allow positive integers, i.e. any values greater than to 0.
PositiveInteger,
/// Ensure that an integer value falls within the specified range.
IntegerInRange(Range<i128>),
/// A custom validation function to run against any supported value type.
Custom(Box<dyn Fn(&Value) -> Result<(), Error>>),
}
impl Validator {
fn validate(&self, value: &Value) -> Result<(), Error> {
match self {
Validator::NegativeInteger => negative_integer(value)?,
Validator::NonNegativeInteger => non_negative_integer(value)?,
Validator::PositiveInteger => positive_integer(value)?,
Validator::IntegerInRange(range) => integer_in_range(range, value)?,
Validator::Custom(validator_fn) => validator_fn(value)?,
}
Ok(())
}
}
fn negative_integer(value: &Value) -> Result<(), Error> {
if !value.is_integer() {
return Err(Error::validation(
"Validator::NegativeInteger can only be used with integer values",
));
} else if value.as_integer() >= 0 {
return Err(Error::validation(format!(
"Expected negative integer, found '{}'",
value.as_integer()
)));
}
Ok(())
}
fn non_negative_integer(value: &Value) -> Result<(), Error> {
if !value.is_integer() {
return Err(Error::validation(
"Validator::NonNegativeInteger can only be used with integer values",
));
} else if value.as_integer() < 0 {
return Err(Error::validation(format!(
"Expected non-negative integer, found '{}'",
value.as_integer()
)));
}
Ok(())
}
fn positive_integer(value: &Value) -> Result<(), Error> {
if !value.is_integer() {
return Err(Error::validation(
"Validator::PositiveInteger can only be used with integer values",
));
} else if value.as_integer() <= 0 {
return Err(Error::validation(format!(
"Expected positive integer, found '{}'",
value.as_integer()
)));
}
Ok(())
}
fn integer_in_range(range: &Range<i128>, value: &Value) -> Result<(), Error> {
if !value.is_integer() || !range.contains(&value.as_integer()) {
Err(Error::validation(format!(
"Value '{}' does not fall within range '{:?}'",
value, range
)))
} else {
Ok(())
}
}
/// Generate and parse config from a prefix, and an array tuples containing the
/// name, description, default value, and an optional validator.
///
/// This function will parse any `SCREAMING_SNAKE_CASE` environment variables
/// that match the given prefix. It will then attempt to parse the [`Value`] and
/// run any validators which have been specified.
///
/// Once the config has been parsed, this function will emit `snake_case` cfg's
/// _without_ the prefix which can be used in the dependant crate. After that,
/// it will create a markdown table in the `OUT_DIR` under the name
/// `{prefix}_config_table.md` where prefix has also been converted to
/// `snake_case`. This can be included in crate documentation to outline the
/// available configuration options for the crate.
///
/// Passing a value of true for the `emit_md_tables` argument will create and
/// write markdown files of the available configuration and selected
/// configuration which can be included in documentation.
///
/// Unknown keys with the supplied prefix will cause this function to panic.
pub fn generate_config(
crate_name: &str,
config: &[(&str, &str, Value, Option<Validator>)],
emit_md_tables: bool,
) -> HashMap<String, Value> {
// Only rebuild if `build.rs` changed. Otherwise, Cargo will rebuild if any
// other file changed.
println!("cargo:rerun-if-changed=build.rs");
#[cfg(not(test))]
env_change_work_around();
let mut doc_table = String::from(DOC_TABLE_HEADER);
let mut selected_config = String::from(SELECTED_TABLE_HEADER);
// Ensure that the prefix is `SCREAMING_SNAKE_CASE`:
let prefix = format!("{}_CONFIG_", screaming_snake_case(crate_name));
// Build a lookup table for any provided validators; we must prefix the
// name of the config and transform it to SCREAMING_SNAKE_CASE so that
// it matches the keys in the hash table produced by `create_config`.
let config_validators = config
.iter()
.flat_map(|(name, _description, _default, validator)| {
if let Some(validator) = validator {
let name = format!("{prefix}{}", screaming_snake_case(name));
Some((name, validator))
} else {
None
}
})
.collect::<HashMap<_, _>>();
let mut configs = create_config(&prefix, config, &mut doc_table);
capture_from_env(&prefix, &mut configs);
for (name, value) in configs.iter() {
if let Some(validator) = config_validators.get(name) {
validator.validate(value).unwrap();
}
}
emit_configuration(&prefix, &configs, &mut selected_config);
if emit_md_tables {
let file_name = snake_case(crate_name);
write_config_tables(&file_name, doc_table, selected_config);
}
configs
}
// A work-around for https://github.com/rust-lang/cargo/issues/10358
// This can be removed when https://github.com/rust-lang/cargo/pull/14058 is merged.
// Unlikely to work on projects in workspaces
#[cfg(not(test))]
fn env_change_work_around() {
let mut out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
// We clean out_dir by removing all trailing directories, until it ends with
// target
while !out_dir.ends_with("target") {
if !out_dir.pop() {
return; // We ran out of directories...
}
}
out_dir.pop();
let dotcargo = out_dir.join(".cargo/");
if dotcargo.exists() {
if dotcargo.join("config.toml").exists() {
println!(
"cargo:rerun-if-changed={}",
dotcargo.join("config.toml").display()
);
}
if dotcargo.join("config").exists() {
println!(
"cargo:rerun-if-changed={}",
dotcargo.join("config").display()
);
}
}
}
fn create_config(
prefix: &str,
config: &[(&str, &str, Value, Option<Validator>)],
doc_table: &mut String,
) -> HashMap<String, Value> {
let mut configs = HashMap::new();
for (name, description, default, _validator) in config {
let name = format!("{prefix}{}", screaming_snake_case(name));
configs.insert(name.clone(), default.clone());
// Write documentation table line:
let default = default.to_string();
writeln!(doc_table, "|**{name}**|{description}|{default}|").unwrap();
// Rebuild if config environment variable changed:
println!("cargo:rerun-if-env-changed={name}");
}
configs
}
fn capture_from_env(prefix: &str, configs: &mut HashMap<String, Value>) {
let mut unknown = Vec::new();
let mut failed = Vec::new();
// Try and capture input from the environment:
for (var, value) in env::vars() {
if var.starts_with(prefix) {
let Some(cfg) = configs.get_mut(&var) else {
unknown.push(var);
continue;
};
if let Err(e) = cfg.parse_in_place(&value) {
failed.push(format!("{var}: {e}"));
}
}
}
if !failed.is_empty() {
panic!("Invalid configuration options detected: {:?}", failed);
}
if !unknown.is_empty() {
panic!("Unknown configuration options detected: {:?}", unknown);
}
}
fn emit_configuration(
prefix: &str,
configs: &HashMap<String, Value>,
selected_config: &mut String,
) {
for (name, value) in configs.iter() {
let cfg_name = snake_case(name.trim_start_matches(prefix));
println!("cargo:rustc-check-cfg=cfg({cfg_name})");
if let Value::Bool(true) = value {
println!("cargo:rustc-cfg={cfg_name}");
}
let value = value.to_string();
// Values that haven't been seen will be output here with the default value:
println!("cargo:rustc-env={}={}", name, value);
writeln!(selected_config, "|**{name}**|{value}|").unwrap();
}
}
fn write_config_tables(prefix: &str, doc_table: String, selected_config: String) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let out_file = out_dir
.join(format!("{prefix}_config_table.md"))
.display()
.to_string();
fs::write(out_file, doc_table).unwrap();
let out_file = out_dir
.join(format!("{prefix}_selected_config.md"))
.display()
.to_string();
fs::write(out_file, selected_config).unwrap();
}
fn snake_case(name: &str) -> String {
let mut name = name.replace("-", "_");
name.make_ascii_lowercase();
name
}
fn screaming_snake_case(name: &str) -> String {
let mut name = name.replace("-", "_");
name.make_ascii_uppercase();
name
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn value_number_formats() {
const INPUTS: &[&str] = &["0xAA", "0o252", "0b0000000010101010", "170"];
let mut v = Value::Integer(0);
for input in INPUTS {
v.parse_in_place(input).unwrap();
// no matter the input format, the output format should be decimal
assert_eq!(format!("{v}"), "170");
}
}
#[test]
fn value_bool_inputs() {
let mut v = Value::Bool(false);
v.parse_in_place("true").unwrap();
assert_eq!(format!("{v}"), "true");
v.parse_in_place("false").unwrap();
assert_eq!(format!("{v}"), "false");
}
#[test]
fn env_override() {
temp_env::with_vars(
[
("ESP_TEST_CONFIG_NUMBER", Some("0xaa")),
("ESP_TEST_CONFIG_NUMBER_SIGNED", Some("-999")),
("ESP_TEST_CONFIG_STRING", Some("Hello world!")),
("ESP_TEST_CONFIG_BOOL", Some("true")),
],
|| {
let configs = generate_config(
"esp-test",
&[
("number", "NA", Value::Integer(999), None),
("number_signed", "NA", Value::Integer(-777), None),
("string", "NA", Value::String("Demo".to_owned()), None),
("bool", "NA", Value::Bool(false), None),
("number_default", "NA", Value::Integer(999), None),
(
"string_default",
"NA",
Value::String("Demo".to_owned()),
None,
),
("bool_default", "NA", Value::Bool(false), None),
],
false,
);
// some values have changed
assert_eq!(
match configs.get("ESP_TEST_CONFIG_NUMBER").unwrap() {
Value::Integer(num) => *num,
_ => unreachable!(),
},
0xaa
);
assert_eq!(
match configs.get("ESP_TEST_CONFIG_NUMBER_SIGNED").unwrap() {
Value::Integer(num) => *num,
_ => unreachable!(),
},
-999
);
assert_eq!(
match configs.get("ESP_TEST_CONFIG_STRING").unwrap() {
Value::String(val) => val,
_ => unreachable!(),
},
"Hello world!"
);
assert_eq!(
match configs.get("ESP_TEST_CONFIG_BOOL").unwrap() {
Value::Bool(val) => *val,
_ => unreachable!(),
},
true
);
// the rest are the defaults
assert_eq!(
match configs.get("ESP_TEST_CONFIG_NUMBER_DEFAULT").unwrap() {
Value::Integer(num) => *num,
_ => unreachable!(),
},
999
);
assert_eq!(
match configs.get("ESP_TEST_CONFIG_STRING_DEFAULT").unwrap() {
Value::String(val) => val,
_ => unreachable!(),
},
"Demo"
);
assert_eq!(
match configs.get("ESP_TEST_CONFIG_BOOL_DEFAULT").unwrap() {
Value::Bool(val) => *val,
_ => unreachable!(),
},
false
);
},
)
}
#[test]
fn builtin_validation_passes() {
temp_env::with_vars(
[
("ESP_TEST_CONFIG_POSITIVE_NUMBER", Some("7")),
("ESP_TEST_CONFIG_NEGATIVE_NUMBER", Some("-1")),
("ESP_TEST_CONFIG_NON_NEGATIVE_NUMBER", Some("0")),
("ESP_TEST_CONFIG_RANGE", Some("9")),
],
|| {
generate_config(
"esp-test",
&[
(
"positive_number",
"NA",
Value::Integer(-1),
Some(Validator::PositiveInteger),
),
(
"negative_number",
"NA",
Value::Integer(1),
Some(Validator::NegativeInteger),
),
(
"non_negative_number",
"NA",
Value::Integer(-1),
Some(Validator::NonNegativeInteger),
),
(
"range",
"NA",
Value::Integer(0),
Some(Validator::IntegerInRange(5..10)),
),
],
false,
)
},
);
}
#[test]
fn custom_validation_passes() {
temp_env::with_vars([("ESP_TEST_CONFIG_NUMBER", Some("13"))], || {
generate_config(
"esp-test",
&[(
"number",
"NA",
Value::Integer(-1),
Some(Validator::Custom(Box::new(|value| {
let range = 10..20;
if !value.is_integer() || !range.contains(&value.as_integer()) {
Err(Error::validation("value does not fall within range"))
} else {
Ok(())
}
}))),
)],
false,
)
});
}
#[test]
#[should_panic]
fn builtin_validation_bails() {
temp_env::with_vars([("ESP_TEST_CONFIG_POSITIVE_NUMBER", Some("-99"))], || {
generate_config(
"esp-test",
&[(
"positive_number",
"NA",
Value::Integer(-1),
Some(Validator::PositiveInteger),
)],
false,
)
});
}
#[test]
#[should_panic]
fn custom_validation_bails() {
temp_env::with_vars([("ESP_TEST_CONFIG_NUMBER", Some("37"))], || {
generate_config(
"esp-test",
&[(
"number",
"NA",
Value::Integer(-1),
Some(Validator::Custom(Box::new(|value| {
let range = 10..20;
if !value.is_integer() || !range.contains(&value.as_integer()) {
Err(Error::validation("value does not fall within range"))
} else {
Ok(())
}
}))),
)],
false,
)
});
}
#[test]
#[should_panic]
fn env_unknown_bails() {
temp_env::with_vars(
[
("ESP_TEST_CONFIG_NUMBER", Some("0xaa")),
("ESP_TEST_CONFIG_RANDOM_VARIABLE", Some("")),
],
|| {
generate_config(
"esp-test",
&[("number", "NA", Value::Integer(999), None)],
false,
);
},
);
}
#[test]
#[should_panic]
fn env_invalid_values_bails() {
temp_env::with_vars([("ESP_TEST_CONFIG_NUMBER", Some("Hello world"))], || {
generate_config(
"esp-test",
&[("number", "NA", Value::Integer(999), None)],
false,
);
});
}
#[test]
fn env_unknown_prefix_is_ignored() {
temp_env::with_vars(
[("ESP_TEST_OTHER_CONFIG_NUMBER", Some("Hello world"))],
|| {
generate_config(
"esp-test",
&[("number", "NA", Value::Integer(999), None)],
false,
);
},
);
}
}

110
esp-config/src/lib.rs Normal file
View File

@ -0,0 +1,110 @@
#![doc = include_str!("../README.md")]
//! ## Feature Flags
#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
#![cfg_attr(not(feature = "build"), no_std)]
#![deny(missing_docs, rust_2018_idioms)]
#[cfg(feature = "build")]
mod generate;
#[cfg(feature = "build")]
pub use generate::{generate_config, Error, Validator, Value};
/// Parse the value of an environment variable as a [bool] at compile time.
#[macro_export]
macro_rules! esp_config_bool {
( $var:expr ) => {
match env!($var).as_bytes() {
b"true" => true,
b"false" => false,
_ => ::core::panic!("boolean value must be either 'true' or 'false'"),
}
};
}
// TODO: From 1.82 on, we can use `<$ty>::from_str_radix(env!($var), 10)`
/// Parse the value of an environment variable as an integer at compile time.
#[macro_export]
macro_rules! esp_config_int {
( $ty:ty, $var:expr ) => {
const {
const BYTES: &[u8] = env!($var).as_bytes();
$crate::esp_config_int_parse!($ty, BYTES)
}
};
}
/// Get the string value of an environment variable at compile time.
#[macro_export]
macro_rules! esp_config_str {
( $var:expr ) => {
env!($var)
};
}
/// Parse a string like "777" into an integer, which _can_ be used in a `const`
/// context
#[doc(hidden)] // To avoid confusion with `esp_config_int`, hide this in the docs
#[macro_export]
macro_rules! esp_config_int_parse {
( $ty:ty, $bytes:expr ) => {{
let mut bytes = $bytes;
let mut val: $ty = 0;
let mut sign_seen = false;
let mut is_negative = false;
while let [byte, rest @ ..] = bytes {
match *byte {
b'0'..=b'9' => {
val = val * 10 + (*byte - b'0') as $ty;
}
b'-' | b'+' if !sign_seen => {
is_negative = *byte == b'-';
sign_seen = true;
}
_ => ::core::panic!("invalid character encountered while parsing integer"),
}
bytes = rest;
}
if is_negative {
let original = val;
// Subtract the value twice to get a negative:
val -= original;
val -= original;
}
val
}};
}
#[cfg(test)]
mod test {
// We can only test success in the const context
const _: () = {
core::assert!(esp_config_int_parse!(i64, "-77777".as_bytes()) == -77777);
core::assert!(esp_config_int_parse!(isize, "-7777".as_bytes()) == -7777);
core::assert!(esp_config_int_parse!(i32, "-999".as_bytes()) == -999);
core::assert!(esp_config_int_parse!(i16, "-99".as_bytes()) == -99);
core::assert!(esp_config_int_parse!(i8, "-9".as_bytes()) == -9);
core::assert!(esp_config_int_parse!(u64, "77777".as_bytes()) == 77777);
core::assert!(esp_config_int_parse!(usize, "7777".as_bytes()) == 7777);
core::assert!(esp_config_int_parse!(u32, "999".as_bytes()) == 999);
core::assert!(esp_config_int_parse!(u16, "99".as_bytes()) == 99);
core::assert!(esp_config_int_parse!(u8, "9".as_bytes()) == 9);
};
#[test]
#[should_panic]
fn test_expect_positive() {
esp_config_int_parse!(u8, "-5".as_bytes());
}
#[test]
#[should_panic]
fn test_invalid_digit() {
esp_config_int_parse!(u32, "a".as_bytes());
}
}

View File

@ -0,0 +1 @@
avoid-breaking-exported-api = false

View File

@ -0,0 +1,74 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
### Changed
- Bump MSRV to 1.83 (#2615)
- Config: Crate prefixes and configuration keys are now separated by `_CONFIG_` (#2848)
### Fixed
### Removed
## 0.5.0 - 2024-11-20
### Added
- `ESP_HAL_EMBASSY_LOW_POWER_WAIT` configuration option. (#2329)
### Changed
- Reduce memory footprint by 4 bytes on multi-core MCUs.
- The time driver no longer uses cross-core critical sections. (#2559)
### Fixed
- Alarm interrupts are now handled on the core that allocated them. (For executors created on the second core after calling `esp_hal_embassy::init`) (#2451)
### Removed
## 0.4.0 - 2024-10-10
### Changed
- MSRV bump to 1.79 (#2156)
### Removed
- Removed the `clocks` parameter from `esp_hal_embassy::init`. (#1999)
## 0.3.0 - 2024-08-29
### Added
- This package now re-exports the `esp_hal_procmacros::main` macro (#1828)
### Changed
- Updated to latest release (`0.6.0`) for `embassy-executor` (#1942)
- Changed `init` to accept timers of multiple types (#1957, #2012)
### Fixed
- Fixed a bug where the timeout was huge whenever the timestamp at the time of scheduling was already in the past (#1875)
- Fixed interrupt executors looping endlessly when `integrated-timers` is used. (#1936)
## 0.2.0 - 2024-07-15
### Changed
- Removed the TIMG and SYSTIMER time drivers, replaced by a generic time driver taking `OneShotTimer<ErasedTimer>` (#1753)
## 0.1.0 - 2024-06-04
[Unreleased]: https://github.com/esp-rs/esp-hal/commits/main/esp-hal-embassy?since=2024-11-20

View File

@ -1,31 +1,38 @@
[package]
name = "esp-hal-embassy"
version = "0.1.0"
version = "0.5.0"
edition = "2021"
rust-version = "1.76.0"
rust-version = "1.83.0"
description = "Embassy support for esp-hal"
keywords = ["async", "embedded", "esp32", "espressif"]
categories = ["asynchronous", "embedded", "hardware-support", "no-std"]
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
[package.metadata.docs.rs]
default-target = "riscv32imac-unknown-none-elf"
features = ["esp32c6", "time-timg0"]
features = ["esp32c6"]
[dependencies]
critical-section = "1.1.2"
critical-section = "1.2.0"
defmt = { version = "0.3.8", optional = true }
document-features = "0.2.8"
embassy-executor = "0.5.0"
embassy-time-driver = "0.1.0"
esp-hal = { version = "0.18.0", path = "../esp-hal" }
portable-atomic = "1.6.0"
document-features = "0.2.10"
embassy-executor = { version = "0.6.3", optional = true }
embassy-time-driver = { version = "0.1.0", features = [ "tick-hz-1_000_000" ] }
esp-hal = { version = "0.22.0", path = "../esp-hal" }
log = { version = "0.4.22", optional = true }
macros = { version = "0.15.0", features = ["embassy"], package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
portable-atomic = "1.9.0"
static_cell = "2.1.0"
[build-dependencies]
cfg-if = "1.0.0"
esp-build = { version = "0.1.0", path = "../esp-build" }
esp-metadata = { version = "0.1.1", path = "../esp-metadata" }
esp-config = { version = "0.2.0", path = "../esp-config", features = ["build"] }
esp-metadata = { version = "0.4.0", path = "../esp-metadata" }
[features]
default = ["executors"]
esp32 = ["esp-hal/esp32"]
esp32c2 = ["esp-hal/esp32c2"]
esp32c3 = ["esp-hal/esp32c3"]
@ -35,14 +42,13 @@ esp32s2 = ["esp-hal/esp32s2"]
esp32s3 = ["esp-hal/esp32s3"]
## Implement `defmt::Format` on certain types.
defmt = ["dep:defmt", "embassy-executor/defmt", "esp-hal/defmt"]
defmt = ["dep:defmt", "embassy-executor?/defmt", "esp-hal/defmt"]
## Enable logging via the log crate
log = ["dep:log"]
## Provide `Executor` and `InterruptExecutor`
executors = ["dep:embassy-executor", "esp-hal/__esp_hal_embassy"]
## Use the executor-integrated `embassy-time` timer queue.
integrated-timers = ["embassy-executor/integrated-timers"]
integrated-timers = ["embassy-executor?/integrated-timers"]
#! ### Time Driver Feature Flags
## SYSTIMER (16MHz)
time-systimer-16mhz = ["embassy-time-driver/tick-hz-16_000_000"]
## SYSTIMER (80MHz)
time-systimer-80mhz = ["embassy-time-driver/tick-hz-80_000_000"]
## TIMG0 (1MHz)
time-timg0 = ["embassy-time-driver/tick-hz-1_000_000"]
[lints.rust]
unexpected_cfgs = "allow"

View File

@ -0,0 +1,63 @@
# Migration Guide from 0.3.x to v0.4.x
## Initialization
You no longer have to set up clocks and pass them to `esp_hal_embassy::init`.
```diff
use esp_hal::{
- clock::ClockControl,
- peripherals::Peripherals,
prelude::*,
- system::SystemControl,
};
#[esp_hal_embassy::main]
async fn main(_spawner: Spawner) -> ! {
- let peripherals = Peripherals::take();
- let system = SystemControl::new(peripherals.SYSTEM);
- let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
+ let peripherals = esp_hal::init(esp_hal::Config::default());
let timg0 = TimerGroup::new(peripherals.TIMG0);
- esp_hal_embassy::init(&clocks, timg0);
+ esp_hal_embassy::init(timg0.timer0);
// ...
}
```
You have to specify a timer instance (that may be a `TimerGroup` timer unit
or a `SystemTimer` alarm) or an array of `AnyTimer`s when calling `init`.
An example of how you can set multiple timers (for example when using
multiple executors):
```rust
use esp_hal::{
prelude::*,
timer::{
AnyTimer,
systimer::SystemTimer
}
};
#[esp_hal_embassy::main]
async fn main(_spawner: Spawner) -> ! {
let peripherals = esp_hal::init(esp_hal::Config::default());
let timg0 = TimerGroup::new(peripherals.TIMG0);
let timer0: AnyTimer = timg0.timer0.into();
let timer1: AnyTimer = timg0.timer1.into();
// You can use either a TimerGroup timer, a SystemTimer alarm,
// or you can mix and match them as well.
let systimer = SystemTimer::new(peripherals.SYSTIMER).split::<Target>();
let timer2: AnyTimer = systimer.alarm0;
esp_hal_embassy::init([timer0, timer1, timer2]);
// ...
}
```
Note that you only have to convert into `AnyTimer` if you want to use multiple timers.

View File

@ -0,0 +1,3 @@
# Migration Guide from 0.4.x to v0.5.x
You don't have to make changes to your code to update esp-hal-embassy.

View File

@ -0,0 +1,15 @@
# Migration Guide from 0.5.x to v0.6.x
## Crate configuration changes
To prevent ambiguity between configurations, we had to change the naming format of configuration
keys. Before, we used `{prefix}_{key}`, which meant that esp-hal and esp-hal-* configuration keys
were impossible to tell apart. To fix this issue, we are changing the separator from one underscore
character to `_CONFIG_`. This also means that users will have to change their `config.toml`
configurations to match the new format.
```diff
[env]
-ESP_HAL_EMBASSY_LOW_POWER_WAIT="false"
+ESP_HAL_EMBASSY_CONFIG_LOW_POWER_WAIT="false"
```

View File

@ -2,12 +2,14 @@
[![Crates.io](https://img.shields.io/crates/v/esp-hal-embassy?labelColor=1C2C2E&color=C96329&logo=Rust&style=flat-square)](https://crates.io/crates/esp-hal-embassy)
[![docs.rs](https://img.shields.io/docsrs/esp-hal-embassy?labelColor=1C2C2E&color=C96329&logo=rust&style=flat-square)](https://docs.rs/esp-hal-embassy)
![MSRV](https://img.shields.io/badge/MSRV-1.76-blue?labelColor=1C2C2E&style=flat-square)
![MSRV](https://img.shields.io/badge/MSRV-1.83-blue?labelColor=1C2C2E&style=flat-square)
![Crates.io](https://img.shields.io/crates/l/esp-hal-embassy?labelColor=1C2C2E&style=flat-square)
[![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&labelColor=1C2C2E&color=BEC5C9&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org)
[Embassy] support for `esp-hal`.
Note that this crate currently requires you to enable the `unstable` feature on `esp-hal`.
[embassy]: https://github.com/embassy-rs/embassy
## [Documentation]
@ -16,7 +18,7 @@
## Minimum Supported Rust Version (MSRV)
This crate is guaranteed to compile on stable Rust 1.76 and up. It _might_
This crate is guaranteed to compile on stable Rust 1.83 and up. It _might_
compile with older versions but that may change in any new patch release.
## License

View File

@ -1,6 +1,7 @@
use std::{error::Error, str::FromStr};
use esp_build::assert_unique_used_features;
use esp_config::{generate_config, Value};
use esp_metadata::{Chip, Config};
fn main() -> Result<(), Box<dyn Error>> {
@ -10,18 +11,6 @@ fn main() -> Result<(), Box<dyn Error>> {
"esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3"
);
// If the `embassy` feature is enabled, ensure that a time driver implementation
// is available:
cfg_if::cfg_if! {
if #[cfg(feature = "esp32")] {
assert_unique_used_features!("time-timg0");
} else if #[cfg(feature = "esp32s2")] {
assert_unique_used_features!("time-systimer-80mhz", "time-timg0");
} else {
assert_unique_used_features!("time-systimer-16mhz", "time-timg0");
}
}
// NOTE: update when adding new device support!
// Determine the name of the configured device:
let device_name = if cfg!(feature = "esp32") {
@ -49,5 +38,17 @@ fn main() -> Result<(), Box<dyn Error>> {
// Define all necessary configuration symbols for the configured device:
config.define_symbols();
// emit config
generate_config(
"esp_hal_embassy",
&[(
"low-power-wait",
"Enables the lower-power wait if no tasks are ready to run on the thread-mode executor. This allows the MCU to use less power if the workload allows. Recommended for battery-powered systems. May impact analog performance.",
Value::Bool(true),
None
)],
true,
);
Ok(())
}

View File

@ -4,18 +4,13 @@ use core::{cell::UnsafeCell, mem::MaybeUninit};
use embassy_executor::{raw, SendSpawner};
use esp_hal::{
get_core,
interrupt::{self, InterruptHandler},
system::SoftwareInterrupt,
interrupt::{self, software::SoftwareInterrupt, InterruptHandler},
Cpu,
};
use portable_atomic::{AtomicUsize, Ordering};
static mut EXECUTORS: [CallbackContext; 4] = [
CallbackContext::new(),
CallbackContext::new(),
CallbackContext::new(),
CallbackContext::new(),
];
const COUNT: usize = 3 + cfg!(not(multi_core)) as usize;
static mut EXECUTORS: [CallbackContext; COUNT] = [const { CallbackContext::new() }; COUNT];
/// Interrupt mode executor.
///
@ -47,13 +42,11 @@ impl CallbackContext {
}
fn set(&self, executor: *mut raw::Executor) {
unsafe {
self.raw_executor.get().write(executor);
}
unsafe { self.raw_executor.get().write(executor) };
}
}
fn handle_interrupt<const NUM: u8>() {
extern "C" fn handle_interrupt<const NUM: u8>() {
let swi = unsafe { SoftwareInterrupt::<NUM>::steal() };
swi.reset();
@ -63,22 +56,6 @@ fn handle_interrupt<const NUM: u8>() {
}
}
extern "C" fn swi_handler0() {
handle_interrupt::<0>();
}
extern "C" fn swi_handler1() {
handle_interrupt::<1>();
}
extern "C" fn swi_handler2() {
handle_interrupt::<2>();
}
extern "C" fn swi_handler3() {
handle_interrupt::<3>();
}
impl<const SWI: u8> InterruptExecutor<SWI> {
/// Create a new `InterruptExecutor`.
/// This takes the software interrupt to be used internally.
@ -97,18 +74,20 @@ impl<const SWI: u8> InterruptExecutor<SWI> {
/// The executor keeps running in the background through the interrupt.
///
/// This returns a [`SendSpawner`] you can use to spawn tasks on it. A
/// [`SendSpawner`] is returned instead of a [`Spawner`] because the
/// [`SendSpawner`] is returned instead of a
/// [`Spawner`](embassy_executor::Spawner) because the
/// executor effectively runs in a different "thread" (the interrupt),
/// so spawning tasks on it is effectively sending them.
///
/// To obtain a [`Spawner`] for this executor, use
/// [`Spawner::for_current_executor()`] from a task running in it.
/// To obtain a [`Spawner`](embassy_executor::Spawner) for this executor,
/// use [`Spawner::for_current_executor`](embassy_executor::Spawner::for_current_executor)
/// from a task running in it.
pub fn start(&'static mut self, priority: interrupt::Priority) -> SendSpawner {
if self
.core
.compare_exchange(
usize::MAX,
get_core() as usize,
Cpu::current() as usize,
Ordering::Acquire,
Ordering::Relaxed,
)
@ -120,16 +99,17 @@ impl<const SWI: u8> InterruptExecutor<SWI> {
unsafe {
(*self.executor.get())
.as_mut_ptr()
.write(raw::Executor::new(SWI as *mut ()));
.write(raw::Executor::new((SWI as usize) as *mut ()));
EXECUTORS[SWI as usize].set((*self.executor.get()).as_mut_ptr());
}
let swi_handler = match SWI {
0 => swi_handler0,
1 => swi_handler1,
2 => swi_handler2,
3 => swi_handler3,
0 => handle_interrupt::<0>,
1 => handle_interrupt::<1>,
2 => handle_interrupt::<2>,
#[cfg(not(multi_core))]
3 => handle_interrupt::<3>,
_ => unreachable!(),
};

View File

@ -5,21 +5,20 @@ mod thread;
#[export_name = "__pender"]
fn __pender(context: *mut ()) {
use esp_hal::system::SoftwareInterrupt;
use esp_hal::interrupt::software::SoftwareInterrupt;
let context = (context as usize).to_le_bytes();
match context[0] {
match context as usize {
// For interrupt executors, the context value is the
// software interrupt number
0 => unsafe { SoftwareInterrupt::<0>::steal().raise() },
1 => unsafe { SoftwareInterrupt::<1>::steal().raise() },
2 => unsafe { SoftwareInterrupt::<2>::steal().raise() },
#[cfg(not(multi_core))]
3 => unsafe { SoftwareInterrupt::<3>::steal().raise() },
other => {
assert_eq!(other, THREAD_MODE_CONTEXT);
// THREAD_MODE_CONTEXT id is reserved for thread mode executors
thread::pend_thread_mode(context[1] as usize)
}
// THREAD_MODE_CONTEXT + core ID
16 => thread::pend_thread_mode(0),
#[cfg(multi_core)]
17 => thread::pend_thread_mode(1),
_ => unreachable!(),
}
}

View File

@ -3,63 +3,56 @@
use core::marker::PhantomData;
use embassy_executor::{raw, Spawner};
use esp_hal::get_core;
use esp_hal::Cpu;
#[cfg(multi_core)]
use esp_hal::macros::handler;
#[cfg(multi_core)]
use esp_hal::peripherals::SYSTEM;
use esp_hal::{interrupt::software::SoftwareInterrupt, macros::handler};
#[cfg(low_power_wait)]
use portable_atomic::{AtomicBool, Ordering};
pub(crate) const THREAD_MODE_CONTEXT: u8 = 16;
pub(crate) const THREAD_MODE_CONTEXT: usize = 16;
/// global atomic used to keep track of whether there is work to do since sev()
/// is not available on either Xtensa or RISC-V
#[cfg(not(multi_core))]
static SIGNAL_WORK_THREAD_MODE: [AtomicBool; 1] = [AtomicBool::new(false)];
#[cfg(multi_core)]
static SIGNAL_WORK_THREAD_MODE: [AtomicBool; 2] = [AtomicBool::new(false), AtomicBool::new(false)];
static SIGNAL_WORK_THREAD_MODE: [AtomicBool; Cpu::COUNT] =
[const { AtomicBool::new(false) }; Cpu::COUNT];
#[cfg(multi_core)]
#[cfg(all(multi_core, low_power_wait))]
#[handler]
fn software3_interrupt() {
// This interrupt is fired when the thread-mode executor's core needs to be
// woken. It doesn't matter which core handles this interrupt first, the
// point is just to wake up the core that is currently executing
// `waiti`.
let system = unsafe { &*SYSTEM::PTR };
system
.cpu_intr_from_cpu_3()
.write(|w| w.cpu_intr_from_cpu_3().bit(false));
unsafe { SoftwareInterrupt::<3>::steal().reset() };
}
pub(crate) fn pend_thread_mode(core: usize) {
// Signal that there is work to be done.
SIGNAL_WORK_THREAD_MODE[core].store(true, Ordering::SeqCst);
pub(crate) fn pend_thread_mode(_core: usize) {
#[cfg(low_power_wait)]
{
// Signal that there is work to be done.
SIGNAL_WORK_THREAD_MODE[_core].store(true, Ordering::Relaxed);
// If we are pending a task on the current core, we're done. Otherwise, we
// need to make sure the other core wakes up.
#[cfg(multi_core)]
if core != get_core() as usize {
// We need to clear the interrupt from software. We don't actually
// need it to trigger and run the interrupt handler, we just need to
// kick waiti to return.
let system = unsafe { &*SYSTEM::PTR };
system
.cpu_intr_from_cpu_3()
.write(|w| w.cpu_intr_from_cpu_3().bit(true));
// If we are pending a task on the current core, we're done. Otherwise, we
// need to make sure the other core wakes up.
#[cfg(multi_core)]
if _core != Cpu::current() as usize {
// We need to clear the interrupt from software. We don't actually
// need it to trigger and run the interrupt handler, we just need to
// kick waiti to return.
unsafe { SoftwareInterrupt::<3>::steal().raise() };
}
}
}
/// A thread aware Executor
/// Thread mode executor.
///
/// This is the simplest and most common kind of executor. It runs on thread
/// mode (at the lowest priority level).
#[cfg_attr(multi_core, doc = "")]
#[cfg_attr(
multi_core,
doc = r#"
This executor is capable of waking an
executor running on another core if work
needs to be completed there for a task to
progress on this core.
"#
doc = "This executor is safe to use on multiple cores. You need to
create one instance per core. The executors don't steal tasks from each other."
)]
pub struct Executor {
inner: raw::Executor,
@ -71,24 +64,17 @@ impl Executor {
#[cfg_attr(
multi_core,
doc = r#"
This will use software-interrupt 3 which isn't
available for anything else to wake the other core(s).
"#
This will use software-interrupt 3 which isn't available for anything else to wake the other core(s)."#
)]
pub fn new() -> Self {
#[cfg(multi_core)]
#[cfg(all(multi_core, low_power_wait))]
unsafe {
esp_hal::system::SoftwareInterrupt::<3>::steal()
.set_interrupt_handler(software3_interrupt)
SoftwareInterrupt::<3>::steal().set_interrupt_handler(software3_interrupt);
}
Self {
inner: raw::Executor::new(usize::from_le_bytes([
THREAD_MODE_CONTEXT,
get_core() as u8,
0,
0,
]) as *mut ()),
inner: raw::Executor::new((THREAD_MODE_CONTEXT + Cpu::current() as usize) as *mut ()),
not_send: PhantomData,
}
}
@ -108,7 +94,7 @@ impl Executor {
/// you mutable access. There's a few ways to do this:
///
/// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
/// - a `static mut` (unsafe)
/// - a `static mut` (unsafe, not recommended)
/// - a local variable in a function you know never returns (like `fn main()
/// -> !`), upgrading its lifetime with `transmute`. (unsafe)
///
@ -116,20 +102,19 @@ impl Executor {
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
init(self.inner.spawner());
let cpu = get_core() as usize;
#[cfg(low_power_wait)]
let cpu = Cpu::current() as usize;
loop {
unsafe {
self.inner.poll();
unsafe { self.inner.poll() };
Self::wait_impl(cpu);
}
#[cfg(low_power_wait)]
Self::wait_impl(cpu);
}
}
#[doc(hidden)]
#[cfg(xtensa)]
pub fn wait_impl(cpu: usize) {
#[cfg(all(xtensa, low_power_wait))]
fn wait_impl(cpu: usize) {
// Manual critical section implementation that only masks interrupts handlers.
// We must not acquire the cross-core on dual-core systems because that would
// prevent the other core from doing useful work while this core is sleeping.
@ -138,9 +123,8 @@ impl Executor {
// we do not care about race conditions between the load and store operations,
// interrupts will only set this value to true.
if SIGNAL_WORK_THREAD_MODE[cpu].load(Ordering::SeqCst) {
SIGNAL_WORK_THREAD_MODE[cpu].store(false, Ordering::SeqCst);
// Acquire makes no sense but at this time it's slightly faster than Relaxed.
if SIGNAL_WORK_THREAD_MODE[cpu].load(Ordering::Acquire) {
// if there is work to do, exit critical section and loop back to polling
unsafe {
core::arch::asm!(
@ -150,33 +134,38 @@ impl Executor {
);
}
} else {
// waiti sets the PS.INTLEVEL when slipping into sleep
// because critical sections in Xtensa are implemented via increasing
// PS.INTLEVEL the critical section ends here
// take care not add code after `waiti` if it needs to be inside the CS
unsafe { core::arch::asm!("waiti 0") }; // critical section ends
// here
// `waiti` sets the `PS.INTLEVEL` when slipping into sleep because critical
// sections in Xtensa are implemented via increasing `PS.INTLEVEL`.
// The critical section ends here. Take care not add code after
// `waiti` if it needs to be inside the CS.
// Do not lower INTLEVEL below the current value.
match token & 0x0F {
0 => unsafe { core::arch::asm!("waiti 0") },
1 => unsafe { core::arch::asm!("waiti 1") },
2 => unsafe { core::arch::asm!("waiti 2") },
3 => unsafe { core::arch::asm!("waiti 3") },
4 => unsafe { core::arch::asm!("waiti 4") },
_ => unsafe { core::arch::asm!("waiti 5") },
}
}
// If this races and some waker sets the signal, we'll reset it, but still poll.
SIGNAL_WORK_THREAD_MODE[cpu].store(false, Ordering::Relaxed);
}
#[doc(hidden)]
#[cfg(riscv)]
pub fn wait_impl(cpu: usize) {
#[cfg(all(riscv, low_power_wait))]
fn wait_impl(cpu: usize) {
// we do not care about race conditions between the load and store operations,
// interrupts will only set this value to true.
critical_section::with(|_| {
// if there is work to do, loop back to polling
// TODO can we relax this?
if SIGNAL_WORK_THREAD_MODE[cpu].load(Ordering::SeqCst) {
SIGNAL_WORK_THREAD_MODE[cpu].store(false, Ordering::SeqCst);
}
// if not, wait for interrupt
else {
if !SIGNAL_WORK_THREAD_MODE[cpu].load(Ordering::Relaxed) {
// if not, wait for interrupt
unsafe { core::arch::asm!("wfi") };
}
});
// if an interrupt occurred while waiting, it will be serviced
// here
// if an interrupt occurred while waiting, it will be serviced here
// If this races and some waker sets the signal, we'll reset it, but still poll.
SIGNAL_WORK_THREAD_MODE[cpu].store(false, Ordering::Relaxed);
}
}

View File

@ -4,6 +4,9 @@
//! systems. This package provides support for building applications using
//! Embassy with [esp-hal].
//!
//! Note that this crate currently requires you to enable the `unstable` feature
//! on `esp-hal`.
//!
//! [esp-hal]: https://github.com/esp-rs/esp-hal
//! [embassy]: https://github.com/embassy-rs/embassy
//!
@ -19,7 +22,7 @@
//! traditional RTOS. More information can be found in the [Embassy
//! documentation].
//!
//! [embassy documentation]: https://embassy.dev/book/dev/runtime.html
//! [embassy documentation]: https://embassy.dev/book/
//!
//! ## Initialization
//!
@ -36,67 +39,124 @@
// MUST be the first module
mod fmt;
use core::cell::Cell;
use embassy_time_driver::{AlarmHandle, Driver};
use esp_hal::clock::Clocks;
#[cfg(not(feature = "esp32"))]
use esp_hal::timer::systimer::Alarm;
use esp_hal::timer::{timg::Timer as TimgTimer, AnyTimer};
pub use macros::main;
#[cfg(feature = "executors")]
pub use self::executor::{Executor, InterruptExecutor};
use self::time_driver::{EmbassyTimer, TimerType};
use self::time_driver::{EmbassyTimer, Timer};
#[cfg(feature = "executors")]
mod executor;
mod time_driver;
/// Initialize embassy
pub fn init(clocks: &Clocks, time_driver: TimerType) {
EmbassyTimer::init(clocks, time_driver)
macro_rules! mk_static {
($t:ty,$val:expr) => {{
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
#[deny(unused_attributes)]
let x = STATIC_CELL.uninit().write(($val));
x
}};
}
#[allow(clippy::type_complexity)]
pub(crate) struct AlarmState {
pub callback: Cell<Option<(fn(*mut ()), *mut ())>>,
pub allocated: Cell<bool>,
/// A trait to allow better UX for initializing the timers.
///
/// This trait is meant to be used only for the `init` function.
/// Calling `timers()` multiple times may panic.
pub trait TimerCollection {
/// Returns the timers as a slice.
fn timers(self) -> &'static mut [Timer];
}
unsafe impl Send for AlarmState {}
/// Helper trait to reduce boilerplate.
///
/// We can't blanket-implement for `Into<AnyTimer>` because of possible
/// conflicting implementations.
trait IntoAnyTimer: Into<AnyTimer> {}
impl AlarmState {
pub const fn new() -> Self {
Self {
callback: Cell::new(None),
allocated: Cell::new(false),
}
impl IntoAnyTimer for AnyTimer {}
impl IntoAnyTimer for TimgTimer where Self: Into<AnyTimer> {}
#[cfg(not(feature = "esp32"))]
impl IntoAnyTimer for Alarm where Self: Into<AnyTimer> {}
impl<T> TimerCollection for T
where
T: IntoAnyTimer,
{
fn timers(self) -> &'static mut [Timer] {
Timer::new(self.into()).timers()
}
}
impl Driver for EmbassyTimer {
fn now(&self) -> u64 {
EmbassyTimer::now()
impl TimerCollection for Timer {
fn timers(self) -> &'static mut [Timer] {
let timers = mk_static!([Timer; 1], [self]);
timers.timers()
}
}
unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
critical_section::with(|cs| {
for (i, alarm) in self.alarms.borrow(cs).iter().enumerate() {
if !alarm.allocated.get() {
// set alarm so it is not overwritten
alarm.allocated.set(true);
self.on_alarm_allocated(i);
return Some(AlarmHandle::new(i as u8));
}
impl TimerCollection for &'static mut [Timer] {
fn timers(self) -> &'static mut [Timer] {
self
}
}
impl<const N: usize> TimerCollection for &'static mut [Timer; N] {
fn timers(self) -> &'static mut [Timer] {
self.as_mut()
}
}
macro_rules! impl_array {
($n:literal) => {
impl<T> TimerCollection for [T; $n]
where
T: IntoAnyTimer,
{
fn timers(self) -> &'static mut [Timer] {
mk_static!([Timer; $n], self.map(|t| Timer::new(t.into())))
}
None
})
}
fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
let n = alarm.id() as usize;
critical_section::with(|cs| {
let alarm = &self.alarms.borrow(cs)[n];
alarm.callback.set(Some((callback, ctx)));
})
}
fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool {
self.set_alarm(alarm, timestamp)
}
}
};
}
impl_array!(2);
impl_array!(3);
impl_array!(4);
/// Initialize embassy.
///
/// Call this as soon as possible, before the first timer-related operation.
///
/// The time driver can be one of a number of different options:
///
/// - A timg `Timer` instance
/// - A systimer `Alarm` instance
/// - An `AnyTimer` instance
/// - A `OneShotTimer` instance
/// - A mutable static slice of `OneShotTimer` instances
/// - A mutable static array of `OneShotTimer` instances
/// - A 2, 3, 4 element array of `AnyTimer` instances
///
/// Note that if you use the `integrated-timers` feature,
/// you need to pass as many timers as you start executors.
///
/// # Examples
///
/// ```rust, no_run
#[doc = esp_hal::before_snippet!()]
/// use esp_hal::timer::timg::TimerGroup;
///
/// let timg0 = TimerGroup::new(peripherals.TIMG0);
/// esp_hal_embassy::init(timg0.timer0);
///
/// // ... now you can spawn embassy tasks or use `Timer::after` etc.
/// # }
/// ```
pub fn init(time_driver: impl TimerCollection) {
EmbassyTimer::init(time_driver.timers())
}

View File

@ -0,0 +1,253 @@
use core::cell::Cell;
use embassy_time_driver::{AlarmHandle, Driver};
use esp_hal::{
interrupt::{InterruptHandler, Priority},
sync::Locked,
time::{now, ExtU64},
timer::OneShotTimer,
Blocking,
};
pub type Timer = OneShotTimer<'static, Blocking>;
enum AlarmState {
Created(extern "C" fn()),
Allocated(extern "C" fn()),
Initialized(&'static mut Timer),
}
impl AlarmState {
fn initialize(timer: &'static mut Timer, interrupt_handler: extern "C" fn()) -> AlarmState {
// If the driver is initialized, bind the interrupt handler to the
// timer. This ensures that alarms allocated after init are correctly
// bound to the core that created the executor.
timer.set_interrupt_handler(InterruptHandler::new(interrupt_handler, Priority::max()));
timer.enable_interrupt(true);
AlarmState::Initialized(timer)
}
}
struct AlarmInner {
pub callback: Cell<(*const (), *mut ())>,
pub state: AlarmState,
}
struct Alarm {
pub inner: Locked<AlarmInner>,
}
unsafe impl Send for Alarm {}
impl Alarm {
pub const fn new(handler: extern "C" fn()) -> Self {
Self {
inner: Locked::new(AlarmInner {
callback: Cell::new((core::ptr::null(), core::ptr::null_mut())),
state: AlarmState::Created(handler),
}),
}
}
}
pub(super) struct EmbassyTimer {
alarms: [Alarm; MAX_SUPPORTED_ALARM_COUNT],
available_timers: Locked<Option<&'static mut [Timer]>>,
}
/// Repeats the `Alarm::new` constructor for each alarm, creating an interrupt
/// handler for each of them.
macro_rules! alarms {
($($idx:literal),*) => {
[$(
Alarm::new({
// Not #[handler] so we don't have to store the priority - which is constant.
extern "C" fn handler() {
DRIVER.on_interrupt($idx);
}
handler
})
),*]
};
}
const MAX_SUPPORTED_ALARM_COUNT: usize = 7;
embassy_time_driver::time_driver_impl!(static DRIVER: EmbassyTimer = EmbassyTimer {
alarms: alarms!(0, 1, 2, 3, 4, 5, 6),
available_timers: Locked::new(None),
});
impl EmbassyTimer {
pub(super) fn init(mut timers: &'static mut [Timer]) {
assert!(
timers.len() <= MAX_SUPPORTED_ALARM_COUNT,
"Maximum {} timers can be used.",
MAX_SUPPORTED_ALARM_COUNT
);
// Reset timers
timers.iter_mut().for_each(|timer| {
timer.enable_interrupt(false);
timer.stop();
});
// Initialize already allocated timers
for alarm in DRIVER.alarms.iter() {
timers = alarm.inner.with(move |alarm| {
if let AlarmState::Allocated(interrupt_handler) = alarm.state {
// Pluck off a timer
let Some((timer, remaining_timers)) = timers.split_first_mut() else {
not_enough_timers();
};
alarm.state = AlarmState::initialize(timer, interrupt_handler);
remaining_timers
} else {
timers
}
});
}
// Store the available timers
DRIVER
.available_timers
.with(|available_timers| *available_timers = Some(timers));
}
fn on_interrupt(&self, id: usize) {
let (cb, ctx) = self.alarms[id].inner.with(|alarm| {
if let AlarmState::Initialized(timer) = &mut alarm.state {
timer.clear_interrupt();
alarm.callback.get()
} else {
unsafe {
// SAFETY: `on_interrupt` is registered right when the alarm is initialized.
core::hint::unreachable_unchecked()
}
}
});
let cb: fn(*mut ()) = unsafe {
// Safety:
// - we can ignore the possibility of `f` being unset (null) because of the
// safety contract of `allocate_alarm`.
// - other than that we only store valid function pointers into alarm.callback
core::mem::transmute(cb)
};
cb(ctx);
}
/// Returns `true` if the timer was armed, `false` if the timestamp is in
/// the past.
fn arm(timer: &mut Timer, timestamp: u64) -> bool {
let now = now().duration_since_epoch();
let ts = timestamp.micros();
if ts > now {
let timeout = ts - now;
unwrap!(timer.schedule(timeout));
true
} else {
// If the timestamp is past, we return `false` to ask embassy to poll again
// immediately.
timer.stop();
false
}
}
}
impl Driver for EmbassyTimer {
fn now(&self) -> u64 {
now().ticks()
}
unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
for (i, alarm) in self.alarms.iter().enumerate() {
let handle = alarm.inner.with(|alarm| {
let AlarmState::Created(interrupt_handler) = alarm.state else {
return None;
};
let timer = self.available_timers.with(|available_timers| {
// `allocate_alarm` may be called before `esp_hal_embassy::init()`. If
// `timers` is `None`, we return `None` to signal that the alarm cannot be
// initialized yet. These alarms will be initialized when `init` is called.
if let Some(timers) = available_timers.take() {
// If the driver is initialized, we can allocate a timer.
// If this fails, we can't do anything about it.
let Some((timer, rest)) = timers.split_first_mut() else {
not_enough_timers();
};
*available_timers = Some(rest);
Some(timer)
} else {
None
}
});
alarm.state = match timer {
Some(timer) => AlarmState::initialize(timer, interrupt_handler),
None => {
// No timers are available yet, mark the alarm as allocated.
AlarmState::Allocated(interrupt_handler)
}
};
Some(AlarmHandle::new(i as u8))
});
if handle.is_some() {
return handle;
}
}
None
}
fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
let n = alarm.id() as usize;
self.alarms[n].inner.with(|alarm| {
alarm.callback.set((callback as *const (), ctx));
})
}
fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool {
let alarm = &self.alarms[alarm.id() as usize];
// If `embassy-executor/integrated-timers` is enabled and there are no pending
// timers, embassy still calls `set_alarm` with `u64::MAX`. By returning
// `true` we signal that no re-polling is necessary.
if timestamp == u64::MAX {
return true;
}
// The hardware fires the alarm even if timestamp is lower than the current
// time. In this case the interrupt handler will pend a wake-up when we exit the
// critical section.
//
// This is correct behavior. See https://docs.rs/embassy-time-driver/0.1.0/embassy_time_driver/trait.Driver.html#tymethod.set_alarm
// (... the driver should return true and arrange to call the alarm callback as
// soon as possible, but not synchronously.)
alarm.inner.with(|alarm| {
if let AlarmState::Initialized(timer) = &mut alarm.state {
Self::arm(timer, timestamp)
} else {
panic!("set_alarm called before esp_hal_embassy::init()")
}
})
}
}
#[cold]
#[track_caller]
fn not_enough_timers() -> ! {
// This is wrapped in a separate function because rustfmt does not like
// extremely long strings. Also, if log is used, this avoids storing the string
// twice.
panic!("There are not enough timers to allocate a new alarm. Call esp_hal_embassy::init() with the correct number of timers, or consider using one of the embassy-timer/generic-queue-X features.");
}

View File

@ -1,9 +0,0 @@
#[cfg(any(feature = "time-systimer-16mhz", feature = "time-systimer-80mhz"))]
pub use self::systimer::*;
#[cfg(feature = "time-timg0")]
pub use self::timg::*;
#[cfg(any(feature = "time-systimer-16mhz", feature = "time-systimer-80mhz"))]
mod systimer;
#[cfg(feature = "time-timg0")]
mod timg;

View File

@ -1,135 +0,0 @@
use critical_section::{CriticalSection, Mutex};
use embassy_time_driver::AlarmHandle;
use esp_hal::{
clock::Clocks,
interrupt,
peripherals::Interrupt,
prelude::*,
timer::systimer::{Alarm, SystemTimer, Target},
Async,
};
use crate::AlarmState;
pub const ALARM_COUNT: usize = 3;
pub type TimerType = SystemTimer<'static, Async>;
pub struct EmbassyTimer {
pub(crate) alarms: Mutex<[AlarmState; ALARM_COUNT]>,
pub(crate) alarm0: Alarm<Target, Async, 0>,
pub(crate) alarm1: Alarm<Target, Async, 1>,
pub(crate) alarm2: Alarm<Target, Async, 2>,
}
#[allow(clippy::declare_interior_mutable_const)]
const ALARM_STATE_NONE: AlarmState = AlarmState::new();
embassy_time_driver::time_driver_impl!(static DRIVER: EmbassyTimer = EmbassyTimer {
alarms: Mutex::new([ALARM_STATE_NONE; ALARM_COUNT]),
alarm0: unsafe { Alarm::<_, Async, 0>::conjure() },
alarm1: unsafe { Alarm::<_, Async, 1>::conjure() },
alarm2: unsafe { Alarm::<_, Async, 2>::conjure() },
});
impl EmbassyTimer {
pub(crate) fn now() -> u64 {
SystemTimer::now()
}
fn trigger_alarm(&self, n: usize, cs: CriticalSection) {
let alarm = &self.alarms.borrow(cs)[n];
if let Some((f, ctx)) = alarm.callback.get() {
f(ctx);
}
}
pub(crate) fn on_alarm_allocated(&self, n: usize) {
match n {
0 => self.alarm0.enable_interrupt(true),
1 => self.alarm1.enable_interrupt(true),
2 => self.alarm2.enable_interrupt(true),
_ => {}
}
}
fn on_interrupt(&self, id: usize) {
critical_section::with(|cs| {
self.clear_interrupt(id);
self.trigger_alarm(id, cs);
})
}
pub fn init(_clocks: &Clocks, _systimer: TimerType) {
unsafe {
interrupt::bind_interrupt(Interrupt::SYSTIMER_TARGET0, target0_handler.handler());
unwrap!(interrupt::enable(
Interrupt::SYSTIMER_TARGET0,
target0_handler.priority()
));
interrupt::bind_interrupt(Interrupt::SYSTIMER_TARGET1, target1_handler.handler());
unwrap!(interrupt::enable(
Interrupt::SYSTIMER_TARGET1,
target1_handler.priority()
));
interrupt::bind_interrupt(Interrupt::SYSTIMER_TARGET2, target2_handler.handler());
unwrap!(interrupt::enable(
Interrupt::SYSTIMER_TARGET2,
target2_handler.priority()
));
}
#[handler]
fn target0_handler() {
DRIVER.on_interrupt(0);
}
#[handler]
fn target1_handler() {
DRIVER.on_interrupt(1);
}
#[handler]
fn target2_handler() {
DRIVER.on_interrupt(2);
}
}
pub(crate) fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool {
critical_section::with(|_cs| {
let n = alarm.id() as usize;
// The hardware fires the alarm even if timestamp is lower than the current
// time. In this case the interrupt handler will pend a wakeup when we exit the
// critical section.
self.arm(n, timestamp);
});
// In theory, the above comment is true. However, in practice, we seem to be
// missing interrupt for very short timeouts, so let's make sure and catch
// timestamps that already passed. Returning `false` means embassy will
// run one more poll loop.
Self::now() < timestamp
}
fn clear_interrupt(&self, id: usize) {
match id {
0 => self.alarm0.clear_interrupt(),
1 => self.alarm1.clear_interrupt(),
2 => self.alarm2.clear_interrupt(),
_ => {}
}
}
fn arm(&self, id: usize, timestamp: u64) {
match id {
0 => self.alarm0.set_target(timestamp),
1 => self.alarm1.set_target(timestamp),
2 => self.alarm2.set_target(timestamp),
_ => {}
}
}
}

View File

@ -1,126 +0,0 @@
use critical_section::{CriticalSection, Mutex};
use embassy_time_driver::AlarmHandle;
#[cfg(any(esp32, esp32s2, esp32s3))]
use esp_hal::timer::timg::Timer1;
use esp_hal::{
clock::Clocks,
interrupt::{self, Priority},
peripherals::{Interrupt, TIMG0},
prelude::*,
timer::timg::{Instance, Timer0, TimerGroup},
Async,
};
use crate::AlarmState;
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
pub const ALARM_COUNT: usize = 1;
#[cfg(any(esp32, esp32s2, esp32s3))]
pub const ALARM_COUNT: usize = 2;
pub type TimerType = TimerGroup<'static, TIMG0, Async>;
pub struct EmbassyTimer {
pub(crate) alarms: Mutex<[AlarmState; ALARM_COUNT]>,
}
#[allow(clippy::declare_interior_mutable_const)]
const ALARM_STATE_NONE: AlarmState = AlarmState::new();
embassy_time_driver::time_driver_impl!(static DRIVER: EmbassyTimer = EmbassyTimer {
alarms: Mutex::new([ALARM_STATE_NONE; ALARM_COUNT]),
});
impl EmbassyTimer {
pub(crate) fn now() -> u64 {
unsafe { Timer0::<TIMG0>::steal() }.now()
}
fn trigger_alarm(&self, n: usize, cs: CriticalSection) {
let alarm = &self.alarms.borrow(cs)[n];
if let Some((f, ctx)) = alarm.callback.get() {
f(ctx);
}
}
pub(crate) fn on_alarm_allocated(&self, _n: usize) {}
fn on_interrupt<Timer: Instance>(&self, id: u8, timer: Timer) {
critical_section::with(|cs| {
timer.clear_interrupt();
self.trigger_alarm(id as usize, cs);
});
}
pub fn init(clocks: &Clocks, timer: TimerType) {
// set divider to get a 1mhz clock. APB (80mhz) / 80 = 1mhz...
timer.timer0.set_divider(clocks.apb_clock.to_MHz() as u16);
timer.timer0.set_counter_active(true);
#[cfg(any(esp32, esp32s2, esp32s3))]
{
timer.timer1.set_divider(clocks.apb_clock.to_MHz() as u16);
timer.timer1.set_counter_active(true);
}
unsafe {
interrupt::bind_interrupt(Interrupt::TG0_T0_LEVEL, tg0_t0_level.handler());
unwrap!(interrupt::enable(
Interrupt::TG0_T0_LEVEL,
tg0_t0_level.priority()
));
}
#[cfg(any(esp32, esp32s2, esp32s3))]
unsafe {
interrupt::bind_interrupt(Interrupt::TG0_T1_LEVEL, tg0_t1_level.handler());
unwrap!(interrupt::enable(
Interrupt::TG0_T1_LEVEL,
tg0_t1_level.priority()
));
}
#[handler(priority = Priority::max())]
fn tg0_t0_level() {
let timer = unsafe { Timer0::<TIMG0>::steal() };
DRIVER.on_interrupt(0, timer);
}
#[cfg(any(esp32, esp32s2, esp32s3))]
#[handler(priority = Priority::max())]
fn tg0_t1_level() {
let timer = unsafe { Timer1::<TIMG0>::steal() };
DRIVER.on_interrupt(1, timer);
}
}
pub(crate) fn set_alarm(&self, _alarm: AlarmHandle, timestamp: u64) -> bool {
critical_section::with(|_cs| {
// The hardware fires the alarm even if timestamp is lower than the current
// time. In this case the interrupt handler will pend a wakeup when we exit the
// critical section.
#[cfg(any(esp32, esp32s2, esp32s3))]
if _alarm.id() == 1 {
let mut tg = unsafe { Timer1::<TIMG0>::steal() };
Self::arm(&mut tg, timestamp);
return;
}
let mut tg = unsafe { Timer0::<TIMG0>::steal() };
Self::arm(&mut tg, timestamp);
});
true
}
fn arm<T>(tg: &mut T, timestamp: u64)
where
T: Instance,
{
tg.load_alarm_value(timestamp);
tg.listen();
tg.set_counter_decrementing(false);
tg.set_auto_reload(false);
tg.set_alarm_active(true);
}
}

View File

@ -0,0 +1,60 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Added the `BuilderLite` derive macro which implements the Builder Lite pattern for a struct (#2614)
### Fixed
### Changed
- Functions marked with `#[handler]` can now be referenced in `const` context. (#2559)
### Removed
- Removed the `enum-dispatch`, `interrupt`, and `ram` features (#2594)
## [0.15.0] - 2024-11-20
### Changed
- Remove `get_` prefix from functions (#2528)
## [0.14.0] - 2024-10-10
## [0.13.0] - 2024-08-29
## [0.12.0] - 2024-07-15
## [0.11.0] - 2024-06-04
## [0.10.0] - 2024-04-18
## [0.9.0] - 2024-03-18
## [0.8.0] - 2023-12-12
## [0.7.0] - 2023-10-31
## [0.6.1] - 2023-09-05
## [0.6.0] - 2023-07-04
## [0.5.0] - 2023-03-27
## [0.4.0] - 2023-02-21
## [0.2.0] - 2023-01-26
## [0.1.0] - 2022-08-25
- Initial release
[Unreleased]: https://github.com/esp-rs/esp-hal/commits/main/esp-hal-procmacros?since=2024-11-20

View File

@ -1,8 +1,8 @@
[package]
name = "esp-hal-procmacros"
version = "0.11.0"
version = "0.15.0"
edition = "2021"
rust-version = "1.76.0"
rust-version = "1.83.0"
description = "Procedural macros for esp-hal"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
@ -14,27 +14,21 @@ features = ["embassy", "has-ulp-core", "interrupt", "ram", "is-ulp-core"]
proc-macro = true
[dependencies]
darling = "0.20.9"
document-features = "0.2.8"
darling = "0.20.10"
document-features = "0.2.10"
litrs = "0.4.1"
object = { version = "0.36.0", optional = true }
proc-macro-crate = "3.1.0"
proc-macro-error = "1.0.4"
proc-macro2 = "1.0.84"
quote = "1.0.36"
syn = { version = "2.0.66", features = ["extra-traits", "full"] }
object = { version = "0.36.5", default-features = false, features = ["read_core", "elf"], optional = true }
proc-macro-crate = "3.2.0"
proc-macro-error2 = "2.0.1"
proc-macro2 = "1.0.92"
quote = "1.0.37"
syn = { version = "2.0.89", features = ["extra-traits", "full"] }
[features]
## Provide a `#[main]` procmacro to mark the entry point for Embassy applications.
embassy = []
## Provide enum dispatch helpers.
enum-dispatch = []
## Provide an `#[interrupt]` procmacro for defining interrupt service routines.
interrupt = []
## Provide a `#[ram]` procmacro to place functions in RAM instead of flash.
ram = []
## Indicates the target devices has RTC slow memory available.
rtc_slow = []
## Indicates the target device has RTC slow memory available.
rtc-slow = []
#! ### Low-power Core Feature Flags
## Indicate that the SoC contains an LP core.

View File

@ -46,13 +46,13 @@ pub(crate) mod main {
if !f.sig.generics.params.is_empty() {
ctxt.error_spanned_by(&f.sig, "main function must not be generic");
}
if !f.sig.generics.where_clause.is_none() {
if f.sig.generics.where_clause.is_some() {
ctxt.error_spanned_by(&f.sig, "main function must not have `where` clauses");
}
if !f.sig.abi.is_none() {
if f.sig.abi.is_some() {
ctxt.error_spanned_by(&f.sig, "main function must not have an ABI qualifier");
}
if !f.sig.variadic.is_none() {
if f.sig.variadic.is_some() {
ctxt.error_spanned_by(&f.sig, "main function must not be variadic");
}
match &f.sig.output {
@ -157,7 +157,7 @@ pub(crate) mod main {
pub fn main() -> TokenStream {
quote! {
#[entry]
#[esp_hal::entry]
fn main() -> ! {
let mut executor = ::esp_hal_embassy::Executor::new();
let executor = unsafe { __make_static(&mut executor) };

View File

@ -1,80 +0,0 @@
use proc_macro2::{Group, TokenStream, TokenTree};
use quote::{format_ident, quote};
use syn::{
parse::{Parse, ParseStream, Result},
Ident,
};
#[derive(Debug)]
pub(crate) struct MakeGpioEnumDispatchMacro {
pub name: String,
pub filter: Vec<String>,
pub elements: Vec<(String, usize)>,
}
impl Parse for MakeGpioEnumDispatchMacro {
fn parse(input: ParseStream) -> Result<Self> {
let name = input.parse::<Ident>()?.to_string();
let filter = input
.parse::<Group>()?
.stream()
.into_iter()
.map(|v| match v {
TokenTree::Group(_) => String::new(),
TokenTree::Ident(ident) => ident.to_string(),
TokenTree::Punct(_) => String::new(),
TokenTree::Literal(_) => String::new(),
})
.filter(|p| !p.is_empty())
.collect();
let mut elements = vec![];
let mut stream = input.parse::<Group>()?.stream().into_iter();
let mut element_name = String::new();
loop {
match stream.next() {
Some(v) => match v {
TokenTree::Ident(ident) => {
element_name = ident.to_string();
}
TokenTree::Literal(lit) => {
let index = lit.to_string().parse().unwrap();
elements.push((element_name.clone(), index));
}
_ => (),
},
None => break,
}
}
Ok(MakeGpioEnumDispatchMacro {
name,
filter,
elements,
})
}
}
pub(crate) fn build_match_arms(input: MakeGpioEnumDispatchMacro) -> Vec<TokenStream> {
let mut arms = Vec::new();
for (gpio_type, num) in input.elements {
let enum_name = format_ident!("ErasedPin");
let variant_name = format_ident!("Gpio{}", num);
if input.filter.contains(&gpio_type) {
arms.push({
quote! { #enum_name::#variant_name($target) => $body }
});
} else {
arms.push({
quote! {
#[allow(unused)]
#enum_name::#variant_name($target) => { panic!("Unsupported") }
}
});
}
}
arms
}

View File

@ -24,7 +24,7 @@ pub(crate) fn check_attr_whitelist(
'o: for attr in attrs {
for val in whitelist {
if eq(&attr, &val) {
if eq(attr, val) {
continue 'o;
}
}
@ -35,7 +35,7 @@ pub(crate) fn check_attr_whitelist(
}
};
return Err(Error::new(attr.span(), &err_str).to_compile_error().into());
return Err(Error::new(attr.span(), err_str).to_compile_error().into());
}
Ok(())

View File

@ -16,63 +16,63 @@
//! optimized memory usage and precise handling of hardware interrupts.
//!
//! Key Components:
//! - [interrupt](attr.interrupt.html) - Attribute macro for marking interrupt
//! handlers. Interrupt handlers are used to handle specific hardware
//! interrupts generated by peripherals.<br> The macro allows users to
//! specify the interrupt name explicitly or use the function name to match
//! the interrupt.
//! - [main](attr.main.html) - Creates a new `executor`` instance and declares
//! - [`interrupt`](attr.interrupt.html) - Attribute macro for marking
//! interrupt handlers. Interrupt handlers are used to handle specific
//! hardware interrupts generated by peripherals.
//!
//! The macro allows users to specify the interrupt name explicitly or use
//! the function name to match the interrupt.
//! - [`main`](attr.main.html) - Creates a new `executor` instance and declares
//! an application entry point spawning the corresponding function body as an
//! async task.
//! - [ram](attr.ram.html) - Attribute macro for placing statics and functions
//! into specific memory sections, such as SRAM or RTC RAM (slow or fast)
//! with different initialization options. Supported options are:
//! - `rtc_fast` - Use RTC fast RAM
//! - `rtc_slow` - Use RTC slow RAM (not all targets support slow RTC RAM)
//! - `uninitialized` - Skip initialization of the memory
//! - `zeroed` - Initialize the memory to zero
//! - [`ram`](attr.ram.html) - Attribute macro for placing statics and
//! functions into specific memory sections, such as SRAM or RTC RAM (slow or
//! fast) with different initialization options. See its documentation for
//! details.
//!
//! ## Examples
//!
//!
//! #### `main` macro
//!
//! Requires the `embassy` feature to be enabled.
//!
//! ```no_run
//! ```rust, no_run
//! #[main]
//! async fn main(spawner: Spawner) {
//! // Your application's entry point
//! }
//! ```
//!
//! #### `ram` macro
//!
//! Requires the `ram` feature to be enabled.
//!
//! ```no_run
//! #[ram(rtc_fast)]
//! static mut SOME_INITED_DATA: [u8; 2] = [0xaa, 0xbb];
//!
//! #[ram(rtc_fast, uninitialized)]
//! static mut SOME_UNINITED_DATA: [u8; 2] = [0; 2];
//!
//! #[ram(rtc_fast, zeroed)]
//! static mut SOME_ZEROED_DATA: [u8; 8] = [0; 8];
//! ```
//!
//! ## Feature Flags
#![doc = document_features::document_features!()]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
#[allow(unused)]
use proc_macro::TokenStream;
use darling::{ast::NestedMeta, Error, FromMeta};
use proc_macro::{Span, TokenStream};
use proc_macro2::Ident;
use proc_macro_crate::{crate_name, FoundCrate};
use proc_macro_error2::abort;
use quote::{format_ident, quote};
use syn::{
parse,
parse::Error as ParseError,
spanned::Spanned,
Data,
DataStruct,
GenericArgument,
Item,
ItemFn,
Path,
PathArguments,
PathSegment,
ReturnType,
Type,
};
use self::interrupt::{check_attr_whitelist, WhiteListCaller};
#[cfg(feature = "embassy")]
mod embassy;
#[cfg(feature = "enum-dispatch")]
mod enum_dispatch;
#[cfg(feature = "interrupt")]
mod interrupt;
#[cfg(any(
feature = "is-lp-core",
@ -82,34 +82,72 @@ mod interrupt;
))]
mod lp_core;
#[cfg(feature = "ram")]
#[derive(Debug, Default, darling::FromMeta)]
#[darling(default)]
struct RamArgs {
rtc_fast: bool,
rtc_slow: bool,
uninitialized: bool,
persistent: bool,
zeroed: bool,
}
/// This attribute allows placing statics and functions into ram.
/// Sets which segment of RAM to use for a function or static and how it should
/// be initialized.
///
/// Options that can be specified are rtc_slow or rtc_fast to use the
/// RTC slow or RTC fast ram instead of the normal SRAM.
/// Requires the `ram` feature.
///
/// The uninitialized option will skip initialization of the memory
/// (e.g. to persist it across resets or deep sleep mode for the RTC RAM)
/// # Options
///
/// Not all targets support RTC slow ram.
#[cfg(feature = "ram")]
/// - `rtc_fast`: Use RTC fast RAM.
/// - `rtc_slow`: Use RTC slow RAM. **Note**: not available on all targets.
/// - `persistent`: Persist the contents of the `static` across resets. See [the
/// section below](#persistent) for details.
/// - `zeroed`: Initialize the memory of the `static` to zero. The initializer
/// expression will be discarded. Types used must implement
/// [`bytemuck::Zeroable`].
///
/// Using both `rtc_fast` and `rtc_slow` or `persistent` and `zeroed` together
/// is an error.
///
/// ## `persistent`
///
/// Initialize the memory to zero after the initial boot. Thereafter,
/// initialization is skipped to allow communication across `software_reset()`,
/// deep sleep, watchdog timeouts, etc.
///
/// Types used must implement [`bytemuck::AnyBitPattern`].
///
/// ### Warnings
///
/// - A system-level or lesser reset occurring before the ram has been zeroed
/// *could* skip initialization and start the application with the static
/// filled with random bytes.
/// - There is no way to keep some kinds of resets from happening while updating
/// a persistent static—not even a critical section.
///
/// If these are issues for your application, consider adding a checksum
/// alongside the data.
///
/// # Examples
///
/// ```rust, no_run
/// #[ram(rtc_fast)]
/// static mut SOME_INITED_DATA: [u8; 2] = [0xaa, 0xbb];
///
/// #[ram(rtc_fast, persistent)]
/// static mut SOME_PERSISTENT_DATA: [u8; 2] = [0; 2];
///
/// #[ram(rtc_fast, zeroed)]
/// static mut SOME_ZEROED_DATA: [u8; 8] = [0; 8];
/// ```
///
/// See the `ram` example in the esp-hal repository for a full usage example.
///
/// [`bytemuck::AnyBitPattern`]: https://docs.rs/bytemuck/1.9.0/bytemuck/trait.AnyBitPattern.html
/// [`bytemuck::Zeroable`]: https://docs.rs/bytemuck/1.9.0/bytemuck/trait.Zeroable.html
#[proc_macro_attribute]
#[proc_macro_error::proc_macro_error]
#[proc_macro_error2::proc_macro_error]
pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
use darling::{ast::NestedMeta, Error, FromMeta};
use proc_macro::Span;
use proc_macro_error::abort;
use syn::{parse, Item};
let attr_args = match NestedMeta::parse_meta_list(args.into()) {
Ok(v) => v,
Err(e) => {
@ -120,7 +158,7 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
let RamArgs {
rtc_fast,
rtc_slow,
uninitialized,
persistent,
zeroed,
} = match FromMeta::from_list(&attr_args) {
Ok(v) => v,
@ -131,7 +169,7 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
let item: Item = parse(input).expect("failed to parse input");
#[cfg(not(feature = "rtc_slow"))]
#[cfg(not(feature = "rtc-slow"))]
if rtc_slow {
abort!(
Span::call_site(),
@ -140,7 +178,7 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
}
let is_fn = matches!(item, Item::Fn(_));
let section_name = match (is_fn, rtc_fast, rtc_slow, uninitialized, zeroed) {
let section_name = match (is_fn, rtc_fast, rtc_slow, persistent, zeroed) {
(true, false, false, false, false) => Ok(".rwtext"),
(true, true, false, false, false) => Ok(".rtc_fast.text"),
(true, false, true, false, false) => Ok(".rtc_slow.text"),
@ -148,11 +186,11 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
(false, false, false, false, false) => Ok(".data"),
(false, true, false, false, false) => Ok(".rtc_fast.data"),
(false, true, false, true, false) => Ok(".rtc_fast.noinit"),
(false, true, false, true, false) => Ok(".rtc_fast.persistent"),
(false, true, false, false, true) => Ok(".rtc_fast.bss"),
(false, false, true, false, false) => Ok(".rtc_slow.data"),
(false, false, true, true, false) => Ok(".rtc_slow.noinit"),
(false, false, true, true, false) => Ok(".rtc_slow.persistent"),
(false, false, true, false, true) => Ok(".rtc_slow.bss"),
_ => Err(()),
@ -171,9 +209,39 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
}
};
let trait_check = if zeroed {
Some("zeroable")
} else if persistent {
Some("persistable")
} else {
None
};
let trait_check = trait_check.map(|name| {
use proc_macro_crate::{crate_name, FoundCrate};
let hal = Ident::new(
if let Ok(FoundCrate::Name(ref name)) = crate_name("esp-hal") {
name
} else {
"crate"
},
Span::call_site().into(),
);
let assertion = quote::format_ident!("assert_is_{name}");
let Item::Static(ref item) = item else {
abort!(item, "Expected a `static`");
};
let ty = &item.ty;
quote::quote! {
const _: () = #hal::__macro_implementation::#assertion::<#ty>();
}
});
let output = quote::quote! {
#section
#item
#trait_check
};
output.into()
@ -185,18 +253,9 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
/// esp_hal::interrupt::Priority::Priority2)]`.
///
/// If no priority is given, `Priority::min()` is assumed
#[cfg(feature = "interrupt")]
#[proc_macro_error::proc_macro_error]
#[proc_macro_attribute]
#[proc_macro_error2::proc_macro_error]
pub fn handler(args: TokenStream, input: TokenStream) -> TokenStream {
use darling::{ast::NestedMeta, FromMeta};
use proc_macro::Span;
use proc_macro2::Ident;
use proc_macro_crate::{crate_name, FoundCrate};
use syn::{parse::Error as ParseError, spanned::Spanned, ItemFn, ReturnType, Type};
use self::interrupt::{check_attr_whitelist, WhiteListCaller};
#[derive(Debug, FromMeta)]
struct MacroArgs {
priority: Option<syn::Expr>,
@ -221,7 +280,7 @@ pub fn handler(args: TokenStream, input: TokenStream) -> TokenStream {
let root = Ident::new(
if let Ok(FoundCrate::Name(ref name)) = crate_name("esp-hal") {
&name
name
} else {
"crate"
},
@ -277,46 +336,15 @@ pub fn handler(args: TokenStream, input: TokenStream) -> TokenStream {
#f
#[allow(non_upper_case_globals)]
#vis static #orig: #root::interrupt::InterruptHandler = #root::interrupt::InterruptHandler::new(#new, #priority);
#vis const #orig: #root::interrupt::InterruptHandler = #root::interrupt::InterruptHandler::new(#new, #priority);
)
.into()
}
/// Create an enum for erased GPIO pins, using the enum-dispatch pattern
///
/// Only used internally
#[cfg(feature = "enum-dispatch")]
#[proc_macro]
pub fn make_gpio_enum_dispatch_macro(input: TokenStream) -> TokenStream {
use quote::{format_ident, quote};
use self::enum_dispatch::{build_match_arms, MakeGpioEnumDispatchMacro};
let input = syn::parse_macro_input!(input as MakeGpioEnumDispatchMacro);
let macro_name = format_ident!("{}", input.name);
let arms = build_match_arms(input);
quote! {
#[doc(hidden)]
#[macro_export]
macro_rules! #macro_name {
($m:ident, $target:ident, $body:block) => {
match $m {
#(#arms)*
}
}
}
pub(crate) use #macro_name;
}
.into()
}
/// Load code to be run on the LP/ULP core.
///
/// ## Example
/// ```no_run
/// ```rust, no_run
/// let lp_core_code = load_lp_code!("path.elf");
/// lp_core_code.run(&mut lp_core, lp_core::LpCoreWakeupSource::HpCpu, lp_pin);
/// ````
@ -328,8 +356,8 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
/// Marks the entry function of a LP core / ULP program.
#[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))]
#[proc_macro_error::proc_macro_error]
#[proc_macro_attribute]
#[proc_macro_error2::proc_macro_error]
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
lp_core::entry(args, input)
}
@ -368,3 +396,129 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
run(&args.meta, f, main()).unwrap_or_else(|x| x).into()
}
/// Automatically implement the [Builder Lite] pattern for a struct.
///
/// This will create an `impl` which contains methods for each field of a
/// struct, allowing users to easily set the values. The generated methods will
/// be the field name prefixed with `with_`, and calls to these methods can be
/// chained as needed.
///
/// ## Example
///
/// ```rust, no_run
/// #[derive(Default)]
/// enum MyEnum {
/// #[default]
/// A,
/// B,
/// }
///
/// #[derive(Default, BuilderLite)]
/// #[non_exhaustive]
/// struct MyStruct {
/// enum_field: MyEnum,
/// bool_field: bool,
/// option_field: Option<i32>,
/// }
///
/// MyStruct::default()
/// .with_enum_field(MyEnum::B)
/// .with_bool_field(true)
/// .with_option_field(-5);
/// ```
///
/// [Builder Lite]: https://matklad.github.io/2022/05/29/builder-lite.html
#[proc_macro_derive(BuilderLite)]
pub fn builder_lite_derive(item: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(item as syn::DeriveInput);
let span = input.span();
let ident = input.ident;
let mut fns = Vec::new();
if let Data::Struct(DataStruct { fields, .. }) = &input.data {
for field in fields {
let field_ident = field.ident.as_ref().unwrap();
let field_type = &field.ty;
let function_ident = format_ident!("with_{}", field_ident);
let maybe_path_type = extract_type_path(field_type)
.and_then(|path| extract_option_segment(path))
.and_then(|path_seg| match path_seg.arguments {
PathArguments::AngleBracketed(ref params) => params.args.first(),
_ => None,
})
.and_then(|generic_arg| match *generic_arg {
GenericArgument::Type(ref ty) => Some(ty),
_ => None,
});
let (field_type, field_assigns) = if let Some(inner_type) = maybe_path_type {
(inner_type, quote! { Some(#field_ident) })
} else {
(field_type, quote! { #field_ident })
};
fns.push(quote! {
#[doc = concat!(" Assign the given value to the `", stringify!(#field_ident) ,"` field.")]
#[must_use]
pub fn #function_ident(mut self, #field_ident: #field_type) -> Self {
self.#field_ident = #field_assigns;
self
}
});
if maybe_path_type.is_some() {
let function_ident = format_ident!("with_{}_none", field_ident);
fns.push(quote! {
#[doc = concat!(" Set the value of `", stringify!(#field_ident), "` to `None`.")]
#[must_use]
pub fn #function_ident(mut self) -> Self {
self.#field_ident = None;
self
}
});
}
}
} else {
return ParseError::new(
span,
"#[derive(Builder)] is only defined for structs, not for enums or unions!",
)
.to_compile_error()
.into();
}
let implementation = quote! {
#[automatically_derived]
impl #ident {
#(#fns)*
}
};
implementation.into()
}
// https://stackoverflow.com/a/56264023
fn extract_type_path(ty: &Type) -> Option<&Path> {
match *ty {
Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path),
_ => None,
}
}
// https://stackoverflow.com/a/56264023
fn extract_option_segment(path: &Path) -> Option<&PathSegment> {
let idents_of_path = path.segments.iter().fold(String::new(), |mut acc, v| {
acc.push_str(&v.ident.to_string());
acc.push('|');
acc
});
vec!["Option|", "std|option|Option|", "core|option|Option|"]
.into_iter()
.find(|s| idents_of_path == *s)
.and_then(|_| path.segments.last())
}

View File

@ -6,7 +6,7 @@ use quote::quote;
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
use proc_macro2::{Ident, Span};
use proc_macro_crate::{crate_name, FoundCrate};
use quote::{format_ident, quote};
use quote::format_ident;
use syn::{
parse::Error,
parse_macro_input,
@ -23,19 +23,19 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
let mut res = String::from("__ULP_MAGIC_");
for &a in args {
let t = &a.ty;
let quoted = to_string(&t);
let quoted = to_string(t);
res.push_str(&quoted);
res.push_str("$");
res.push('$');
}
res
}
pub(crate) fn get_simplename(t: &Type) -> String {
String::from(match t {
Type::Path(p) => String::from(&p.path.segments.last().unwrap().ident.to_string()),
pub(crate) fn simplename(t: &Type) -> String {
match t {
Type::Path(p) => p.path.segments.last().unwrap().ident.to_string(),
_ => String::new(),
})
}
}
pub(crate) fn extract_pin(ty: &Type) -> u8 {
@ -49,7 +49,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
res = extract_pin(t);
}
GenericArgument::Const(c) => {
res = (&quote! { #c }.to_string()).parse().unwrap();
res = quote! { #c }.to_string().parse().unwrap();
}
_ => (),
}
@ -68,11 +68,11 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
res.push_str(&segment.ident.to_string());
if let PathArguments::AngleBracketed(g) = &segment.arguments {
res.push_str("<");
res.push('<');
let mut pushed = false;
for arg in &g.args {
if pushed {
res.push_str(",");
res.push(',');
}
match arg {
@ -87,7 +87,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
_ => (),
}
}
res.push_str(">");
res.push('>');
}
}
@ -125,7 +125,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
.into();
}
FnArg::Typed(t) => {
match get_simplename(&t.ty).as_str() {
match simplename(&t.ty).as_str() {
"Output" => {
let pin = extract_pin(&t.ty);
if used_pins.contains(&pin) {
@ -219,7 +219,7 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
};
let hal_crate = if let Ok(FoundCrate::Name(ref name)) = hal_crate {
let ident = Ident::new(&name, Span::call_site().into());
let ident = Ident::new(name, Span::call_site().into());
quote!( #ident )
} else {
quote!(crate)
@ -261,12 +261,14 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
let mut sections: Vec<Section> = sections
.into_iter()
.filter(|section| match section.kind() {
SectionKind::Text
| SectionKind::ReadOnlyData
| SectionKind::Data
| SectionKind::UninitializedData => true,
_ => false,
.filter(|section| {
matches!(
section.kind(),
SectionKind::Text
| SectionKind::ReadOnlyData
| SectionKind::Data
| SectionKind::UninitializedData
)
})
.collect();
sections.sort_by(|a, b| a.address().partial_cmp(&b.address()).unwrap());
@ -280,9 +282,8 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
for section in sections {
if section.address() > last_address {
for _ in 0..(section.address() - last_address) {
binary.push(0);
}
let fill = section.address() - last_address;
binary.extend(std::iter::repeat(0).take(fill as usize));
}
binary.extend_from_slice(section.data().unwrap());
@ -293,21 +294,20 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
.symbols()
.find(|s| s.name().unwrap().starts_with("__ULP_MAGIC_"));
if let None = magic_symbol {
let magic_symbol = if let Some(magic_symbol) = magic_symbol {
magic_symbol.name().unwrap()
} else {
return Error::new(
Span::call_site().into(),
"Given file doesn't seem to be an LP/ULP core application.",
)
.to_compile_error()
.into();
}
let magic_symbol = magic_symbol.unwrap().name().unwrap();
};
let magic_symbol = magic_symbol.trim_start_matches("__ULP_MAGIC_");
let args: Vec<proc_macro2::TokenStream> = magic_symbol
.split("$")
.into_iter()
.map(|t| {
let t = if t.contains("OutputOpenDrain") {
t.replace("OutputOpenDrain", "LowPowerOutputOpenDrain")

View File

@ -1,37 +0,0 @@
[package]
name = "esp-hal-smartled"
version = "0.11.0"
edition = "2021"
rust-version = "1.76.0"
description = "RMT adapter for smartleds"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
[package.metadata.docs.rs]
features = ["esp32c3"]
targets = ["riscv32imc-unknown-none-elf"]
[dependencies]
defmt = { version = "0.3.8", optional = true }
document-features = "0.2.8"
esp-hal = { version = "0.18.0", path = "../esp-hal" }
fugit = "0.3.7"
smart-leds-trait = "0.3.0"
[features]
## Implement `defmt::Format` on certain types.
defmt = ["dep:defmt", "esp-hal/defmt"]
#! ### Chip Support Feature Flags
## Target the ESP32.
esp32 = ["esp-hal/esp32"]
## Target the ESP32-C3.
esp32c3 = ["esp-hal/esp32c3"]
## Target the ESP32-C6.
esp32c6 = ["esp-hal/esp32c6"]
## Target the ESP32-H2.
esp32h2 = ["esp-hal/esp32h2"]
## Target the ESP32-S2.
esp32s2 = ["esp-hal/esp32s2"]
## Target the ESP32-S3.
esp32s3 = ["esp-hal/esp32s3"]

View File

@ -1,35 +0,0 @@
# esp-hal-smartled
[![Crates.io](https://img.shields.io/crates/v/esp-hal-smartled?labelColor=1C2C2E&color=C96329&logo=Rust&style=flat-square)](https://crates.io/crates/esp-hal-smartled)
[![docs.rs](https://img.shields.io/docsrs/esp-hal-smartled?labelColor=1C2C2E&color=C96329&logo=rust&style=flat-square)](https://docs.rs/esp-hal-smartled)
![MSRV](https://img.shields.io/badge/MSRV-1.76-blue?labelColor=1C2C2E&style=flat-square)
![Crates.io](https://img.shields.io/crates/l/esp-hal-smartled?labelColor=1C2C2E&style=flat-square)
[![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&labelColor=1C2C2E&color=BEC5C9&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org)
Allows for the use of an RMT output channel to easily interact with RGB LEDs and use the convenience functions of the [smart-leds] crate.
[smart-leds]: https://crates.io/crates/smart-leds
## [Documentation]
[documentation]: https://docs.rs/esp-hal-smartled/
## Minimum Supported Rust Version (MSRV)
This crate is guaranteed to compile on stable Rust 1.76 and up. It _might_
compile with older versions but that may change in any new patch release.
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without
any additional terms or conditions.

View File

@ -1,202 +0,0 @@
//! This adapter allows for the use of an RMT output channel to easily interact
//! with RGB LEDs and use the convenience functions of the
//! [`smart-leds`](https://crates.io/crates/smart-leds) crate.
//!
//! This is a simple implementation where every LED is adressed in an
//! individual RMT operation. This is working perfectly fine in blocking mode,
//! but in case this is used in combination with interrupts that might disturb
//! the sequential sending, an alternative implementation (addressing the LEDs
//! in a sequence in a single RMT send operation) might be required!
//!
//! ## Example
//!
//! ```rust,ignore
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! let rmt = Rmt::new(peripherals.RMT, 80.MHz(), &clocks, None).unwrap();
//!
//! let rmt_buffer = smartLedBuffer!(1);
//! let mut led = SmartLedsAdapter::new(rmt.channel0, io.pins.gpio2, rmt_buffer, &clocks);
//! ```
//!
//! ## Feature Flags
#![doc = document_features::document_features!()]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
#![deny(missing_docs)]
#![no_std]
use core::{fmt::Debug, slice::IterMut};
use esp_hal::{
clock::Clocks,
gpio::OutputPin,
peripheral::Peripheral,
rmt::{Error as RmtError, PulseCode, TxChannel, TxChannelConfig, TxChannelCreator},
};
use smart_leds_trait::{SmartLedsWrite, RGB8};
const SK68XX_CODE_PERIOD: u32 = 1200;
const SK68XX_T0H_NS: u32 = 320;
const SK68XX_T0L_NS: u32 = SK68XX_CODE_PERIOD - SK68XX_T0H_NS;
const SK68XX_T1H_NS: u32 = 640;
const SK68XX_T1L_NS: u32 = SK68XX_CODE_PERIOD - SK68XX_T1H_NS;
/// All types of errors that can happen during the conversion and transmission
/// of LED commands
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum LedAdapterError {
/// Raised in the event that the provided data container is not large enough
BufferSizeExceeded,
/// Raised if something goes wrong in the transmission,
TransmissionError(RmtError),
}
/// Macro to allocate a buffer sized for a specific number of LEDs to be
/// addressed.
///
/// Attempting to use more LEDs that the buffer is configured for will result in
/// an `LedAdapterError:BufferSizeExceeded` error.
#[macro_export]
macro_rules! smartLedBuffer {
( $buffer_size: literal ) => {
// The size we're assigning here is calculated as following
// (
// Nr. of LEDs
// * channels (r,g,b -> 3)
// * pulses per channel 8)
// ) + 1 additional pulse for the end delimiter
[0u32; $buffer_size * 24 + 1]
};
}
/// Adapter taking an RMT channel and a specific pin and providing RGB LED
/// interaction functionality using the `smart-leds` crate
pub struct SmartLedsAdapter<TX, const BUFFER_SIZE: usize>
where
TX: TxChannel,
{
channel: Option<TX>,
rmt_buffer: [u32; BUFFER_SIZE],
pulses: (u32, u32),
}
impl<'d, TX, const BUFFER_SIZE: usize> SmartLedsAdapter<TX, BUFFER_SIZE>
where
TX: TxChannel,
{
/// Create a new adapter object that drives the pin using the RMT channel.
pub fn new<C, O>(
channel: C,
pin: impl Peripheral<P = O> + 'd,
rmt_buffer: [u32; BUFFER_SIZE],
clocks: &Clocks,
) -> SmartLedsAdapter<TX, BUFFER_SIZE>
where
O: OutputPin + 'd,
C: TxChannelCreator<'d, TX, O>,
{
let config = TxChannelConfig {
clk_divider: 1,
idle_output_level: false,
carrier_modulation: false,
idle_output: true,
..TxChannelConfig::default()
};
let channel = channel.configure(pin, config).unwrap();
// Assume the RMT peripheral is set up to use the APB clock
let src_clock = clocks.apb_clock.to_MHz();
Self {
channel: Some(channel),
rmt_buffer,
pulses: (
u32::from(PulseCode {
level1: true,
length1: ((SK68XX_T0H_NS * src_clock) / 1000) as u16,
level2: false,
length2: ((SK68XX_T0L_NS * src_clock) / 1000) as u16,
}),
u32::from(PulseCode {
level1: true,
length1: ((SK68XX_T1H_NS * src_clock) / 1000) as u16,
level2: false,
length2: ((SK68XX_T1L_NS * src_clock) / 1000) as u16,
}),
),
}
}
fn convert_rgb_to_pulse(
value: RGB8,
mut_iter: &mut IterMut<u32>,
pulses: (u32, u32),
) -> Result<(), LedAdapterError> {
Self::convert_rgb_channel_to_pulses(value.g, mut_iter, pulses)?;
Self::convert_rgb_channel_to_pulses(value.r, mut_iter, pulses)?;
Self::convert_rgb_channel_to_pulses(value.b, mut_iter, pulses)?;
Ok(())
}
fn convert_rgb_channel_to_pulses(
channel_value: u8,
mut_iter: &mut IterMut<u32>,
pulses: (u32, u32),
) -> Result<(), LedAdapterError> {
for position in [128, 64, 32, 16, 8, 4, 2, 1] {
*mut_iter.next().ok_or(LedAdapterError::BufferSizeExceeded)? =
match channel_value & position {
0 => pulses.0,
_ => pulses.1,
}
}
Ok(())
}
}
impl<TX, const BUFFER_SIZE: usize> SmartLedsWrite for SmartLedsAdapter<TX, BUFFER_SIZE>
where
TX: TxChannel,
{
type Error = LedAdapterError;
type Color = RGB8;
/// Convert all RGB8 items of the iterator to the RMT format and
/// add them to internal buffer, then start a singular RMT operation
/// based on that buffer.
fn write<T, I>(&mut self, iterator: T) -> Result<(), Self::Error>
where
T: IntoIterator<Item = I>,
I: Into<Self::Color>,
{
// We always start from the beginning of the buffer
let mut seq_iter = self.rmt_buffer.iter_mut();
// Add all converted iterator items to the buffer.
// This will result in an `BufferSizeExceeded` error in case
// the iterator provides more elements than the buffer can take.
for item in iterator {
Self::convert_rgb_to_pulse(item.into(), &mut seq_iter, self.pulses)?;
}
// Finally, add an end element.
*seq_iter.next().ok_or(LedAdapterError::BufferSizeExceeded)? = 0;
// Perform the actual RMT operation. We use the u32 values here right away.
let channel = self.channel.take().unwrap();
match channel.transmit(&self.rmt_buffer).wait() {
Ok(chan) => {
self.channel = Some(chan);
Ok(())
}
Err((e, chan)) => {
self.channel = Some(chan);
Err(LedAdapterError::TransmissionError(e))
}
}
}
}

1
esp-hal/.clippy.toml Normal file
View File

@ -0,0 +1 @@
avoid-breaking-exported-api = false

View File

@ -5,6 +5,476 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- ESP32-S3: Added SDMMC signals (#2556)
- Added `set_priority` to the `DmaChannel` trait on GDMA devices (#2403, #2526)
- Added `into_async` and `into_blocking` functions for `ParlIoTxOnly`, `ParlIoRxOnly` (#2526)
- ESP32-C6, H2, S3: Added `split` function to the `DmaChannel` trait. (#2526, #2532)
- DMA: `PeripheralDmaChannel` type aliasses and `DmaChannelFor` traits to improve usability. (#2532)
- `dma::{Channel, ChannelRx, ChannelTx}::set_priority` for GDMA devices (#2403)
- `esp_hal::asynch::AtomicWaker` that does not hold a global critical section (#2555)
- `esp_hal::sync::RawMutex` for embassy-sync. (#2555)
- ESP32-C6, H2, S3: Added `split` function to the `DmaChannel` trait. (#2526)
- Added PSRAM configuration to `esp_hal::Config` if `quad-psram` or `octal-psram` is enabled (#2546)
- Added `esp_hal::psram::psram_raw_parts` (#2546)
- The timer drivers `OneShotTimer` & `PeriodicTimer` have `into_async` and `new_typed` methods (#2586)
- `timer::Timer` trait has three new methods, `wait`, `async_interrupt_handler` and `peripheral_interrupt` (#2586)
- Configuration structs in the I2C, SPI, and UART drivers now implement the Builder Lite pattern (#2614)
- Added `I8080::apply_config`, `DPI::apply_config` and `Camera::apply_config` (#2610)
- Introduced the `unstable` feature which will be used to restrict stable APIs to a subset of esp-hal. (#2628)
- HAL configuration structs now implement the Builder Lite pattern (#2645)
- Added `OutputOpenDrain::unlisten` (#2625)
- Added `{Input, Flex}::wait_for` (#2625)
- Peripheral singletons now implement `Debug` and `defmt::Format` (#2682, #2834)
- `BurstConfig`, a device-specific configuration for configuring DMA transfers in burst mode (#2543)
- `{DmaRxBuf, DmaTxBuf, DmaRxTxBuf}::set_burst_config` (#2543)
- Added `SpiDmaBus::split` for moving between manual & automatic DMA buffers (#2824)
- ESP32-S2: DMA support for AES (#2699)
- Added `transfer_in_place_async` and embedded-hal-async implementation to `Spi` (#2691)
- `InterruptHandler` now implements `Hash` and `defmt::Format` (#2830)
- `uart::ConfigError` now implements `Eq` (#2825)
- `i2c::master::Error` now implements `Eq` and `Hash` (#2825)
- `i2c::master::Operation` now implements `Debug`, `PartialEq`, `Eq`, `Hash`, and `Display` (#2825)
- `i2c::master::Config` now implements `PartialEq`, `Eq`, ans `Hash` (#2825)
- `i2c::master::I2c` now implements `Debug`, `PartialEq`, and `Eq` (#2825)
- `i2c::master::Info` now implements `Debug` (#2825)
- `spi::master::Config` now implements `Hash` (#2823)
- `spi::master` drivers now implement `Debug` and `defmt::Format` (#2823)
- `DmaRxBuf`, `DmaTxBuf` and `DmaRxTxBuf` now implement `Debug` and `defmt::Format` (#2823)
- DMA channels (`AnyGdmaChannel`, `SpiDmaChannel`, `I2sDmaChannel`, `CryptoDmaChannel`) and their RX/TX halves now implement `Debug` and `defmt::Format` (#2823)
- `DmaDescriptor` and `DmaDescriptorFlags` now implement `PartialEq` and `Eq` (#2823)
- `gpio::{Event, WakeEvent, GpioRegisterAccess}` now implement `Debug`, `Eq`, `PartialEq` and `Hash` (#2842)
- `gpio::{Level, Pull, AlternateFunction, RtcFunction}` now implement `Hash` (#2842)
- `gpio::{GpioPin, AnyPin, Io, Output, OutputOpenDrain, Input, Flex}` now implement `Debug`, `defmt::Format` (#2842)
- More interrupts are available in `esp_hal::spi::master::SpiInterrupt`, add `enable_listen`,`interrupts` and `clear_interrupts` for ESP32/ESP32-S2 (#2833)
- The `ExtU64` and `RateExtU32` traits have been added to `esp_hal::time` (#2845)
- Added `AnyPin::steal(pin_number)` (#2854)
- `adc::{AdcCalSource, Attenuation, Resolution}` now implement `Hash` and `defmt::Format` (#2840)
- `rtc_cntl::{RtcFastClock, RtcSlowClock, RtcCalSel}` now implement `PartialEq`, `Eq`, `Hash` and `defmt::Format` (#2840)
- Added `tsens::TemperatureSensor` peripheral for ESP32C6 and ESP32C3 (#2875)
- Added `with_rx()` and `with_tx()` methods to Uart, UartRx, and UartTx ()
### Changed
- Bump MSRV to 1.83 (#2615)
- In addition to taking by value, peripheral drivers can now mutably borrow DMA channel objects. (#2526)
- DMA channel objects are no longer wrapped in `Channel`. The `Channel` drivers are now managed by DMA enabled peripheral drivers. (#2526)
- The `Dpi` driver and `DpiTransfer` now have a `Mode` type parameter. The driver's asyncness is determined by the asyncness of the `Lcd` used to create it. (#2526)
- `dma::{Channel, ChannelRx, ChannelTx}::set_priority` for GDMA devices (#2403)
- `SystemTimer::set_unit_value` & `SystemTimer::configure_unit` (#2576)
- `SystemTimer` no longer uses peripheral ref (#2576)
- `TIMGX` no longer uses peripheral ref (#2581)
- `SystemTimer::now` has been renamed `SystemTimer::unit_value(Unit)` (#2576)
- `SpiDma` transfers now explicitly take a length along with the DMA buffer object (#2587)
- `dma::{Channel, ChannelRx, ChannelTx}::set_priority` for GDMA devices (#2403)
- `SystemTimer`s `Alarm`s are now type erased (#2576)
- `TimerGroup` `Timer`s are now type erased (#2581)
- PSRAM is now initialized automatically if `quad-psram` or `octal-psram` is enabled (#2546)
- DMA channels are now available via the `Peripherals` struct, and have been renamed accordingly. (#2545)
- Moved interrupt related items from lib.rs, moved to the `interrupt` module (#2613)
- The timer drivers `OneShotTimer` & `PeriodicTimer` now have a `Mode` parameter and type erase the underlying driver by default (#2586)
- `timer::Timer` has new trait requirements of `Into<AnyTimer>`, `'static` and `InterruptConfigurable` (#2586)
- `systimer::etm::Event` no longer borrows the alarm indefinitely (#2586)
- A number of public enums and structs in the I2C, SPI, and UART drivers have been marked with `#[non_exhaustive]` (#2614)
- Interrupt handling related functions are only provided for Blocking UART. (#2610)
- Changed how `Spi`, (split or unsplit) `Uart`, `LpUart`, `I8080`, `Camera`, `DPI` and `I2C` drivers are constructed (#2610)
- I8080, camera, DPI: The various standalone configuration options have been merged into `Config` (#2610)
- Dropped GPIO futures stop listening for interrupts (#2625)
- UART driver's `StopBits` enum variants now correctly use UpperCamelCase (#2669)
- The `PeripheralInput` and `PeripheralOutput` traits are now sealed (#2690)
- `esp_hal::sync::Lock` has been renamed to RawMutex (#2684)
- Updated `esp-pacs` with support for Wi-Fi on the ESP32 and made the peripheral non virtual
- `SpiBitOrder`, `SpiDataMode`, `SpiMode` were renamed to `BitOder`, `DataMode` and `Mode` (#2828)
- `crate::Mode` was renamed to `crate::DriverMode` (#2828)
- `Spi::with_miso` has been overloaded into `Spi::with_miso` and `Spi::with_sio1` (#2557)
- Renamed some I2C error variants (#2844)
- I2C: Replaced potential panics with errors. (#2831)
- UART: Make `AtCmdConfig` and `ConfigError` non-exhaustive (#2851)
- UART: Make `AtCmdConfig` use builder-lite pattern (#2851)
- UART: Fix naming violations for `DataBits`, `Parity`, and `StopBits` enum variants (#2893)
- UART: Remove blocking version of `read_bytes` and rename `drain_fifo` to `read_bytes` instead (#2895)
- Renamed variants of `CpuClock`, made the enum non-exhaustive (#2899)
- SPI: Fix naming violations for `Mode` enum variants (#2902)
- SPI: Fix naming violations for `Address` and `Command` enum variants (#2906)
- `ClockSource` enums are now `#[non_exhaustive]` (#2912)
- `gpio::{Input, Flex}::wakeup_enable` now returns an error instead of panicking. (#2916)
- Removed the `I` prefix from `DriveStrength` enum variants. (#2922)
- Removed the `Attenuation` prefix from `Attenuation` enum variants. (#2922)
### Fixed
- Xtensa devices now correctly enable the `esp-hal-procmacros/rtc-slow` feature (#2594)
- User-bound GPIO interrupt handlers should no longer interfere with async pins. (#2625)
- `spi::master::Spi::{into_async, into_blocking}` are now correctly available on the typed driver, to. (#2674)
- It is no longer possible to safely conjure `GpioPin` instances (#2688)
- UART: Public API follows `C-WORD_ORDER` Rust API standard (`VerbObject` order) (#2851)
- `DmaRxStreamBuf` now correctly resets the descriptors the next time it's used (#2890)
### Removed
- Remove more examples. Update doctests. (#2547)
- The `configure` and `configure_for_async` DMA channel functions has been removed (#2403)
- The DMA channel objects no longer have `tx` and `rx` fields. (#2526)
- `SysTimerAlarms` has been removed, alarms are now part of the `SystemTimer` struct (#2576)
- `FrozenUnit`, `AnyUnit`, `SpecificUnit`, `SpecificComparator`, `AnyComparator` have been removed from `systimer` (#2576)
- Remove Dma[Rx|Tx]Buffer::length (#2587)
- `esp_hal::psram::psram_range` (#2546)
- The `Dma` structure has been removed. (#2545)
- Removed `embedded-hal 0.2.x` impls and deps from `esp-hal` (#2593)
- Removed `Camera::set_` functions (#2610)
- `DmaTxBuf::{compute_chunk_size, compute_descriptor_count, new_with_block_size}` (#2543)
- The `prelude` module has been removed (#2845)
- Removed all peripheral instance type parameters and `new_typed` constructors (#2907)
## [0.22.0] - 2024-11-20
### Added
- A new config option `PLACE_SWITCH_TABLES_IN_RAM` to improve performance (especially for interrupts) at the cost of slightly more RAM usage (#2331)
- A new config option `PLACE_ANON_IN_RAM` to improve performance (especially for interrupts) at the cost of RAM usage (#2331)
- Add burst transfer support to DMA buffers (#2336)
- `AnyPin` now implements `From<GpioPin<N>>`. (#2326)
- Added `AnySpi` and `AnySpiDmaChannel`. (#2334)
- Added `AnyI2s` and `AnyI2sDmaChannel`. (#2367)
- Added `AnyTwai`. (#2359)
- Added `AnyUart`. (#2381)
- `Pins::steal()` to unsafely obtain GPIO. (#2335)
- `I2c::with_timeout` (#2361)
- `Spi::half_duplex_read` and `Spi::half_duplex_write` (#2373)
- Add RGB/DPI driver (#2415)
- Add `DmaLoopBuf` (#2415)
- `Cpu::COUNT` and `Cpu::current()` (#2411)
- `UartInterrupt` and related functions (#2406)
- I2S Parallel output driver for ESP32. (#2348, #2436, #2472)
- Add an option to configure `WDT` action (#2330)
- `DmaDescriptor` is now `Send` (#2456)
- `into_async` and `into_blocking` functions for most peripherals (#2430, #2461)
- API mode type parameter (currently always `Blocking`) to `master::Spi` and `slave::Spi` (#2430)
- `gpio::{GpioPin, AnyPin, Flex, Output, OutputOpenDrain}::split()` to obtain peripheral interconnect signals. (#2418)
- `gpio::Input::{split(), into_peripheral_output()}` when used with output pins. (#2418)
- `gpio::Output::peripheral_input()` (#2418)
- `{Uart, UartRx, UartTx}::apply_config()` (#2449)
- `{Uart, UartRx, UartTx}` now implement `embassy_embedded_hal::SetConfig` (#2449)
- GPIO ETM tasks and events now accept `InputSignal` and `OutputSignal` (#2427)
- `spi::master::Config` and `{Spi, SpiDma, SpiDmaBus}::apply_config` (#2448)
- `embassy_embedded_hal::SetConfig` is now implemented for `spi::master::{Spi, SpiDma, SpiDmaBus}`, `i2c::master::I2c` (#2448, #2477)
- `slave::Spi::{with_mosi(), with_miso(), with_sclk(), with_cs()}` functions (#2485)
- I8080: Added `set_8bits_order()` to set the byte order in 8-bit mode (#2487)
- `I2c::{apply_config(), with_sda(), with_scl()}` (#2477)
- ESP32-S2: Added missing GPIO alternate functions (#2512)
### Changed
- Peripheral type erasure for SPI (#2334)
- Peripheral type erasure for I2S (#2367)
- Peripheral type erasure for I2C (#2361)
- Peripheral type erasure for TWAI (#2359)
- The SPI driver has been rewritten to allow using half-duplex and full-duplex functionality on the same bus. See the migration guide for details. (#2373)
- Renamed `SpiDma` functions: `dma_transfer` to `transfer`, `dma_write` to `write`, `dma_read` to `read`. (#2373)
- Peripheral type erasure for UART (#2381)
- Changed listening for UART events (#2406)
- Circular DMA transfers now correctly error, `available` returns `Result<usize,DmaError>` now (#2409)
- Interrupt listen/unlisten/clear functions now accept any type that converts into `EnumSet` (i.e. single interrupt flags). (#2442)
- SPI interrupt listening is now only available in Blocking mode. The `set_interrupt_handler` is available via `InterruptConfigurable` (#2442)
- Allow users to create DMA `Preparation`s (#2455)
- The `rmt::asynch::RxChannelAsync` and `rmt::asynch::TxChannelAsync` traits have been moved to `rmt` (#2430)
- Calling `AnyPin::output_signals` on an input-only pin (ESP32 GPIO 34-39) will now result in a panic. (#2418)
- UART configuration types have been moved to `esp_hal::uart` (#2449)
- `spi::master::Spi::new()` no longer takes `frequency` and `mode` as a parameter. (#2448)
- Peripheral interconnections via GPIO pins now use the GPIO matrix. (#2419)
- The I2S driver has been moved to `i2s::master` (#2472)
- `slave::Spi` constructors no longer take pins (#2485)
- The `I2c` master driver has been moved from `esp_hal::i2c` to `esp_hal::i2c::master`. (#2476)
- `I2c` SCL timeout is now defined in bus clock cycles. (#2477)
- Trying to send a single-shot RMT transmission will result in an error now, `RMT` deals with `u32` now, `PulseCode` is a convenience trait now (#2463)
- Removed `get_` prefixes from functions (#2528)
- The `Camera` and `I8080` drivers' constructors now only accepts blocking-mode DMA channels. (#2519)
- Many peripherals are now disabled by default and also get disabled when the driver is dropped (#2544)
- Config: Crate prefixes and configuration keys are now separated by `_CONFIG_` (#2848)
### Fixed
- Fix conflict between `RtcClock::get_xtal_freq` and `Rtc::disable_rom_message_printing` (#2360)
- Fixed an issue where interrupts enabled before `esp_hal::init` were disabled. This issue caused the executor created by `#[esp_hal_embassy::main]` to behave incorrectly in multi-core applications. (#2377)
- Fixed `TWAI::transmit_async`: bus-off state is not reached when CANH and CANL are shorted. (#2421)
- ESP32: added UART-specific workaround for https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32/03-errata-description/esp32/cpu-subsequent-access-halted-when-get-interrupted.html (#2441)
- Fixed some SysTimer race conditions and panics (#2451)
- TWAI: accept all messages by default (#2467)
- I8080: `set_byte_order()` now works correctly in 16-bit mode (#2487)
- ESP32-C6/ESP32-H2: Make higher LEDC frequencies work (#2520)
### Removed
- The `i2s::{I2sWrite, I2sWriteDma, I2sRead, I2sReadDma, I2sWriteDmaAsync, I2sReadDmaAsync}` traits have been removed. (#2316)
- The `ledc::ChannelHW` trait is no longer generic. (#2387)
- The `I2c::new_with_timeout` constructors have been removed (#2361)
- `I2c::new()` no longer takes `frequency` and pins as parameters. (#2477)
- The `spi::master::HalfDuplexReadWrite` trait has been removed. (#2373)
- The `Spi::with_pins` methods have been removed. (#2373)
- The `Spi::new_half_duplex` constructor have been removed. (#2373)
- The `HalfDuplexMode` and `FullDuplexMode` parameters have been removed from `Spi`. (#2373)
- Removed the output pin type parameter from `ledc::{Channel, ChannelIFace}` (#2388)
- Removed the output pin type parameter from `mcpwm::operator::{PwmPin, LinkedPins}` (#2388)
- Removed the output pin type parameter from `parl_io::{ClkOutPin, ClkInPin, RxClkInPin}` (#2388)
- Removed the valid pin type parameter from `parl_io::{TxPinConfigWithValidPin, RxPinConfigWithValidPin}` (#2388)
- Removed the pin type parameters from `parl_io::{TxOneBit, TxTwoBits, TxFourBits, TxEightBits, TxSixteenBits}` (#2388)
- Removed the pin type parameters from `parl_io::{RxOneBit, RxTwoBits, RxFourBits, RxEightBits, RxSixteenBits}` (#2388)
- Removed the pin type parameters from `lcd_cam::lcd::i8080::{TxEightBits, TxSixteenBits}` (#2388)
- Removed the pin type parameters from `lcd_cam::cam::{RxEightBits, RxSixteenBits}` (#2388)
- Most of the async-specific constructors (`new_async`, `new_async_no_transceiver`) have been removed. (#2430)
- The `configure_for_async` DMA functions have been removed (#2430)
- The `Uart::{change_baud, change_stop_bits}` functions have been removed (#2449)
- `gpio::{Input, Output, OutputOpenDrain, Flex, GpioPin}::{peripheral_input, into_peripheral_output}` have been removed. (#2418)
- The `GpioEtm` prefix has been removed from `gpio::etm` types (#2427)
- The `TimerEtm` prefix has been removed from `timer::timg::etm` types (#2427)
- The `SysTimerEtm` prefix has been removed from `timer::systimer::etm` types (#2427)
- The `GpioEtmEventRising`, `GpioEtmEventFalling`, `GpioEtmEventAny` types have been replaced with `Event` (#2427)
- The `TaskSet`, `TaskClear`, `TaskToggle` types have been replaced with `Task` (#2427)
- `{Spi, SpiDma, SpiDmaBus}` configuration methods (#2448)
- `Io::new_with_priority` and `Io::new_no_bind_interrupt`. (#2486)
- `parl_io::{no_clk_pin(), NoClkPin}` (#2531)
- Removed `get_core` function in favour of `Cpu::current` (#2533)
- Removed `uart::Config` setters and `symbol_length`. (#2847)
## [0.21.1]
### Fixed
- Restored blocking `embedded_hal` compatibility for async I2C driver (#2343)
- I2c::transaction is now able to transmit data of arbitrary length (#2481)
## [0.21.0]
### Added
- Introduce traits for the DMA buffer objects (#1976, #2213)
- Implement `embedded-hal` output pin traits for `NoPin` (#2019, #2133)
- Added `esp_hal::init` to simplify HAL initialisation (#1970, #1999)
- Added GpioPin::degrade to create ErasePins easily. Same for AnyPin by accident. (#2075)
- Added missing functions to `Flex`: `unlisten`, `is_interrupt_set`, `wakeup_enable`, `wait_for_high`, `wait_for_low`, `wait_for_rising_edge`, `wait_for_falling_edge`, `wait_for_any_edge`. (#2075)
- `Flex` now implements `Wait`. (#2075)
- Added sleep and wakeup support for esp32c2 (#1922)
- `Input`, `Output`, `OutputOpenDrain` and `Flex` now implement `Peripheral`. (#2094)
- Previously unavailable memory is available via `.dram2_uninit` section (#2079)
- You can now use `Input`, `Output`, `OutputOpenDrain` and `Flex` pins as EXTI and RTCIO wakeup sources (#2095)
- Added `Rtc::set_current_time` to allow setting RTC time, and `Rtc::current_time` to getting RTC time while taking into account boot time (#1883)
- Added APIs to allow connecting signals through the GPIO matrix. (#2128)
- Allow I8080 transfers to be cancelled on the spot (#2191)
- Implement `TryFrom<u32>` for `ledc::timer::config::Duty` (#1984)
- Expose `RtcClock::get_xtal_freq` and `RtcClock::get_slow_freq` publically for all chips (#2183)
- TWAI support for ESP32-H2 (#2199)
- Make `DmaDescriptor` methods public (#2237)
- Added a way to configure watchdogs in `esp_hal::init` (#2180)
- Introduce `DmaRxStreamBuf` (#2242)
- Implement `embedded_hal_async::delay::DelayNs` for `TIMGx` timers (#2084)
- Added `Efuse::read_bit` (#2259)
- Limited SPI slave support for ESP32 (Modes 1 and 3 only) (#2278)
- Added `Rtc::disable_rom_message_printing` (S3 and H2 only) (#2280)
- Added `esp_hal::time::{Duration, Instant}` (#2304)
### Changed
- Make saving and restoring SHA digest state an explicit operation (#2049)
- Reordered RX-TX pairs in all APIs to be consistent (#2074)
- Make saving and restoring SHA digest state an explicit operation (#2049)
- `Delay::new()` is now a `const` function (#1999)
- `Input`, `Output`, `OutputOpenDrain` and `Flex` are now type-erased by default. Use the new `new_typed` constructor to keep using the ZST pin types. (#2075)
- To avoid confusion with the `Rtc::current_time` wall clock time APIs, we've renamed `esp_hal::time::current_time` to `esp_hal::time::now`. (#2091)
- Renamed `touch::Continous` to `touch::Continuous`. (#2094)
- Faster SHA (#2112)
- The (previously undocumented) `ErasedPin` enum has been replaced with the `ErasedPin` struct. (#2094)
- Renamed and merged `Rtc::get_time_us` and `Rtc::get_time_ms` into `Rtc::time_since_boot` (#1883)
- ESP32: Added support for touch sensing on GPIO32 and 33 (#2109)
- Removed gpio pin generics from I8080 driver type. (#2171)
- I8080 driver now decides bus width at transfer time rather than construction time. (#2171)
- Migrate the I8080 driver to a move based API (#2191)
- Replaced `AnyPin` with `InputSignal` and `OutputSignal` and renamed `ErasedPin` to `AnyPin` (#2128)
- Replaced the `ErasedTimer` enum with the `AnyTimer` struct. (#2144)
- `Camera` and `AesDma` now support erasing the DMA channel type (#2258)
- Changed the parameters of `Spi::with_pins` to no longer be optional (#2133)
- Renamed `DummyPin` to `NoPin` and removed all internal logic from it. (#2133)
- The `NO_PIN` constant has been removed. (#2133)
- MSRV bump to 1.79 (#2156)
- Allow handling interrupts while trying to lock critical section on multi-core chips. (#2197)
- Migrate `Camera` to a move based API (#2242).
- Removed the PS-RAM related features, replaced by `quad-psram`/`octal-psram`, `init_psram` takes a configuration parameter, it's now possible to auto-detect PS-RAM size (#2178)
- `EspTwaiFrame` constructors now accept any type that converts into `esp_hal::twai::Id` (#2207)
- Change `DmaTxBuf` to support PSRAM on `esp32s3` (#2161)
- I2c `transaction` is now also available as a inherent function, lift size limit on `write`,`read` and `write_read` (#2262)
- SPI transactions are now cancelled if the transfer object (or async Future) is dropped. (#2216)
- The DMA channel types have been removed from peripherals (#2261)
- `I2C` driver renamed to `I2c` (#2320)
- The GPIO pins are now accessible via `Peripherals` and are no longer part of the `Io` struct (#2508)
- `dma::{ChannelRx, ChannelTx}` now have a `Mode` type parameter (#2519)
### Fixed
- SHA driver can now be safely used in multiple contexts concurrently (#2049)
- Fixed an issue with DMA transfers potentially not waking up the correct async task (#2065)
- Fixed an issue with LCD_CAM i8080 where it would send double the clocks in 16bit mode (#2085)
- Fix i2c embedded-hal transaction (#2028)
- Fix some inconsistencies in DMA interrupt bits (#2169)
- Fix SPI DMA alternating `write` and `read` for ESP32 and ESP32-S2 (#2131)
- Fix I2C ending up in a state when only re-creating the peripheral makes it useable again (#2141)
- Fix `SpiBus::transfer` transferring data twice in some cases (#2159)
- Fixed UART freezing when using `RcFast` clock source on ESP32-C2/C3 (#2170)
- I2S: on ESP32 and ESP32-S2 data is now output to the right (WS=1) channel first. (#2194)
- SPI: Fixed an issue where unexpected data was written outside of the read buffer (#2179)
- SPI: Fixed an issue where `wait` has returned before the DMA has finished writing the memory (#2179)
- SPI: Fixed an issue where repeated calls to `dma_transfer` may end up looping indefinitely (#2179)
- SPI: Fixed an issue that prevented correctly reading the first byte in a transaction (#2179)
- SPI: ESP32: Send address with correct data mode even when no data is sent. (#2231)
- SPI: ESP32: Allow using QSPI mode on SPI3. (#2245)
- PARL_IO: Fixed an issue that caused garbage to be output at the start of some requests (#2211)
- TWAI on ESP32 (#2207)
- TWAI should no longer panic when receiving a non-compliant frame (#2255)
- OneShotTimer: fixed `delay_nanos` behaviour (#2256)
- Fixed unsoundness around `Efuse` (#2259)
- Empty I2C writes to unknown addresses now correctly fail with `AckCheckFailed`. (#2506)
### Removed
- Removed `digest::Digest` implementation from SHA (#2049)
- Removed `NoPinType` in favour of `DummyPin`. (#2068)
- Removed the `async`, `embedded-hal-02`, `embedded-hal`, `embedded-io`, `embedded-io-async`, and `ufmt` features (#2070)
- Removed the `GpioN` type aliasses. Use `GpioPin<N>` instead. (#2073)
- Removed `Peripherals::take`. Use `esp_hal::init` to obtain `Peripherals` (#1999)
- Removed `AnyInputOnlyPin` in favour of `AnyPin`. (#2071)
- Removed the following functions from `GpioPin`: `is_high`, `is_low`, `set_high`, `set_low`, `set_state`, `is_set_high`, `is_set_low`, `toggle`. (#2094)
- Removed `Rtc::get_time_raw` (#1883)
- Removed `_with_default_pins` UART constructors (#2132)
- Removed transfer methods `send`, `send_dma` and `send_dma_async` from `I8080` (#2191)
- Removed `uart::{DefaultRxPin, DefaultTxPin}` (#2132)
- Removed `PcntSource` and `PcntInputConfig`. (#2134)
- Removed the `place-spi-driver-in-ram` feature, this is now enabled via [esp-config](https://docs.rs/esp-config) (#2156)
- Removed `esp_hal::spi::slave::prelude` (#2260)
- Removed `esp_hal::spi::slave::WithDmaSpiN` traits (#2260)
- The `WithDmaAes` trait has been removed (#2261)
- The `I2s::new_i2s1` constructor has been removed (#2261)
- `Peripherals.GPIO` has been removed (#2508)
## [0.20.1] - 2024-08-30
### Fixed
- A build issue when including doc comment prelude (#2040)
## [0.20.0] - 2024-08-29
### Added
- Introduce DMA buffer objects (#1856, #1985)
- Added new `Io::new_no_bind_interrupt` constructor (#1861)
- Added touch pad support for esp32 (#1873, #1956)
- Allow configuration of period updating method for MCPWM timers (#1898)
- Add self-testing mode for TWAI peripheral. (#1929)
- Added a `PeripheralClockControl::reset` to the driver constructors where missing (#1893)
- Added `digest::Digest` implementation to SHA (#1908)
- Added `debugger::debugger_connected`. (#1961)
- DMA: don't require `Sealed` to implement `ReadBuffer` and `WriteBuffer` (#1921)
- Allow DMA to/from psram for esp32s3 (#1827)
- Added missing methods to `SpiDmaBus` (#2016).
- PARL_IO use ReadBuffer and WriteBuffer for Async DMA (#1996)
### Changed
- Peripheral driver constructors don't take `InterruptHandler`s anymore. Use `set_interrupt_handler` to explicitly set the interrupt handler now. (#1819)
- Migrate SPI driver to use DMA buffer objects (#1856, #1985)
- Use the peripheral ref pattern for `OneShotTimer` and `PeriodicTimer` (#1855)
- Improve SYSTIMER API (#1871)
- SHA driver now use specific structs for the hashing algorithm instead of a parameter. (#1908)
- Remove `fn free(self)` in HMAC which goes against esp-hal API guidelines (#1972)
- `AnyPin`, `AnyInputOnyPin` and `DummyPin` are now accessible from `gpio` module (#1918)
- Changed the RSA modular multiplication API to be consistent across devices (#2002)
### Fixed
- Improve error detection in the I2C driver (#1847)
- Fix I2S async-tx (#1833)
- Fix PARL_IO async-rx (#1851)
- SPI: Clear DMA interrupts before (not after) DMA starts (#1859)
- SPI: disable and re-enable MISO and MOSI in `start_transfer_dma`, `start_read_bytes_dma` and `start_write_bytes_dma` accordingly (#1894)
- TWAI: GPIO pins are not configured as input and output (#1906)
- ESP32C6: Make ADC usable after TRNG deinicialization (#1945)
- We should no longer generate 1GB .elf files for ESP32C2 and ESP32C3 (#1962)
- Reset peripherals in driver constructors where missing (#1893, #1961)
- Fixed ESP32-S2 systimer interrupts (#1979)
- Software interrupt 3 is no longer available when it is required by `esp-hal-embassy`. (#2011)
- ESP32: Fixed async RSA (#2002)
### Removed
- This package no longer re-exports the `esp_hal_procmacros::main` macro (#1828)
- The `AesFlavour` trait no longer has the `ENCRYPT_MODE`/`DECRYPT_MODE` associated constants (#1849)
- Removed `FlashSafeDma` (#1856)
- Remove redundant WithDmaSpi traits (#1975)
- `IsFullDuplex` and `IsHalfDuplex` traits (#1985)
## [0.19.0] - 2024-07-15
### Added
- uart: Added `with_cts`/`with_rts`s methods to configure CTS, and RTS pins (#1592)
- uart: Constructors now require TX and RX pins (#1592)
- uart: Added `Uart::new_with_default_pins` constructor (#1592)
- uart: Added `UartTx` and `UartRx` constructors (#1592)
- Add Flex / AnyFlex GPIO pin driver (#1659)
- Add new `DmaError::UnsupportedMemoryRegion` - used memory regions are checked when preparing a transfer now (#1670)
- Add DmaTransactionTxOwned, DmaTransactionRxOwned, DmaTransactionTxRxOwned, functions to do owning transfers added to SPI half-duplex (#1672)
- uart: Implement `embedded_io::ReadReady` for `Uart` and `UartRx` (#1702)
- ESP32-S3: Expose optional HSYNC input in LCD_CAM (#1707)
- ESP32-S3: Add async support to the LCD_CAM I8080 driver (#1834)
- ESP32-C6: Support lp-core as wake-up source (#1723)
- Add support for GPIO wake-up source (#1724)
- gpio: add DummyPin (#1769)
- dma: add Mem2Mem to support memory to memory transfer (#1738)
- Add `uart` wake source (#1727)
- `#[ram(persistent)]` option to replace the unsound `uninitialized` option (#1677)
- uart: Make `rx_timeout` optional in Config struct (#1759)
- Add interrupt related functions to `PeriodicTimer`/`OneShotTimer`, added `ErasedTimer` (#1753)
- Added blocking `read_bytes` method to `Uart` and `UartRx` (#1784)
- Add method to expose `InputPin::is_interrupt_set` in `Input<InputPin>` for use in interrupt handlers (#1829)
### Fixed
- ESP32-S3: Fix DMA waiting check in LCD_CAM (#1707)
- TIMG: Fix interrupt handler setup (#1714)
- Fix `sleep_light` for ESP32-C6 (#1720)
- ROM Functions: Fix address of `ets_update_cpu_frequency_rom` (#1722)
- Fix `regi2c_*` functions for `esp32h2` (#1737)
- Improved `#[ram(zeroed)]` soundness by adding a `bytemuck::Zeroable` type bound (#1677)
- EESP32-S2 / ESP32-S3: Fix UsbDm and UsbDp for Gpio19 and Gpio20
- Fix reading/writing small buffers via SPI master async dma (#1760)
- Remove unnecessary delay in rtc_ctnl (#1794)
### Changed
- Refactor `Dac1`/`Dac2` drivers into a single `Dac` driver (#1661)
- esp-hal-embassy: make executor code optional (but default) again
- Improved interrupt latency on RISC-V based chips (#1679)
- `esp_wifi::initialize` no longer requires running maximum CPU clock, instead check it runs above 80MHz. (#1688)
- Move DMA descriptors from DMA Channel to each individual peripheral driver. (#1719)
- Allow users to easily name DMA channels (#1770)
- Support DMA chunk sizes other than the default 4092 (#1758)
- Improved interrupt latency on Xtensa based chips (#1735)
- Improve PCNT api (#1765)
### Removed
- uart: Removed `configure_pins` methods (#1592)
- Removed `DmaError::Exhausted` error by improving the implementation of the `pop` function (#1664)
- Unsound `#[ram(uninitialized)]` option in favor of the new `persistent` option (#1677)
## [0.18.0] - 2024-06-04
### Added
@ -17,6 +487,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `embassy-usb` support (#1517)
- SPI Slave support for ESP32-S2 (#1562)
- Add new generic `OneShotTimer` and `PeriodicTimer` drivers, plus new `Timer` trait which is implemented for `TIMGx` and `SYSTIMER` (#1570)
- Feature: correct `TRNG` mechanism #1804
### Fixed
@ -186,6 +657,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Auto detect crystal frequency based on `RtcClock::estimate_xtal_frequency()` (#1165)
- ESP32-S3: Configure 32k ICACHE (#1169)
- Lift the minimal buffer size requirement for I2S (#1189)
- Replaced `SystemTimer::TICKS_PER_SEC` with `SystemTimer::ticks_per_sec()` (#1981)
### Removed
@ -580,6 +1052,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.1.0] - 2022-08-05
[Unreleased]: https://github.com/esp-rs/esp-hal/compare/v0.22.0...HEAD
[0.22.0]: https://github.com/esp-rs/esp-hal/compare/v0.21.1...v0.22.0
[0.21.1]: https://github.com/esp-rs/esp-hal/compare/v0.21.0...v0.21.1
[0.21.0]: https://github.com/esp-rs/esp-hal/compare/v0.20.1...v0.21.0
[0.20.1]: https://github.com/esp-rs/esp-hal/compare/v0.20.0...v0.20.1
[0.20.0]: https://github.com/esp-rs/esp-hal/compare/v0.19.0...v0.20.0
[0.19.0]: https://github.com/esp-rs/esp-hal/compare/v0.18.0...v0.19.0
[0.18.0]: https://github.com/esp-rs/esp-hal/compare/v0.17.0...v0.18.0
[0.17.0]: https://github.com/esp-rs/esp-hal/compare/v0.16.1...v0.17.0
[0.16.1]: https://github.com/esp-rs/esp-hal/compare/v0.16.0...v0.16.1

View File

@ -1,88 +1,96 @@
[package]
name = "esp-hal"
version = "0.18.0"
version = "0.22.0"
edition = "2021"
rust-version = "1.76.0"
rust-version = "1.83.0"
description = "Bare-metal HAL for Espressif devices"
documentation = "https://docs.esp-rs.org/esp-hal/"
keywords = ["embedded", "embedded-hal", "esp32", "espressif", "hal"]
categories = ["embedded", "hardware-support", "no-std"]
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
links = "esp-hal"
[package.metadata.docs.rs]
default-target = "riscv32imac-unknown-none-elf"
features = ["embedded-hal", "esp32c6"]
features = ["esp32c6"]
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
bitflags = "2.5.0"
bitfield = "0.15.0"
bitflags = "2.6.0"
bytemuck = "1.19.0"
bitfield = "0.17.0"
cfg-if = "1.0.0"
critical-section = "1.1.2"
chrono = { version = "0.4.38", default-features = false }
critical-section = "1.2.0"
defmt = { version = "0.3.8", optional = true }
delegate = "0.12.0"
document-features = "0.2.8"
embassy-futures = { version = "0.1.1", optional = true }
embassy-sync = { version = "0.6.0", optional = true }
delegate = "0.13.1"
digest = { version = "0.10.7", default-features = false, optional = true }
document-features = "0.2.10"
embassy-embedded-hal = { version = "0.2.0", optional = true }
embassy-futures = "0.1.1"
embassy-sync = "0.6.1"
embassy-usb-driver = { version = "0.1.0", optional = true }
embassy-usb-synopsys-otg = { version = "0.1.0", optional = true }
embassy-usb-synopsys-otg = { version = "0.2.0", optional = true }
embedded-can = { version = "0.4.1", optional = true }
embedded-dma = "0.2.0"
embedded-hal-02 = { version = "0.2.7", optional = true, features = ["unproven"], package = "embedded-hal" }
embedded-hal = { version = "1.0.0", optional = true }
embedded-hal-async = { version = "1.0.0", optional = true }
embedded-hal-nb = { version = "1.0.0", optional = true }
embedded-hal = "1.0.0"
embedded-hal-async = "1.0.0"
embedded-hal-nb = "1.0.0"
embedded-io = { version = "0.6.1", optional = true }
embedded-io-async = { version = "0.6.1", optional = true }
enumset = "1.1.3"
esp-synopsys-usb-otg = { version = "0.4.1", optional = true, features = ["fs", "esp32sx"] }
enumset = "1.1.5"
esp-build = { version = "0.1.0", path = "../esp-build" }
esp-synopsys-usb-otg = { version = "0.4.2", optional = true, features = ["fs", "esp32sx"] }
fugit = "0.3.7"
log = { version = "0.4.21", optional = true }
instability = "0.3.6"
log = { version = "0.4.22", optional = true }
nb = "1.1.0"
paste = "1.0.15"
portable-atomic = { version = "1.6.0", default-features = false }
procmacros = { version = "0.11.0", features = ["embassy", "enum-dispatch", "interrupt", "ram"], package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
riscv = { version = "0.11.1", optional = true }
strum = { version = "0.26.2", default-features = false, features = ["derive"] }
portable-atomic = { version = "1.9.0", default-features = false }
procmacros = { version = "0.15.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
strum = { version = "0.26.3", default-features = false, features = ["derive"] }
void = { version = "1.0.2", default-features = false }
usb-device = { version = "0.3.2", optional = true }
rand_core = "0.6.4"
ufmt-write = { version = "0.1.0", optional = true }
xtensa-lx = { version = "0.9.0", optional = true }
ufmt-write = "0.1.0"
# IMPORTANT:
# Each supported device MUST have its PAC included below along with a
# corresponding feature.
esp32 = { version = "0.31.0", features = ["critical-section", "rt"], optional = true }
esp32c2 = { version = "0.20.0", features = ["critical-section", "rt"], optional = true }
esp32c3 = { version = "0.23.0", features = ["critical-section", "rt"], optional = true }
esp32c6 = { version = "0.14.0", features = ["critical-section", "rt"], optional = true }
esp32h2 = { version = "0.10.0", features = ["critical-section", "rt"], optional = true }
esp32s2 = { version = "0.22.0", features = ["critical-section", "rt"], optional = true }
esp32s3 = { version = "0.26.0", features = ["critical-section", "rt"], optional = true }
esp32 = { version = "0.34.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "ffbee35069d137ef611097d39fa7734c299ce124", optional = true }
esp32c2 = { version = "0.23.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "ffbee35069d137ef611097d39fa7734c299ce124", optional = true }
esp32c3 = { version = "0.26.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "ffbee35069d137ef611097d39fa7734c299ce124", optional = true }
esp32c6 = { version = "0.17.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "ffbee35069d137ef611097d39fa7734c299ce124", optional = true }
esp32h2 = { version = "0.13.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "ffbee35069d137ef611097d39fa7734c299ce124", optional = true }
esp32s2 = { version = "0.25.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "ffbee35069d137ef611097d39fa7734c299ce124", optional = true }
esp32s3 = { version = "0.29.0", features = ["critical-section", "rt"], git = "https://github.com/esp-rs/esp-pacs", rev = "ffbee35069d137ef611097d39fa7734c299ce124", optional = true }
[target.'cfg(target_arch = "riscv32")'.dependencies]
esp-riscv-rt = { version = "0.8.0", path = "../esp-riscv-rt" }
riscv = { version = "0.12.1" }
esp-riscv-rt = { version = "0.9.1", path = "../esp-riscv-rt" }
critical-section = { version = "1.2.0", features = ["restore-state-u8"] }
[target.'cfg(target_arch = "xtensa")'.dependencies]
xtensa-lx-rt = "0.16.0"
xtensa-lx = { version = "0.9.0", path = "../xtensa-lx" }
xtensa-lx-rt = { version = "0.17.2", path = "../xtensa-lx-rt" }
critical-section = { version = "1.2.0", features = ["restore-state-u32"] }
[build-dependencies]
basic-toml = "0.1.9"
cfg-if = "1.0.0"
esp-build = { version = "0.1.0", path = "../esp-build" }
esp-metadata = { version = "0.1.1", path = "../esp-metadata" }
serde = { version = "1.0.203", features = ["derive"] }
esp-metadata = { version = "0.4.0", path = "../esp-metadata" }
esp-config = { version = "0.2.0", path = "../esp-config", features = ["build"] }
serde = { version = "1.0.215", features = ["derive"] }
[features]
default = ["embedded-hal"]
riscv = ["dep:riscv", "critical-section/restore-state-u8", "esp-riscv-rt/zero-bss"]
xtensa = ["dep:xtensa-lx", "critical-section/restore-state-u32"]
default = []
bluetooth = []
usb-otg = ["esp-synopsys-usb-otg", "usb-device"]
usb-otg = ["dep:embassy-usb-driver", "dep:embassy-usb-synopsys-otg", "dep:esp-synopsys-usb-otg", "dep:usb-device"]
__esp_hal_embassy = []
## Enable debug features in the HAL (used for development).
debug = [
@ -96,58 +104,37 @@ debug = [
]
## Enable logging output using the `log` crate.
log = ["dep:log"]
## Configuration for placing device drivers in the IRAM for faster access.
place-spi-driver-in-ram = []
# Chip Support Feature Flags
# Target the ESP32.
esp32 = ["dep:esp32", "xtensa", "xtensa-lx/spin", "xtensa-lx-rt/esp32"]
esp32 = ["dep:esp32", "procmacros/rtc-slow", "xtensa-lx-rt/esp32"]
# Target the ESP32-C2.
esp32c2 = ["dep:esp32c2", "riscv", "portable-atomic/unsafe-assume-single-core"]
esp32c2 = ["dep:esp32c2", "portable-atomic/unsafe-assume-single-core"]
# Target the ESP32-C3.
esp32c3 = ["dep:esp32c3", "riscv", "portable-atomic/unsafe-assume-single-core", "rv-zero-rtc-bss"]
esp32c3 = ["dep:esp32c3", "esp-riscv-rt/rtc-ram", "portable-atomic/unsafe-assume-single-core"]
# Target the ESP32-C6.
esp32c6 = ["dep:esp32c6", "riscv", "procmacros/has-lp-core", "rv-zero-rtc-bss"]
esp32c6 = ["dep:esp32c6", "esp-riscv-rt/rtc-ram", "procmacros/has-lp-core"]
# Target the ESP32-H2.
esp32h2 = ["dep:esp32h2", "riscv", "rv-zero-rtc-bss"]
esp32h2 = ["dep:esp32h2", "esp-riscv-rt/rtc-ram"]
# Target the ESP32-S2.
esp32s2 = ["dep:esp32s2", "xtensa", "portable-atomic/critical-section", "procmacros/has-ulp-core", "xtensa-lx-rt/esp32s2", "usb-otg"]
esp32s2 = ["dep:esp32s2", "portable-atomic/critical-section", "procmacros/has-ulp-core", "procmacros/rtc-slow", "usb-otg", "xtensa-lx-rt/esp32s2"]
# Target the ESP32-S3.
esp32s3 = ["dep:esp32s3", "xtensa", "procmacros/has-ulp-core", "xtensa-lx/spin", "xtensa-lx-rt/esp32s3", "usb-otg"]
esp32s3 = ["dep:esp32s3", "procmacros/has-ulp-core", "procmacros/rtc-slow", "usb-otg", "xtensa-lx-rt/esp32s3"]
#! ### RISC-V Exclusive Feature Flags
## Move the stack to start of RAM to get zero-cost stack overflow protection
## (ESP32-C6 and ESPS32-H2 only!).
flip-link = ["esp-riscv-rt/fix-sp"]
## Initialize the `.data` section of memory.
rv-init-data = ["esp-riscv-rt/init-data", "esp-riscv-rt/init-rw-text"]
## Zero the `.bss` section of low-power memory.
rv-zero-rtc-bss = ["esp-riscv-rt/zero-rtc-fast-bss"]
## Initialize the `.data` section of low-power memory.
rv-init-rtc-data = ["esp-riscv-rt/init-rtc-fast-data", "esp-riscv-rt/init-rtc-fast-text"]
#! ### Trait Implementation Feature Flags
## Enable support for asynchronous operation, with interfaces provided by
## `embedded-hal-async` and `embedded-io-async`.
## Also enables `embassy-usb` support for ESP32-S2 and ESP32-S3.
async = [
"embedded-hal",
"embedded-hal-async",
"embedded-io",
"embedded-io-async",
"embassy-sync",
"embassy-futures",
"embassy-usb-driver",
"embassy-usb-synopsys-otg"
]
## Implement `defmt::Format` on certain types.
defmt = [
"dep:defmt",
"embassy-futures?/defmt",
"embassy-sync?/defmt",
"embedded-hal?/defmt-03",
"embassy-futures/defmt",
"embassy-sync/defmt",
"embedded-hal/defmt-03",
"embedded-io/defmt-03",
"embedded-io-async?/defmt-03",
"embedded-io-async/defmt-03",
"esp32?/defmt",
"esp32c2?/defmt",
"esp32c3?/defmt",
@ -155,42 +142,34 @@ defmt = [
"esp32h2?/defmt",
"esp32s2?/defmt",
"esp32s3?/defmt",
"fugit/defmt",
]
## Implement the traits defined in the `1.0.0` releases of `embedded-hal` and
## `embedded-hal-nb` for the relevant peripherals.
embedded-hal = ["dep:embedded-hal", "dep:embedded-hal-nb", "dep:embedded-can"]
## Implement the traits defined in the `0.2.x` release of `embedded-hal`.
embedded-hal-02 = ["dep:embedded-hal-02"]
## Implement the traits defined in `embedded-io` for certain peripherals.
embedded-io = ["dep:embedded-io"]
## Implement the `ufmt_write::uWrite` trait for certain peripherals.
ufmt = ["dep:ufmt-write"]
#! ### PSRAM Feature Flags
## Use externally connected PSRAM (2MB).
psram-2m = []
## Use externally connected PSRAM (4MB).
psram-4m = []
## Use externally connected PSRAM (8MB).
psram-8m = []
## PSRAM 80Mhz frequency support
psram-80mhz = []
## Use externally connected Quad PSRAM
quad-psram = []
#! ### Octal RAM Feature Flags
## Use externally connected Octal RAM (2MB).
opsram-2m = []
## Use externally connected Octal RAM (4MB).
opsram-4m = []
## Use externally connected Octal RAM (8MB).
opsram-8m = []
## Use externally connected Octal RAM (16MB).
opsram-16m = []
## Use externally connected Octal RAM
octal-psram = []
# This feature is intended for testing; you probably don't want to enable it:
ci = ["async", "embedded-hal-02", "embedded-io", "ufmt"]
ci = ["defmt", "bluetooth"]
#! ### Unstable APIs
#! Unstable APIs are drivers and features that are not yet ready for general use.
#! They may be incomplete, have bugs, or be subject to change without notice.
#! Unstable APIs are not covered by semver guarantees.
## Enables APIs that are not stable and thus come with no stability guarantees.
unstable = [
"dep:embassy-embedded-hal",
"dep:embedded-can",
"dep:embedded-io",
"dep:embedded-io-async",
]
[lints.clippy]
mixed_attributes_style = "allow"
[lints.rust]
unexpected_cfgs = "allow"
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(host_os, values("windows"))'] }

349
esp-hal/MIGRATING-0.20.md Normal file
View File

@ -0,0 +1,349 @@
# Migration Guide from 0.20.x to v0.21.x
## Cargo Features
A number of trait implementations which were previously feature-gated are now implemented by default. The following Cargo features have been removed:
- `async`
- `embedded-hal-02`
- `embedded-hal`
- `embedded-io`
- `embedded-io-async`
- `ufmt`
If your project enables any of these features, simply remove them from your Cargo manifest and things should continue to work as expected.
## HAL Initialization
Instead of manually grabbing peripherals and setting up clocks, you should now call `esp_hal::init`.
```diff
use esp_hal::{
- clock::ClockControl,
- peripherals::Peripherals,
prelude::*,
- system::SystemControl,
};
#[entry]
fn main() -> ! {
- let peripherals = Peripherals::take();
- let system = SystemControl::new(peripherals.SYSTEM);
- let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
+ let peripherals = esp_hal::init(esp_hal::Config::default());
// ...
}
```
## GPIO changes
- The `GpioN` type aliasses are no longer available. You can use `GpioPin<N>` instead.
- The `AnyInputOnlyPin` has been removed. Replace any use with `AnyPin`.
- The `NoPinType` has been removed. You can use `DummyPin` in its place.
### Type-erased GPIO drivers
The `AnyInput`, `AnyOutput`, `AnyOutputOpenDrain` and `AnyFlex` structures have been removed.
Instead, you can use the non-`Any` counterparts. By default, the structures will use `AnyPin` in
their type names, which you don't have to specify.
```diff
-let pin = AnyInput::new(io.gpio0, Pull::Up);
+let pin = Input::new(io.gpio0, Pull::Up); // pin will have the type `Input<'some>` (or `Input<'some, AnyPin>` if you want to be explicit about it)
```
You can use `new_typed` if you want to keep using the typed form:
```rust
let pin = Input::new_typed(io.gpio0, Pull::Up); // pin will have the type `Input<'some, GpioPin<0>>`
```
### Creating an `AnyPin`
Instead of `AnyPin::new`, you can now use the `Pin` trait's `degrade` method to obtain an `AnyPin`.
You can now create an `AnyPin` out of input only pins (like ESP32's IO34), but trying to use such
pins as output (or, generally, trying to use pins in ways they don't support) will panic.
```diff
+ use esp_hal::gpio::Pin;
-let pin = AnyPin::new(io.gpio0);
+let pin = io.gpio0.degrade();
```
### Wakeup using pin drivers
You can now use pin drivers as wakeup sources.
```rust
use esp_hal::peripheral::Peripheral; // needed for `into_ref`
let pin2 = Input::new(io.pins.gpio2, Pull::None);
let mut pin3 = Input::new(io.pins.gpio3, Pull::None);
// ... use pin2 as an input ..
// Ext0
let ext0 = Ext0WakeupSource::new(pin2, WakeupLevel::High);
// Ext1
let mut wakeup_pins: [&mut dyn RtcPin; 2] = [
&mut *pin_0.into_ref(),
&mut io.pins.gpio4, // unconfigured pins continue to work, too!
];
let ext1 = Ext1WakeupSource::new(&mut wakeup_pins, WakeupLevel::High);
```
## RX/TX Order
Previously, our API was pretty inconsistent with the RX/TX ordering, and different peripherals had different order. Now, all
the peripherals use rx-tx. Make sure your methods are expecting the right RX/TX order, for example an SPI DMA app should be updated to:
```diff
- let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4);
+ let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(4);
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
...
let transfer = spi
- .dma_transfer(dma_tx_buf, dma_rx_buf)
+ .dma_transfer(dma_rx_buf, dma_tx_buf)
.map_err(|e| e.0)
.unwrap();
```
When using the asymmetric variant of the macro to create DMA buffers and descriptors make sure to swap the order of parameters
```diff
- let (tx_buffer, tx_descriptors, _, _) = dma_buffers!(32000, 0);
+ let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, 32000);
```
## Removed constructors
### UART
The `Uart::new_with_default_pins` and `Uart::new_async_with_default_pins` constructors
have been removed. Use `new` or `new_async` instead.
### I2S1
The `I2s::new_i2s1` constructor has been removed. Use `I2s::new` instead.
## Timer changes
### `ErasedTimer` rename
The `ErasedTimer` has been renamed to `AnyTimer`.
### `esp_hal::time::current_time` rename
To avoid confusion with the `Rtc::current_time` wall clock time APIs, we've renamed `esp_hal::time::current_time` to `esp_hal::time::now()`.
### RTC Wall Clock APIs
Instead of the `get_time_ms`, `get_time_us`, and `get_time_raw` functions, the `Rtc` struct now provides the `current_time` function, using `chrono`'s `NaiveDateTime` struct.
```diff
let rtc = Rtc::new(peripherals.LPWR);
- let current_time_ms = rtc.get_time_ms();
+ let current_time_ms = rtc.current_time().and_utc().timestamp_millis(); // assuming UTC
```
## PCNT input config
The `PcntSource` and `PcntInputConfig` have been removed. You can use `Input` or `Flex` instead to
configure an input pin, and pass it to `set_edge_signal` or `set_ctrl_signal`.
```diff
- let mut pin_a = io.pins.gpio4;
- ch0.set_ctrl_signal(PcntSource::from_pin(
- &mut pin_a,
- PcntInputConfig { pull: Pull::Up },
- ));
+ ch0.set_ctrl_signal(Input::new(io.pins.gpio4, Pull::Up));
- let mut pin_b = io.pins.gpio5;
- ch0.set_edge_signal(PcntSource::from_pin(
- &mut pin_b,
- PcntInputConfig { pull: Pull::Down },
- ));
+ ch0.set_edge_signal(Input::new(io.pins.gpio5, Pull::Down));
```
## SPI pins and `NO_PIN`
Use `NoPin` in place of the now-removed `NO_PIN` constant.
SPI pins, when using the `with_pin` function, are no longer optional.
You can pass `NoPin` or `Level` if you don't need a particular pin.
```diff
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
- .with_pins(Some(sclk), Some(mosi), NO_PIN, NO_PIN);
+ .with_pins(sclk, mosi, Level::Low, NoPin);
```
## I8080 type definition
The I8080 driver no longer holds on to pins in its type definition.
```diff
- let _: I8080<'a, DmaChannel3, TxEightBits<AnyPin, AnyPin, AnyPin, ....>, Blocking>;
+ let _: I8080<'a, DmaChannel3, Blocking>;
```
## I8080 transfer API changes
- The I8080 driver now decides bus width at transfer time, which means you don't get type inference anymore.
- Starting a transfer moves the driver into the transfer object, allowing you to store it in a `static` or struct.
- The transfer API no longer works with plain slices, it now works with `DmaTxBuffer`s which allow to bring your own DMA data structure and implement efficient queueing of transfers.
- The three transfer methods (`send`, `send_dma`, `send_dma_async`) have been merged into one `send` method.
```diff
let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, 32678);
+ let mut dma_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
let mut i8080 = I8080::new(
lcd_cam.lcd,
channel.tx,
- tx_descriptors,
tx_pins,
20.MHz(),
Config::default(),
)
- i8080.send(0x12, 0, &[0, 1, 2, 3, 4]);
+ dma_buf.fill(&[0, 1, 2, 3, 4]);
+ let transfer = i8080.send(0x12u8, 0, dma_buf).unwrap();
+ // transfer.wait_for_done().await;
+ (_, i8080, dma_buf) = transfer.wait();
```
### Placing drivers in RAM is now done via esp-config
We've replaced some usage of features with [esp-config](https://docs.rs/esp-config). Please remove any reference to `place-spi-driver-in-ram` in your `Cargo.toml` and migrate to the `[env]` section of `.cargo/config.toml`.
```diff
# feature in Cargo.toml
- esp-hal = { version = "0.20", features = ["place-spi-driver-in-ram"] }
# key in .cargo/config.toml [env] section
+ ESP_HAL_PLACE_SPI_DRIVER_IN_RAM="true"
```
## `Camera` driver now uses `DmaRxBuffer` and moves the driver into the transfer object.
For one shot transfers.
```diff
let (rx_buffer, rx_descriptors, _, _) = dma_buffers!(32678, 0);
+ let dma_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
let mut camera = Camera::new(
lcd_cam.cam,
channel.rx,
- rx_descriptors,
data_pins,
20u32.MHz(),
);
- let transfer = camera.read_dma(rx_buffer).unwrap();
- transfer.wait();
+ let transfer = camera.receive(dma_buf).unwrap();
+ let (_, camera, buf) = transfer.wait();
```
For circular transfers.
```diff
- let (rx_buffer, rx_descriptors, _, _) = dma_buffers!(32678, 0);
+ let dma_buf = dma_rx_stream_buffer!(32678);
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
let mut camera = Camera::new(
lcd_cam.cam,
channel.rx,
- rx_descriptors,
data_pins,
20u32.MHz(),
);
- let mut transfer = camera.read_dma_circular(rx_buffer).unwrap();
+ let mut transfer = camera.receive(dma_buf).unwrap();
transfer.pop(&mut [.....]);
transfer.pop(&mut [.....]);
transfer.pop(&mut [.....]);
```
## PS-RAM
Initializing PS-RAM now takes a chip specific config and returns start of the mapped memory and the size.
Example
```rust
let (start, size) = psram::init_psram(peripherals.PSRAM, psram::PsramConfig::default());
```
If you don't specify the size of PS-RAM via `PsramConfig::size` the size of PS-RAM is derived from the RAM-chip id (or via probing in case of ESP32).
`psram::psram_vaddr_start()` and `psram::PSRAM_BYTES` are removed.
The features `psram-Xm` and `opsram-Xm` are removed and replaced by `quad-psram`/`octal-psram`.
The feature `psram-80mhz` is removed and replaced by `PsramConfig`
Diff of the `psram_quad.rs` example
```diff
-//% FEATURES: psram-2m
+//% FEATURES: esp-hal/quad-psram
...
-fn init_psram_heap() {
+fn init_psram_heap(start: *mut u8, size: usize) {
unsafe {
esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new(
- psram::psram_vaddr_start() as *mut u8,
- psram::PSRAM_BYTES,
+ start,
+ size,
esp_alloc::MemoryCapability::External.into(),
));
}
...
- psram::init_psram(peripherals.PSRAM);
- init_psram_heap();
+ let (start, size) = psram::init_psram(peripherals.PSRAM, psram::PsramConfig::default());
+ init_psram_heap(start, size);
...
```
## eFuse
Calling `Efuse::read_field_le::<bool>()` no longer compiles. Use `Efuse::read_bit()` instead.
## DMA
The DMA channel types have been removed from peripherals.
A non-exhausitve list demonstrating this change:
```diff
-I2sTx<'static, I2S0, DmaChannel0, Async>
+I2sTx<'static, I2S0, Async>
-SpiDma<'static, esp_hal::peripherals::SPI2, DmaChannel0, HalfDuplexMode, Blocking>
+SpiDma<'static, esp_hal::peripherals::SPI2, HalfDuplexMode, Blocking>
```
## `I2C` driver renamed to `I2c`
To firstly match the naming in `embedded-hal`, but also because types should be `UpperCamelCase`.

471
esp-hal/MIGRATING-0.21.md Normal file
View File

@ -0,0 +1,471 @@
# Migration Guide from 0.21.x to v0.22.x
## IO changes
### GPIO pins are now accessible via `Peripherals`
```diff
let peripherals = esp_hal::init(Default::default());
-let io = Io::new(peripherals.GPIO, peripherals.IOMUX);
-let pin = io.pins.gpio5;
+let pin = peripherals.GPIO5;
```
### `Io` constructor changes
- `new_with_priority` and `new_no_bind_interrupts` have been removed.
Use `set_priority` to configure the GPIO interrupt priority.
We no longer overwrite interrupt handlers set by user code during initialization.
- `new` no longer takes `peripherals.GPIO`
## Removed `async`-specific constructors
The following async-specific constuctors have been removed:
- `configure_for_async` DMA channel constructors
- `TwaiConfiguration::new_async` and `TwaiConfiguration::new_async_no_transceiver`
- `I2c::new_async`
- `LcdCam::new_async`
- `UsbSerialJtag::new_async`
- `Rsa::new_async`
- `Rmt::new_async`
- `Uart::new_async`, `Uart::new_async_with_config`
- `UartRx::new_async`, `UartRx::new_async_with_config`
- `UartTx::new_async`, `UartTx::new_async_with_config`
You can use the blocking counterparts, then call `into_async` on the returned peripheral instead.
```diff
-let mut config = twai::TwaiConfiguration::new_async(
+let mut config = twai::TwaiConfiguration::new(
peripherals.TWAI0,
loopback_pin.peripheral_input(),
loopback_pin,
twai::BaudRate::B1000K,
TwaiMode::SelfTest,
-);
+).into_async();
```
Some drivers were implicitly configured to the asyncness of the DMA channel used to construct them.
This is no longer the case, and the following drivers will always be created in blocking mode:
- `i2s::master::I2s`
- `spi::master::SpiDma` and `spi::master::SpiDmaBus`
## Peripheral types are now optional
You no longer have to specify the peripheral instance in the driver's type for the following
peripherals:
- SPI (both master and slave)
- I2S
- I2C
- TWAI
- UART
```diff
-Spi<'static, SPI2, FullDuplexMode>
+Spi<'static, FullDuplexMode>
-SpiDma<'static, SPI2, HalfDuplexMode, Blocking>
+SpiDma<'static, HalfDuplexMode, Blocking>
-I2sTx<'static, I2S0, Async>
+I2sTx<'static, Async>
```
Note that you may still specify the instance if you need to. To do this, we provide `_typed`
versions of the constructors (for example: `new_typed`, `new_half_duplex_typed`). Please note that
the peripheral instance has been moved to the last generic parameter position.
```rust
let spi: Spi<'static, FullDuplexMode, SPI2> = Spi::new_typed(peripherals.SPI2, 1.MHz(), SpiMode::Mode0);
```
## I2C changes
The I2C master driver and related types have been moved to `esp_hal::i2c::master`.
The `with_timeout` constructors have been removed. `new` and `new_typed` now take a `Config` struct
with the available configuration options.
- The default configuration is now:
- bus frequency: 100 kHz
- timeout: about 10 bus clock cycles
The constructors no longer take pins. Use `with_sda` and `with_scl` instead.
```diff
-use esp_hal::i2c::I2c;
+use esp_hal::i2c::{Config, I2c};
-let i2c = I2c::new_with_timeout(peripherals.I2C0, sda, scl, 100.kHz(), timeout);
+let i2c = I2c::new(
+ peripherals.I2C0,
+ {
+ let mut config = Config::default();
+ config.frequency = 100.kHz();
+ config.timeout = timeout;
+ config
+ },
+)
+.with_sda(sda)
+.with_scl(scl);
```
### The calculation of I2C timeout has changed
Previously, I2C timeouts were counted in increments of I2C peripheral clock cycles. This meant that
the configure value meant different lengths of time depending on the device. With this update, the
I2C configuration now expects the timeout value in number of bus clock cycles, which is consistent
between devices.
ESP32 and ESP32-S2 use an exact number of clock cycles for its timeout. Other MCUs, however, use
the `2^timeout` value internally, and the HAL rounds up the timeout to the next appropriate value.
## Changes to half-duplex SPI
The `HalfDuplexMode` and `FullDuplexMode` type parameters have been removed from SPI master and slave
drivers. It is now possible to execute half-duplex and full-duplex operations on the same SPI bus.
### Driver construction
- The `Spi::new_half_duplex` constructor has been removed. Use `new` (or `new_typed`) instead.
- The `with_pins` methods have been removed. Use the individual `with_*` functions instead.
- The `with_mosi` and `with_miso` functions now take input-output peripheral signals to support half-duplex mode.
```diff
- let mut spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
- .with_pins(sck, mosi, miso, sio2, sio3, cs);
+ let mut spi = Spi::new(peripherals.SPI2) // or new_with_config
+ .with_sck(sck)
+ .with_cs(cs)
+ .with_mosi(mosi)
+ .with_miso(miso)
+ .with_sio2(sio2)
+ .with_sio3(sio3);
```
### Transfer functions
The `Spi<'_, SPI, HalfDuplexMode>::read` and `Spi<'_, SPI, HalfDuplexMode>::write` functions have been replaced by
`half_duplex_read` and `half_duplex_write`.
```diff
let mut data = [0u8; 2];
let transfer = spi
- .read(
+ .half_duplex_read(
SpiDataMode::Single,
Command::Command8(0x90, SpiDataMode::Single),
Address::Address24(0x000000, SpiDataMode::Single),
0,
&mut data,
)
.unwrap();
let transfer = spi
- .write(
+ .half_duplex_write(
SpiDataMode::Quad,
Command::Command8(write as u16, command_data_mode),
Address::Address24(
write as u32 | (write as u32) << 8 | (write as u32) << 16,
SpiDataMode::Quad,
),
0,
dma_tx_buf,
)
.unwrap();
```
## Slave-mode SPI
### Driver construction
The constructors no longer accept pins. Use the `with_pin_name` setters instead.
```diff
let mut spi = Spi::new(
peripherals.SPI2,
- sclk,
- mosi,
- miso,
- cs,
SpiMode::Mode0,
-);
+)
+.with_sclk(sclk)
+.with_mosi(mosi)
+.with_miso(miso)
+.with_cs(cs);
```
## UART event listening
The following functions have been removed:
- `listen_at_cmd`
- `unlisten_at_cmd`
- `listen_tx_done`
- `unlisten_tx_done`
- `listen_rx_fifo_full`
- `unlisten_rx_fifo_full`
- `at_cmd_interrupt_set`
- `tx_done_interrupt_set`
- `rx_fifo_full_interrupt_set`
- `reset_at_cmd_interrupt`
- `reset_tx_done_interrupt`
- `reset_rx_fifo_full_interrupt`
You can now use the `UartInterrupt` enum and the corresponding `listen`, `unlisten`, `interrupts` and `clear_interrupts` functions.
Use `interrupts` in place of `<INTERRUPT>_interrupt_set` and `clear_interrupts` in place of the old `reset_` functions.
`UartInterrupt`:
- `AtCmd`
- `TxDone`
- `RxFifoFull`
Checking interrupt bits is now done using APIs provided by [enumset](https://docs.rs/enumset/1.1.5/enumset/index.html). For example, to see if
a particular interrupt bit is set, use `contains`:
```diff
-serial.at_cmd_interrupt_set()
+serial.interupts().contains(UartInterrupt::AtCmd)
```
You can now listen/unlisten multiple interrupt bits at once:
```diff
-uart0.listen_at_cmd();
-uart0.listen_rx_fifo_full();
+uart0.listen(UartInterrupt::AtCmd | UartConterrupt::RxFifoFull);
```
## I2S changes
### The I2S driver has been moved to `i2s::master`
```diff
-use esp_hal::i2s::{DataFormat, I2s, Standard};
+use esp_hal::i2s::master::{DataFormat, I2s, Standard};
```
### Removed `i2s` traits
The following traits have been removed:
- `I2sWrite`
- `I2sWriteDma`
- `I2sRead`
- `I2sReadDma`
- `I2sWriteDmaAsync`
- `I2sReadDmaAsync`
You no longer have to import these to access their respective APIs. If you used these traits
in your functions as generic parameters, you can use the `I2s` type directly instead.
For example:
```diff
-fn foo(i2s: &mut impl I2sWrite) {
+fn foo(i2s: &mut I2s<'_, I2S0, Blocking>) {
// ...
}
```
## DMA related changes
### Circular DMA transfer's `available` returns `Result<usize, DmaError>` now
In case of any error you should drop the transfer and restart it.
```diff
loop {
- let avail = transfer.available();
+ let avail = match transfer.available() {
+ Ok(avail) => avail,
+ Err(_) => {
+ core::mem::drop(transfer);
+ transfer = i2s_tx.write_dma_circular(&tx_buffer).unwrap();
+ continue;
+ },
+ };
```
### Channel, ChannelRx and ChannelTx types have changed
- `Channel`'s `Async`/`Blocking` mode has been moved before the channel instance parameter.
- `ChannelRx` and `ChannelTx` have gained a new `Async`/`Blocking` mode parameter.
```diff
-Channel<'d, DmaChannel0, Async>
+Channel<'d, Async, DmaChannel0>
-ChannelRx<'d, DmaChannel0>
+ChannelRx<'d, Async, DmaChannel0>
-ChannelTx<'d, DmaChannel0>
+ChannelTx<'d, Async, DmaChannel0>
```
## Removed `peripheral_input` and `into_peripheral_output` from GPIO pin types
Creating peripheral interconnect signals now consume the GPIO pin used for the connection.
The previous signal function have been replaced by `split`. This change affects the following APIs:
- `GpioPin`
- `AnyPin`
```diff
-let input_signal = gpioN.peripheral_input();
-let output_signal = gpioN.into_peripheral_output();
+let (input_signal, output_signal) = gpioN.split();
```
`into_peripheral_output`, `split` (for output pins only) and `peripheral_input` have been added to
the GPIO drivers (`Input`, `Output`, `OutputOpenDrain` and `Flex`) instead.
## ETM changes
- The types are no longer prefixed with `GpioEtm`, `TimerEtm` or `SysTimerEtm`. You can still use
import aliasses in case you need to differentiate due to name collisions
(e.g. `use esp_hal::gpio::etm::Event as GpioEtmEvent`).
- The old task and event types have been replaced by `Task` and `Event`.
- GPIO tasks and events are no longer generic.
## Changes to peripheral configuration
### The `uart::config` module has been removed
The module's contents have been moved into `uart`.
```diff
-use esp_hal::uart::config::Config;
+use esp_hal::uart::Config;
```
If you work with multiple configurable peripherals, you may want to import the `uart` module and
refer to the `Config` struct as `uart::Config`.
### SPI drivers can now be configured using `spi::master::Config`
- The old methods to change configuration have been removed.
- The `new` and `new_typed` constructor no longer takes `frequency` and `mode`.
- The default configuration is now:
- bus frequency: 1 MHz
- bit order: MSB first
- mode: SPI mode 0
- There are new constructors (`new_with_config`, `new_typed_with_config`) and a new `apply_config` method to apply custom configuration.
```diff
-use esp_hal::spi::{master::Spi, SpiMode};
+use esp_hal::spi::{master::{Config, Spi}, SpiMode};
-Spi::new(SPI2, 100.kHz(), SpiMode::Mode1);
+Spi::new_with_config(
+ SPI2,
+ Config {
+ frequency: 100.kHz(),
+ mode: SpiMode::Mode0,
+ ..Config::default()
+ },
+)
```
## LCD_CAM changes
### I8080 driver split `set_byte_order()` into `set_8bits_order()` and `set_byte_order()`.
If you were using an 8-bit bus.
```diff
- i8080.set_byte_order(ByteOrder::default());
+ i8080.set_8bits_order(ByteOrder::default());
```
If you were using an 16-bit bus, you don't need to change anything, `set_byte_order()` now works correctly.
If you were sharing the bus between an 8-bit and 16-bit device, you will have to call the corresponding method when
you switch between devices. Be sure to read the documentation of the new methods.
### Mixed mode constructors
It is no longer possible to construct `I8080` or `Camera` with an async-mode DMA channel.
Convert the DMA channel into blocking before passing it to these constructors.
```diff
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
let channel = ctx
.dma
.channel0
- .configure(false, DmaPriority::Priority0)
- .into_async();
+ .configure(false, DmaPriority::Priority0);
let i8080 = I8080::new(
lcd_cam.lcd,
channel.tx,
pins,
20.MHz(),
Config::default(),
);
```
## `rmt::Channel::transmit` now returns `Result`, `PulseCode` is now `u32`
When trying to send a one-shot transmission will fail if it doesn't end with an end-marker.
```diff
- let mut data = [PulseCode {
- level1: true,
- length1: 200,
- level2: false,
- length2: 50,
- }; 20];
-
- data[data.len() - 2] = PulseCode {
- level1: true,
- length1: 3000,
- level2: false,
- length2: 500,
- };
- data[data.len() - 1] = PulseCode::default();
+ let mut data = [PulseCode::new(true, 200, false, 50); 20];
+ data[data.len() - 2] = PulseCode::new(true, 3000, false, 500);
+ data[data.len() - 1] = PulseCode::empty();
- let transaction = channel.transmit(&data);
+ let transaction = channel.transmit(&data).unwrap();
```
## The `parl_io::NoClkPin` and `no_clk_pin()` have been removed
You can use `gpio::NoPin` instead.
```diff
use esp_hal:: {
- parl_io::no_clk_pin,
+ gpio::NoPin,
}
-parl_io.rx.with_config(&mut rx_pins, no_clk_pin(), BitPackOrder::Msb, Some(0xfff))
+let mut rx_clk_pin = NoPin;
+parl_io.rx.with_config(&mut rx_pins, &mut rx_clk_pin, BitPackOrder::Msb, Some(0xfff))
```
## `get_` prefixes have been removed from functions
In order to better comply with the Rust API Guidelines [getter names convention], we have removed the `get_` prefixes from all functions which previously had it. Due to the number of changes it's not practical to list all changes here, however if a function previous began with `get_`, you can simply remove this prefix.
[getter names convention]: https://rust-lang.github.io/api-guidelines/naming.html#c-getter
## The `get_core()` function has been removed in favour of `Cpu::current()`
```diff
- let core = esp_hal::get_core();
+ let core = esp_hal::Cpu::current();
```

478
esp-hal/MIGRATING-0.22.md Normal file
View File

@ -0,0 +1,478 @@
# Migration Guide from 0.22.x to v1.0.0-beta.0
Starting with this release, unstable parts of esp-hal will be gated behind the `unstable` feature.
The `unstable` feature itself is unstable, we might change the way we hide APIs without notice.
Unstable APIs are not covered by semver guarantees, they may break even between patch releases.
Please refer to the documentation to see which APIs are marked as unstable.
## DMA changes
### Accessing channel objects
DMA channels are now available through the `Peripherals` struct, which is returned
by `esp_hal::init()`. The channels themselves have been renamed to match other peripheral singletons.
- ESP32-C2, C3, C6, H2 and S3: `channelX -> DMA_CHX`
- ESP32 and S2: `spiXchannel -> DMA_SPIX`, `i2sXchannel -> DMA_I2SX`
```diff
-let dma = Dma::new(peripherals.DMA);
-let channel = dma.channel2;
+let channel = peripherals.DMA_CH2;
```
### Channel configuration changes
- `configure_for_async` and `configure` have been removed
- PDMA devices (ESP32, ESP32-S2) provide no channel configurability
- GDMA devices provide `set_priority` to change DMA in/out channel priority
```diff
let mut spi = Spi::new_with_config(
peripherals.SPI2,
Config::default(),
)
// other setup
-.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
+.with_dma(dma_channel);
```
```diff
+dma_channel.set_priority(DmaPriority::Priority1);
let mut spi = Spi::new_with_config(
peripherals.SPI2,
Config::default(),
)
// other setup
-.with_dma(dma_channel.configure(false, DmaPriority::Priority1));
+.with_dma(dma_channel);
```
### Burst mode configuration
Burst mode is now a property of buffers, instead of DMA channels. Configuration can be done by
calling `set_burst_config` on buffers that support it. The configuration options and the
corresponding `BurstConfig` type are device specfic.
### Usability changes affecting applications
Individual channels are no longer wrapped in `Channel`, but they implement the `DmaChannel` trait.
This means that if you want to split them into an `rx` and a `tx` half (which is only supported on
the H2, C6 and S3 currently), you can't move out of the channel but instead you need to call
the `split` method.
```diff
-let tx = channel.tx;
+use esp_hal::dma::DmaChannel;
+let (rx, tx) = channel.split();
```
The `Channel` types remain available for use in peripheral drivers.
It is now simpler to work with DMA channels in generic contexts. esp-hal now provides convenience
traits and type aliasses to specify peripheral compatibility. The `ChannelCreator` types have been
removed, further simplifying use.
For example, previously you may have needed to write something like this to accept a DMA channel
in a generic function:
```rust
fn new_foo<'d, T>(
dma_channel: ChannelCreator<2>, // It wasn't possible to accept a generic ChannelCreator.
peripheral: impl Peripheral<P = T> + 'd,
)
where
T: SomePeripheralInstance,
ChannelCreator<2>: DmaChannelConvert<<T as DmaEligible>::Dma>,
{
let dma_channel = dma_channel.configure_for_async(false, DmaPriority::Priority0);
let driver = PeripheralDriver::new(peripheral, config).with_dma(dma_channel);
// ...
}
```
From now on a similar, but more flexible implementation may look like:
```rust
fn new_foo<'d, T, CH>(
dma_channel: impl Peripheral<P = CH> + 'd,
peripheral: impl Peripheral<P = T> + 'd,
)
where
T: SomePeripheralInstance,
CH: DmaChannelFor<T>,
{
// Optionally: dma_channel.set_priority(DmaPriority::Priority2);
let driver = PeripheralDriver::new(peripheral, config).with_dma(dma_channel);
// ...
}
```
### Usability changes affecting third party peripheral drivers
If you are writing a driver and need to store a channel in a structure, you can use one of the
`ChannelFor` type aliasses.
```diff
struct Aes<'d> {
- channel: ChannelTx<'d, Blocking, <AES as DmaEligible>::Dma>,
+ channel: ChannelTx<'d, Blocking, PeripheralTxChannel<AES>>,
}
```
## Timer changes
The low level timers, `SystemTimer` and `TimerGroup` are now "dumb". They contain no logic for operating modes or trait implementations (except the low level `Timer` trait).
### Timer drivers - `OneShotTimer` & `PeriodicTimer`
Both drivers now have a `Mode` parameter. Both also type erase the underlying driver by default, call `new_typed` to retain the type.
```diff
- OneShotTimer<'static, systimer::Alarm>;
+ OneShotTimer<'static, Blocking>;
- PeriodicTimer<'static, systimer::Alarm>;
+ PeriodicTimer<'static, Blocking>;
```
### SystemTimer
```diff
let systimer = SystemTimer::new(peripherals.SYSTIMER);
- static UNIT0: StaticCell<SpecificUnit<'static, 0>> = StaticCell::new();
- let unit0 = UNIT0.init(systimer.unit0);
- let frozen_unit = FrozenUnit::new(unit0);
- let alarm0 = Alarm::new(systimer.comparator0, &frozen_unit);
- alarm0.set_period(1u32.secs());
+ let alarm0 = systimer.alarm0;
+ let mut timer = PeriodicTimer::new(alarm0);
+ timer.start(1u64.secs());
```
### TIMG
Timer group timers have been type erased.
```diff
- timg::Timer<timg::Timer0<crate::peripherals::TIMG0>, Blocking>
+ timg::Timer
```
### ETM usage has changed
Timer dependant ETM events should be created _prior_ to initializing the timer with the chosen driver.
```diff
let task = ...; // ETM task
let syst = SystemTimer::new(peripherals.SYSTIMER);
let alarm0 = syst.alarm0;
- alarm0.load_value(1u64.millis()).unwrap();
- alarm0.start();
- let event = Event::new(&mut alarm0);
+ let event = Event::new(&alarm0);
+ let timer = OneShotTimer::new(alarm0);
+ timer.schedule(1u64.millis()).unwrap();
let _configured_channel = channel0.setup(&event, &task);
```
## PSRAM is now initialized automatically
Calling `esp_hal::initialize` will now configure PSRAM if either the `quad-psram` or `octal-psram`
is enabled. To retrieve the address and size of the initialized external memory, use
`esp_hal::psram::psram_raw_parts`, which returns a pointer and a length.
```diff
-let peripherals = esp_hal::init(esp_hal::Config::default());
-let (start, size) = esp_hal::psram::init_psram(peripherals.PSRAM, psram_config);
+let peripherals = esp_hal::init({
+ let mut config = esp_hal::Config::default();
+ config.psram = psram_config;
+ config
+});
+let (start, size) = esp_hal::psram::psram_raw_parts(&peripherals.PSRAM, psram);
```
The usage of `esp_alloc::psram_allocator!` remains unchanged.
## embedded-hal 0.2.\* is not supported anymore.
As per https://github.com/rust-embedded/embedded-hal/pull/640, our driver no longer implements traits from `embedded-hal 0.2.x`.
Analogs of all traits from the above mentioned version are available in `embedded-hal 1.x.x`
```diff
- use embedded_hal_02::can::Frame;
+ use embedded_can::Frame;
```
```diff
- use embedded_hal_02::digital::v2::OutputPin;
- use embedded_hal_02::digital::v2::ToggleableOutputPin;
+ use embedded_hal::digital::OutputPin;
+ use embedded_hal::digital::StatefulOutputPin;
```
```diff
- use embedded_hal_02::serial::{Read, Write};
+ use embedded_hal_nb::serial::{Read, Write};
```
You might also want to check the full official `embedded-hal` migration guide:
https://github.com/rust-embedded/embedded-hal/blob/master/docs/migrating-from-0.2-to-1.0.md
## Interrupt related reshuffle
```diff
- use esp_hal::InterruptConfigurable;
- use esp_hal::DEFAULT_INTERRUPT_HANDLER;
+ use esp_hal::interrupt::InterruptConfigurable;
+ use esp_hal::interrupt::DEFAULT_INTERRUPT_HANDLER;
```
## Driver constructors now take a configuration and are fallible
The old `new_with_config` constructor have been removed, and `new` constructors now always take
a configuration structure. They have also been updated to return a `ConfigError` if the configuration
is not compatible with the hardware.
```diff
-let mut spi = Spi::new_with_config(
+let mut spi = Spi::new(
peripherals.SPI2,
Config {
frequency: 100.kHz(),
mode: SpiMode::_0,
..Config::default()
},
-);
+)
+.unwrap();
```
```diff
let mut spi = Spi::new(
peripherals.SPI2,
+ Config::default(),
-);
+)
+.unwrap();
```
## Peripheral instance type parameters and `new_typed` constructors have been removed
Call `new` instead and remove the type parameters if you've used them.
```diff
-let mut spi: Spi<'lt, SPI2> = Spi::new_typed(..).unwrap();
+let mut spi: Spi<'lt> = Spi::new(..).unwrap();
```
## LCD_CAM configuration changes
- `cam` now has a `Config` strurct that contains frequency, bit/byte order, VSync filter options.
- DPI, I8080: `frequency` has been moved into `Config`.
```diff
+let mut cam_config = cam::Config::default();
+cam_config.frequency = 1u32.MHz();
cam::Camera::new(
lcd_cam.cam,
dma_rx_channel,
pins,
- 1u32.MHz(),
+ cam_config,
)
```
## SpiDma now requires you specify the transfer length explicitly
```diff
dma_tx_buf.set_length(5 /* or greater */);
- spi_dma.write(dma_tx_buf);
+ spi_dma.write(5, dma_tx_buf);
```
```diff
dma_rx_buf.set_length(5 /* or greater */);
- spi_dma.read(dma_rx_buf);
+ spi_dma.read(5, dma_rx_buf);
```
```diff
dma_rx_buf.set_length(5 /* or greater */);
dma_tx_buf.set_length(5 /* or greater */);
- spi_dma.transfer(dma_rx_buf, dma_tx_buf);
+ spi_dma.transfer(5, dma_rx_buf, 5, dma_tx_buf);
```
## I2C Error changes
To avoid abbreviations and contractions (as per the esp-hal guidelines), some error variants have changed
```diff
- Error::ExecIncomplete
+ Error::ExecutionIncomplete
- Error::CommandNrExceeded
+ Error::CommandNumberExceeded
- Error::ExceedingFifo
+ Error::FifoExceeded
- Error::TimeOut
+ Error::Timeout
- Error::InvalidZeroLength
+ Error::ZeroLengthInvalid
```
## The crate prelude has been removed
The reexports that were previously part of the prelude are available through other paths:
- `nb` is no longer re-exported. Please import the `nb` crate if you need it.
- `ExtU64` and `RateExtU32` have been moved to `esp_hal::time`
- `Clock` and `CpuClock`: `esp_hal::clock::{Clock, CpuClock}`
- The following traits need to be individually imported when needed:
- `esp_hal::analog::dac::Instance`
- `esp_hal::gpio::Pin`
- `esp_hal::ledc::channel::ChannelHW`
- `esp_hal::ledc::channel::ChannelIFace`
- `esp_hal::ledc::timer::TimerHW`
- `esp_hal::ledc::timer::TimerIFace`
- `esp_hal::timer::timg::TimerGroupInstance`
- `esp_hal::timer::Timer`
- `esp_hal::interrupt::InterruptConfigurable`
- The `entry` macro can be imported as `esp_hal::entry`, while other macros are found under `esp_hal::macros`
## `AtCmdConfig` now uses builder-lite pattern
```diff
- uart0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None));
+ uart0.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#'));
```
## Crate configuration changes
To prevent ambiguity between configurations, we had to change the naming format of configuration
keys. Before, we used `{prefix}_{key}`, which meant that esp-hal and esp-hal-\* configuration keys
were impossible to tell apart. To fix this issue, we are changing the separator from one underscore
character to `_CONFIG_`. This also means that users will have to change their `config.toml`
configurations to match the new format.
```diff
[env]
-ESP_HAL_PLACE_SPI_DRIVER_IN_RAM="true"
+ESP_HAL_CONFIG_PLACE_SPI_DRIVER_IN_RAM="true"
```
## UART changes
The `Config` struct's setters are now prefixed with `with_`. `parity_none`, `parity_even`,
`parity_odd` have been replaced by `with_parity` that takes a `Parity` parameter.
```diff
let config = Config::default()
- .rx_fifo_full_threshold(30)
+ .with_rx_fifo_full_threshold(30)
- .parity_even();
+ .with_parity(Parity::Even);
```
The `DataBits`, `Parity`, and `StopBits` enum variants are no longer prefixed with the name of the enum.
e.g.
```diff
- DataBits::DataBits8
+ DataBits::_8
- Parity::ParityNone
+ Parity::None
- StopBits::Stop1
+ StopBits::_1
```
The previous blocking implementation of `read_bytes` has been removed, and the non-blocking `drain_fifo` has instead been renamed to `read_bytes` in its place.
Any code which was previously using `read_bytes` to fill a buffer in a blocking manner will now need to implement the necessary logic to block until the buffer is filled in their application instead.
The `Error` enum variant uses object+verb naming.
e.g.
```diff
- RxGlichDetected
+ GlitchOccurred
```
RX/TX pin assignment moved from constructors to builder functions.
e.g.
```diff
let mut uart1 = Uart::new(
peripherals.UART1,
- Config::default(),
- peripherals.GPIO1,
- peripherals.GPIO2,
- ).unwrap();
+ Config::default())
+ .unwrap()
+ .with_rx(peripherals.GPIO1)
+ .with_tx(peripherals.GPIO2);
```
## Spi `with_miso` has been split
Previously, `with_miso` set up the provided pin as an input and output, which was necessary for half duplex.
Full duplex does not require this, and it also creates an artificial restriction.
If you were using half duplex SPI with `with_miso`,
you should now use `with_sio1` instead to get the previous behavior.
## CPU Clocks
The specific CPU clock variants are renamed from e.g. `Clock80MHz` to `_80MHz`.
```diff
- CpuClock::Clock80MHz
+ CpuClock::_80MHz
```
Additionally the enum is marked as non-exhaustive.
## SPI Changes
The SPI mode variants are renamed from e.g. `Mode0` to `_0`.
```diff
- Mode::Mode0
+ Mode::_0
```
The Address and Command enums have similarly had their variants changed from e.g. `Address1` to `_1Bit` and `Command1` to `_1Bit` respectively:
```diff
- Address::Address1
+ Address::_1Bit
- Command::Command1
+ Command::_1Bit
```
## GPIO Changes
The GPIO drive strength variants are renamed from e.g. `I5mA` to `_5mA`.
```diff
-DriveStrength::I5mA
+DriveStrength::_5mA
```
## ADC Changes
The ADC attenuation variants are renamed from e.g. `Attenuation0dB` to `_0dB`.
```diff
-Attenuation::Attenuation0dB
+Attenuation::_0dB
```

View File

@ -2,7 +2,7 @@
[![Crates.io](https://img.shields.io/crates/v/esp-hal?labelColor=1C2C2E&color=C96329&logo=Rust&style=flat-square)](https://crates.io/crates/esp-hal)
[![docs.rs](https://img.shields.io/docsrs/esp-hal?labelColor=1C2C2E&color=C96329&logo=rust&style=flat-square)](https://docs.esp-rs.org/esp-hal)
![MSRV](https://img.shields.io/badge/MSRV-1.76-blue?labelColor=1C2C2E&style=flat-square)
![MSRV](https://img.shields.io/badge/MSRV-1.83-blue?labelColor=1C2C2E&style=flat-square)
![Crates.io](https://img.shields.io/crates/l/esp-hal?labelColor=1C2C2E&style=flat-square)
[![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&labelColor=1C2C2E&color=BEC5C9&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org)
@ -46,9 +46,13 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a
[s2-trm]: https://www.espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf
[s3-trm]: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf
## `unstable` feature
The stable feature set is designed to remain consistent and reliable. Other parts guarded by the `unstable` feature, however, are still under active development and may undergo breaking changes and are disabled by default.
## Minimum Supported Rust Version (MSRV)
This crate is guaranteed to compile on stable Rust 1.76 and up. It _might_
This crate is guaranteed to compile on stable Rust 1.83 and up. It _might_
compile with older versions but that may change in any new patch release.
## License

View File

@ -8,18 +8,17 @@ use std::{
};
use esp_build::assert_unique_used_features;
use esp_config::{generate_config, Value};
use esp_metadata::{Chip, Config};
#[cfg(debug_assertions)]
esp_build::warning! {"
WARNING: use --release
We *strongly* recommend using release profile when building esp-hal.
The dev profile can potentially be one or more orders of magnitude
slower than release, and may cause issues with timing-senstive
peripherals and/or devices.
"}
fn main() -> Result<(), Box<dyn Error>> {
println!("cargo:rustc-check-cfg=cfg(is_debug_build)");
if let Ok(level) = std::env::var("OPT_LEVEL") {
if level == "0" || level == "1" {
println!("cargo:rustc-cfg=is_debug_build");
}
}
// NOTE: update when adding new device support!
// Ensure that exactly one chip has been specified:
assert_unique_used_features!(
@ -57,28 +56,68 @@ fn main() -> Result<(), Box<dyn Error>> {
let config = Config::for_chip(&chip);
// Check PSRAM features are only given if the target supports PSRAM:
if !config.contains(&String::from("psram"))
&& (cfg!(feature = "psram-2m") || cfg!(feature = "psram-4m") || cfg!(feature = "psram-8m"))
{
if !config.contains(&String::from("psram")) && cfg!(feature = "quad-psram") {
panic!("The target does not support PSRAM");
}
if !config.contains(&String::from("octal_psram")) && cfg!(feature = "octal-psram") {
panic!("The target does not support Octal PSRAM");
}
// Define all necessary configuration symbols for the configured device:
config.define_symbols();
#[allow(unused_mut)]
let mut config_symbols = config.all();
#[cfg(feature = "flip-link")]
config_symbols.push("flip-link".to_owned());
// Place all linker scripts in `OUT_DIR`, and instruct Cargo how to find these
// files:
let out = PathBuf::from(env::var_os("OUT_DIR").unwrap());
println!("cargo:rustc-link-search={}", out.display());
// emit config
let cfg = generate_config(
"esp_hal",
&[
(
"place-spi-driver-in-ram",
"Places the SPI driver in RAM for better performance",
Value::Bool(false),
None
),
(
"spi-address-workaround",
"(ESP32 only) Enables a workaround for the issue where SPI in half-duplex mode incorrectly transmits the address on a single line if the data buffer is empty.",
Value::Bool(true),
None
),
(
"place-switch-tables-in-ram",
"Places switch-tables, some lookup tables and constants related to interrupt handling into RAM - resulting in better performance but slightly more RAM consumption.",
Value::Bool(true),
None
),
(
"place-anon-in-ram",
"Places anonymous symbols into RAM - resulting in better performance at the cost of significant more RAM consumption. Best to be combined with `place-switch-tables-in-ram`.",
Value::Bool(false),
None
),
],
true,
);
// RISC-V and Xtensa devices each require some special handling and processing
// of linker scripts:
#[allow(unused_mut)]
let mut config_symbols = config.all().collect::<Vec<_>>();
#[cfg(feature = "flip-link")]
config_symbols.push("flip-link");
for (key, value) in &cfg {
if let Value::Bool(true) = value {
config_symbols.push(key);
}
}
if cfg!(feature = "esp32") || cfg!(feature = "esp32s2") || cfg!(feature = "esp32s3") {
// Xtensa devices:
@ -129,7 +168,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// Helper Functions
fn copy_dir_all(
config_symbols: &Vec<String>,
config_symbols: &[&str],
src: impl AsRef<Path>,
dst: impl AsRef<Path>,
) -> std::io::Result<()> {
@ -156,7 +195,7 @@ fn copy_dir_all(
/// A naive pre-processor for linker scripts
fn preprocess_file(
config: &[String],
config: &[&str],
src: impl AsRef<Path>,
dst: impl AsRef<Path>,
) -> std::io::Result<()> {
@ -170,8 +209,7 @@ fn preprocess_file(
let line = line?;
let trimmed = line.trim();
if let Some(stripped) = trimmed.strip_prefix("#IF ") {
let condition = stripped.to_string();
if let Some(condition) = trimmed.strip_prefix("#IF ") {
let should_take = take.iter().all(|v| *v);
let should_take = should_take && config.contains(&condition);
take.push(should_take);
@ -215,11 +253,7 @@ fn generate_memory_extras() -> Vec<u8> {
#[cfg(feature = "esp32s2")]
fn generate_memory_extras() -> Vec<u8> {
let reserved_cache = if cfg!(any(
feature = "psram-2m",
feature = "psram-4m",
feature = "psram-8m"
)) {
let reserved_cache = if cfg!(feature = "quad-psram") {
"0x4000"
} else {
"0x2000"

8
esp-hal/ld/README.md Normal file
View File

@ -0,0 +1,8 @@
# ROM functions
Files in the `rom` subdirectories are taken from esp-idf
- DON'T include any `*newlib*` functions
- systimer, wdt and mbedtls shouldn't be included
- make sure to align the version you take the files from with esp-wifi-sys - NEVER randomly sync the files with other versions
- some additional functions are needed from ROM - see `additional.ld` (these are usually defined in the `*newlib*` files)

View File

@ -8,6 +8,10 @@ PROVIDE(__zero_bss = default_mem_hook);
PROVIDE(__init_data = default_mem_hook);
PROVIDE(__post_init = default_post_init);
PROVIDE(__level_1_interrupt = handle_interrupts);
PROVIDE(__level_2_interrupt = handle_interrupts);
PROVIDE(__level_3_interrupt = handle_interrupts);
INCLUDE exception.x
/* ESP32 fixups */
@ -15,22 +19,16 @@ INCLUDE "fixups/rtc_fast_rwdata_dummy.x"
/* END ESP32 fixups */
/* Shared sections - ordering matters */
INCLUDE "text.x"
INCLUDE "rodata.x"
INCLUDE "rwtext.x"
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "rtc_fast.x"
INCLUDE "rtc_slow.x"
INCLUDE "stack.x"
INCLUDE "dram2.x"
/* End of Shared sections */
/* an uninitialized section for use as the wifi-heap in esp-wifi */
SECTIONS {
.dram2_uninit (NOLOAD) : ALIGN(4) {
*(.dram2_uninit)
} > dram2_seg
}
EXTERN(DefaultHandler);
EXTERN(WIFI_EVENT); /* Force inclusion of WiFi libraries */

View File

@ -1,34 +1,9 @@
PROVIDE(ets_delay_us = 0x40008534);
PROVIDE(ets_update_cpu_frequency_rom = 0x40008550);
PROVIDE(rom_i2c_writeReg = 0x400041a4);
PROVIDE(rom_i2c_writeReg_Mask = 0x400041fc);
PROVIDE(rtc_get_reset_reason = 0x400081d4);
PROVIDE(software_reset = 0x4000824c);
PROVIDE(software_reset_cpu = 0x40008264);
INCLUDE "rom/esp32.rom.api.ld"
INCLUDE "rom/esp32.rom.eco3.ld"
INCLUDE "rom/esp32.rom.ld"
INCLUDE "rom/esp32.rom.libgcc.ld"
INCLUDE "rom/esp32.rom.redefined.ld"
INCLUDE "rom/esp32.rom.spiflash_legacy.ld"
INCLUDE "rom/esp32.rom.syscalls.ld"
PROVIDE ( ets_efuse_get_spiconfig = 0x40008658 );
PROVIDE ( esp_rom_efuse_get_flash_gpio_info = ets_efuse_get_spiconfig );
PROVIDE ( esp_rom_gpio_connect_out_signal = gpio_matrix_out );
PROVIDE ( gpio_matrix_out = 0x40009f0c );
PROVIDE ( gpio_matrix_in = 0x40009edc );
PROVIDE ( esp_rom_gpio_connect_in_signal = gpio_matrix_in );
PROVIDE ( esp_rom_spiflash_config_clk = 0x40062bc8 );
PROVIDE ( g_rom_spiflash_dummy_len_plus = 0x3ffae290 );
PROVIDE ( g_rom_flashchip = 0x3ffae270 );
PROVIDE ( cache_sram_mmu_set_rom = 0x400097f4 );
PROVIDE (esp_rom_crc32_be = 0x4005d024);
PROVIDE (esp_rom_crc16_be = 0x4005d09c);
PROVIDE (esp_rom_crc8_be = 0x4005d114);
PROVIDE (esp_rom_crc32_le = 0x4005cfec);
PROVIDE (esp_rom_crc16_le = 0x4005d05c);
PROVIDE (esp_rom_crc8_le = 0x4005d0e0);
PROVIDE (esp_rom_md5_init = 0x4005da7c);
PROVIDE (esp_rom_md5_update = 0x4005da9c);
PROVIDE (esp_rom_md5_final = 0x4005db1c);
memcmp = 0x4000c260;
memcpy = 0x4000c2c8;
memmove = 0x4000c3c0;
memset = 0x4000c44c;
INCLUDE "rom/additional.ld"

View File

@ -0,0 +1,20 @@
memcmp = 0x4000c260;
memcpy = 0x4000c2c8;
memmove = 0x4000c3c0;
memset = 0x4000c44c;
PROVIDE ( strcpy = 0x400013ac );
PROVIDE ( abs = 0x40056340 );
PROVIDE ( strncpy = 0x400015d4 );
PROVIDE ( strncmp = 0x4000c5f4 );
PROVIDE ( bzero = 0x4000c1f4 );
PROVIDE ( strcat = 0x4000c518 );
PROVIDE ( strcmp = 0x40001274 );
PROVIDE ( strchr = 0x4000c53c );
PROVIDE ( strlcpy = 0x4000c584 );
PROVIDE ( strstr = 0x4000c674 );
PROVIDE ( strcasecmp = 0x400011cc );
PROVIDE ( memchr = 0x4000c244 );

View File

@ -0,0 +1,62 @@
/**
* ROM APIs
*/
PROVIDE ( esp_rom_crc32_le = crc32_le );
PROVIDE ( esp_rom_crc16_le = crc16_le );
PROVIDE ( esp_rom_crc8_le = crc8_le );
PROVIDE ( esp_rom_crc32_be = crc32_be );
PROVIDE ( esp_rom_crc16_be = crc16_be );
PROVIDE ( esp_rom_crc8_be = crc8_be );
PROVIDE ( esp_rom_gpio_pad_select_gpio = gpio_pad_select_gpio );
PROVIDE ( esp_rom_gpio_pad_pullup_only = gpio_pad_pullup );
PROVIDE ( esp_rom_gpio_pad_set_drv = gpio_pad_set_drv );
PROVIDE ( esp_rom_gpio_pad_unhold = gpio_pad_unhold );
PROVIDE ( esp_rom_gpio_connect_in_signal = gpio_matrix_in );
PROVIDE ( esp_rom_gpio_connect_out_signal = gpio_matrix_out );
PROVIDE ( esp_rom_efuse_mac_address_crc8 = esp_crc8 );
PROVIDE ( esp_rom_efuse_get_flash_gpio_info = ets_efuse_get_spiconfig );
PROVIDE ( esp_rom_efuse_is_secure_boot_enabled = ets_efuse_secure_boot_enabled );
PROVIDE ( esp_rom_uart_flush_tx = uart_tx_flush );
PROVIDE ( esp_rom_uart_tx_one_char = uart_tx_one_char );
PROVIDE ( esp_rom_uart_tx_wait_idle = uart_tx_wait_idle );
PROVIDE ( esp_rom_uart_rx_one_char = uart_rx_one_char );
PROVIDE ( esp_rom_uart_rx_string = UartRxString );
PROVIDE ( esp_rom_uart_set_as_console = uart_tx_switch );
PROVIDE ( esp_rom_uart_putc = ets_write_char_uart );
PROVIDE ( esp_rom_uart_switch_buffer = uart_buff_switch );
PROVIDE ( esp_rom_output_flush_tx = uart_tx_flush );
PROVIDE ( esp_rom_output_tx_one_char = uart_tx_one_char );
PROVIDE ( esp_rom_output_tx_wait_idle = uart_tx_wait_idle );
PROVIDE ( esp_rom_output_rx_one_char = uart_rx_one_char );
PROVIDE ( esp_rom_output_rx_string = UartRxString );
PROVIDE ( esp_rom_output_set_as_console = uart_tx_switch );
PROVIDE ( esp_rom_output_putc = ets_write_char_uart );
PROVIDE ( esp_rom_output_switch_buffer = uart_buff_switch );
/* wpa_supplicant re-implements the MD5 functions: MD5Init, MD5Update, MD5Final */
/* so here we directly assign the symbols with the ROM API address */
PROVIDE ( esp_rom_md5_init = 0x4005da7c );
PROVIDE ( esp_rom_md5_update = 0x4005da9c );
PROVIDE ( esp_rom_md5_final = 0x4005db1c );
PROVIDE ( esp_rom_software_reset_system = software_reset );
PROVIDE ( esp_rom_software_reset_cpu = software_reset_cpu );
PROVIDE ( esp_rom_printf = ets_printf );
PROVIDE ( esp_rom_delay_us = ets_delay_us );
PROVIDE ( esp_rom_install_uart_printf = ets_install_uart_printf );
PROVIDE ( esp_rom_get_reset_reason = rtc_get_reset_reason );
PROVIDE ( esp_rom_route_intr_matrix = intr_matrix_set );
PROVIDE ( esp_rom_get_cpu_ticks_per_us = ets_get_cpu_frequency );
PROVIDE ( esp_rom_spiflash_set_bp = esp_rom_spiflash_lock );
PROVIDE ( esp_rom_spiflash_write_enable = SPI_write_enable);
PROVIDE ( esp_rom_regi2c_read = rom_i2c_readReg );
PROVIDE ( esp_rom_regi2c_read_mask = rom_i2c_readReg_Mask );
PROVIDE ( esp_rom_regi2c_write = rom_i2c_writeReg );
PROVIDE ( esp_rom_regi2c_write_mask = rom_i2c_writeReg_Mask );

View File

@ -0,0 +1,10 @@
/*
ESP32 ECO3 ROM address table
Secure Boot Version 2 API's imported from the ROM
*/
PROVIDE ( ets_secure_boot_verify_signature = 0x4006543c);
PROVIDE ( ets_secure_boot_verify_boot_bootloader = 0x400655ec);
PROVIDE ( ets_use_secure_boot_v2 = 0x4000f8d4);
PROVIDE ( ets_rsa_pss_verify = 0x40065310);
PROVIDE ( ets_mgf1_sha256 = 0x400651a8);
PROVIDE ( ets_emsa_pss_verify = 0x4006520c);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
/* Unlike other ROM functions which are exported using PROVIDE, which declares
weak symbols, these libgcc functions are exported using assignment,
which declares strong symbols. This is done so that ROM functions are always
used instead of the ones provided by libgcc.a.
*/
__absvdi2 = 0x4006387c;
__absvsi2 = 0x40063868;
__adddf3 = 0x40002590;
__addsf3 = 0x400020e8;
__addvdi3 = 0x40002cbc;
__addvsi3 = 0x40002c98;
__ashldi3 = 0x4000c818;
__ashrdi3 = 0x4000c830;
__bswapdi2 = 0x40064b08;
__bswapsi2 = 0x40064ae0;
__clrsbdi2 = 0x40064b7c;
__clrsbsi2 = 0x40064b64;
__clzdi2 = 0x4000ca50;
__clzsi2 = 0x4000c7e8;
__cmpdi2 = 0x40063820;
__ctzdi2 = 0x4000ca64;
__ctzsi2 = 0x4000c7f0;
__divdc3 = 0x400645a4;
__divdf3 = 0x40002954;
__divdi3 = 0x4000ca84;
__divsi3 = 0x4000c7b8;
__eqdf2 = 0x400636a8;
__eqsf2 = 0x40063374;
__extendsfdf2 = 0x40002c34;
__ffsdi2 = 0x4000ca2c;
__ffssi2 = 0x4000c804;
__fixdfdi = 0x40002ac4;
__fixdfsi = 0x40002a78;
__fixsfdi = 0x4000244c;
__fixsfsi = 0x4000240c;
__fixunsdfsi = 0x40002b30;
__fixunssfdi = 0x40002504;
__fixunssfsi = 0x400024ac;
__floatdidf = 0x4000c988;
__floatdisf = 0x4000c8c0;
__floatsidf = 0x4000c944;
__floatsisf = 0x4000c870;
__floatundidf = 0x4000c978;
__floatundisf = 0x4000c8b0;
__floatunsidf = 0x4000c938;
__floatunsisf = 0x4000c864;
__gcc_bcmp = 0x40064a70;
__gedf2 = 0x40063768;
__gesf2 = 0x4006340c;
__gtdf2 = 0x400636dc;
__gtsf2 = 0x400633a0;
__ledf2 = 0x40063704;
__lesf2 = 0x400633c0;
__lshrdi3 = 0x4000c84c;
__ltdf2 = 0x40063790;
__ltsf2 = 0x4006342c;
__moddi3 = 0x4000cd4c;
__modsi3 = 0x4000c7c0;
__muldc3 = 0x40063c90;
__muldf3 = 0x4006358c;
__muldi3 = 0x4000c9fc;
__mulsf3 = 0x400632c8;
__mulsi3 = 0x4000c7b0;
__mulvdi3 = 0x40002d78;
__mulvsi3 = 0x40002d60;
__nedf2 = 0x400636a8;
__negdf2 = 0x400634a0;
__negdi2 = 0x4000ca14;
__negsf2 = 0x400020c0;
__negvdi2 = 0x40002e98;
__negvsi2 = 0x40002e78;
__nesf2 = 0x40063374;
__nsau_data = 0x3ff96544;
__paritysi2 = 0x40002f3c;
__popcount_tab = 0x3ff96544;
__popcountdi2 = 0x40002ef8;
__popcountsi2 = 0x40002ed0;
__powidf2 = 0x400638e4;
__subdf3 = 0x400026e4;
__subsf3 = 0x400021d0;
__subvdi3 = 0x40002d20;
__subvsi3 = 0x40002cf8;
__truncdfsf2 = 0x40002b90;
__ucmpdi2 = 0x40063840;
__udiv_w_sdiv = 0x40064bec;
__udivdi3 = 0x4000cff8;
__udivmoddi4 = 0x40064bf4;
__udivsi3 = 0x4000c7c8;
__umoddi3 = 0x4000d280;
__umodsi3 = 0x4000c7d0;
__umulsidi3 = 0x4000c7d8;
__unorddf2 = 0x400637f4;
__unordsf2 = 0x40063478;

View File

@ -0,0 +1,38 @@
/*
ROM Functions defined in this file are not used in ESP-IDF as is,
and different definitions for functions with the same names are provided.
This file is not used when linking ESP-IDF and is intended for reference only
*/
PROVIDE ( abort = 0x4000bba4 );
PROVIDE ( aes_128_cbc_decrypt = 0x4005cc7c );
PROVIDE ( aes_128_cbc_encrypt = 0x4005cc18 );
PROVIDE ( aes_unwrap = 0x4005ccf0 );
PROVIDE ( base64_decode = 0x4005ced8 );
PROVIDE ( base64_encode = 0x4005cdbc );
PROVIDE ( ets_isr_mask = 0x400067fc );
PROVIDE ( ets_isr_unmask = 0x40006808 );
PROVIDE ( ets_timer_arm = 0x40008368 );
PROVIDE ( ets_timer_arm_us = 0x400083ac );
PROVIDE ( ets_timer_disarm = 0x400083ec );
PROVIDE ( ets_timer_done = 0x40008428 );
PROVIDE ( ets_timer_init = 0x400084e8 );
PROVIDE ( ets_timer_handler_isr = 0x40008454 );
PROVIDE ( ets_timer_setfn = 0x40008350 );
PROVIDE ( hmac_md5 = 0x4005d264 );
PROVIDE ( hmac_md5_vector = 0x4005d17c );
PROVIDE ( hmac_sha1 = 0x40060acc );
PROVIDE ( hmac_sha1_vector = 0x400609e4 );
PROVIDE ( hmac_sha256 = 0x40060d58 );
PROVIDE ( hmac_sha256_vector = 0x40060c84 );
PROVIDE ( MD5Final = 0x4005db1c );
PROVIDE ( MD5Init = 0x4005da7c );
PROVIDE ( MD5Update = 0x4005da9c );
PROVIDE ( md5_vector = 0x4005db80 );
PROVIDE ( pbkdf2_sha1 = 0x40060ba4 );
PROVIDE ( rc4_skip = 0x40060928 );
PROVIDE ( sha1_prf = 0x40060ae8 );
PROVIDE ( sha1_vector = 0x40060b64 );
PROVIDE ( sha256_prf = 0x40060d70 );
PROVIDE ( sha256_vector = 0x40060e08 );
PROVIDE ( uart_tx_wait_idle = 0x40009278 );

View File

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
Address table for SPI driver functions in ESP32 ROM.
These functions are only linked from ROM when SPI_FLASH_ROM_DRIVER_PATCH is not set in configuration.
*/
PROVIDE ( esp_rom_spiflash_write_encrypted = 0x40062e78 );
PROVIDE ( esp_rom_spiflash_erase_area = 0x400631ac );
PROVIDE ( esp_rom_spiflash_erase_block = 0x40062c4c );
PROVIDE ( esp_rom_spiflash_erase_chip = 0x40062c14 );
PROVIDE ( esp_rom_spiflash_erase_sector = 0x40062ccc );
PROVIDE ( esp_rom_spiflash_attach = 0x40062a6c );
PROVIDE ( esp_rom_spiflash_lock = 0x400628f0 );
PROVIDE ( esp_rom_spiflash_read = 0x40062ed8 );
PROVIDE ( esp_rom_spiflash_config_readmode = 0x40062b64 ); /* SPIMasterReadModeCnfig */
PROVIDE ( esp_rom_spiflash_read_status = 0x4006226c );
PROVIDE ( esp_rom_spiflash_read_statushigh = 0x40062448 );
PROVIDE ( esp_rom_spiflash_write = 0x40062d50 );
PROVIDE ( esp_rom_spiflash_enable_write = 0x40062320 );
PROVIDE ( esp_rom_spiflash_write_status = 0x400622f0 );
/* always using patched versions of these functions
PROVIDE ( esp_rom_spiflash_wait_idle = 0x400622c0 );
PROVIDE ( esp_rom_spiflash_unlock = 0x400????? );
*/

View File

@ -0,0 +1,66 @@
/* These ROM functions call respective entries in the syscall table.
They are called by other ROM functions (mostly from newlib).
We don't link to them directly, since in IDF there are actual
implementations of these functions, with same names.
I.e.:
times (in ROM) -> _times_r (in ROM) -> syscall table entry _times_r -> _times_r (in IDF)
Hence the following entries are provided only for reference
and commented out.
*/
/* <--- the following lines are commented out
PROVIDE ( calloc = 0x4000bee4 );
PROVIDE ( free = 0x4000beb8 );
PROVIDE ( _free_r = 0x4000bbcc );
PROVIDE ( _getpid_r = 0x4000bcfc );
PROVIDE ( __getreent = 0x4000be8c );
PROVIDE ( _gettimeofday_r = 0x4000bc58 );
PROVIDE ( _kill_r = 0x4000bd10 );
PROVIDE ( _lock_acquire = 0x4000be14 );
PROVIDE ( _lock_acquire_recursive = 0x4000be28 );
PROVIDE ( _lock_close = 0x4000bdec );
PROVIDE ( _lock_close_recursive = 0x4000be00 );
PROVIDE ( _lock_init = 0x4000bdc4 );
PROVIDE ( _lock_init_recursive = 0x4000bdd8 );
PROVIDE ( _lock_release = 0x4000be64 );
PROVIDE ( _lock_release_recursive = 0x4000be78 );
PROVIDE ( _lock_try_acquire = 0x4000be3c );
PROVIDE ( _lock_try_acquire_recursive = 0x4000be50 );
PROVIDE ( malloc = 0x4000bea0 );
PROVIDE ( _malloc_r = 0x4000bbb4 );
PROVIDE ( _raise_r = 0x4000bc70 );
PROVIDE ( realloc = 0x4000becc );
PROVIDE ( _realloc_r = 0x4000bbe0 );
PROVIDE ( _sbrk_r = 0x4000bce4 );
PROVIDE ( _system_r = 0x4000bc10 );
PROVIDE ( _times_r = 0x4000bc40 );
PROVIDE ( _close_r = 0x4000bd3c );
PROVIDE ( _exit_r = 0x4000bd28 );
PROVIDE ( _fstat_r = 0x4000bccc );
PROVIDE ( _link_r = 0x4000bc9c );
PROVIDE ( _lseek_r = 0x4000bd8c );
PROVIDE ( _open_r = 0x4000bd54 );
PROVIDE ( _read_r = 0x4000bda8 );
PROVIDE ( _rename_r = 0x4000bc28 );
PROVIDE ( _unlink_r = 0x4000bc84 );
PROVIDE ( _write_r = 0x4000bd70 );
---> end commented out block
*/
/* These are the non-reentrant versions of syscalls present in the ROM.
They call the reentrant versions, passing the pointer returned by __getreent
as the first argument.
*/
close = 0x40001778;
open = 0x4000178c;
read = 0x400017dc;
sbrk = 0x400017f4;
times = 0x40001808;
write = 0x4000181c;

View File

@ -36,14 +36,6 @@ PROVIDE(_mp_hook = default_mp_hook);
PROVIDE(_start_trap = default_start_trap);
/* esp32c2 fixups */
SECTIONS {
.text.dummy (NOLOAD) :
{
/* This section is intended to make _stext address work */
. = ABSOLUTE(_stext);
} > ROTEXT
}
INSERT BEFORE .text;
SECTIONS {
.trap : ALIGN(4)
@ -88,11 +80,12 @@ PROVIDE(__global_pointer$ = _data_start + 0x800);
/* end of esp32c2 fixups */
/* Shared sections - ordering matters */
INCLUDE "text.x"
INCLUDE "rodata.x"
INCLUDE "rwtext.x"
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "stack.x"
INCLUDE "dram2.x"
/* End of Shared sections */
INCLUDE "debug.x"

View File

@ -12,12 +12,14 @@ MEMORY
[0x4037C000, 0x403C0000, "IRAM"]]
*/
/* 272K of on soc RAM, 16K reserved for cache */
ICACHE : ORIGIN = 0x4037C000, LENGTH = 16K
ICACHE : ORIGIN = 0x4037C000, LENGTH = 16K
/* Instruction RAM */
IRAM : ORIGIN = 0x4037C000 + 16K, LENGTH = 272K - 16K
IRAM : ORIGIN = 0x4037C000 + LENGTH(ICACHE), LENGTH = 186k
/* Data RAM */
DRAM : ORIGIN = 0x3FCA0000, LENGTH = 0x30000
DRAM : ORIGIN = 0x3FCA0000, LENGTH = 186k
/* memory available after the 2nd stage bootloader is finished */
dram2_seg ( RW ) : ORIGIN = ORIGIN(DRAM) + LENGTH(DRAM), len = 0x3fcdeb70 - (ORIGIN(DRAM) + LENGTH(DRAM))
/* External flash */
/* Instruction ROM */

View File

@ -1,23 +1,8 @@
PROVIDE(ets_delay_us = 0x40000044);
PROVIDE(ets_update_cpu_frequency_rom = 0x40000774);
PROVIDE(rom_i2c_writeReg = 0x400022f4);
PROVIDE(rom_i2c_writeReg_Mask = 0x400022fc);
PROVIDE(rtc_get_reset_reason = 0x40000018);
PROVIDE(software_reset = 0x40000088);
PROVIDE(software_reset_cpu = 0x4000008c);
INCLUDE "rom/esp32c2.rom.api.ld"
INCLUDE "rom/esp32c2.rom.heap.ld"
INCLUDE "rom/esp32c2.rom.ld"
INCLUDE "rom/esp32c2.rom.libgcc.ld"
INCLUDE "rom/esp32c2.rom.rvfp.ld"
INCLUDE "rom/esp32c2.rom.version.ld"
PROVIDE(esp_rom_crc32_be = 0x40000808);
PROVIDE(esp_rom_crc16_be = 0x4000080c);
PROVIDE(esp_rom_crc8_be = 0x40000810);
PROVIDE(esp_rom_crc32_le = 0x400007fc);
PROVIDE(esp_rom_crc16_le = 0x40000800);
PROVIDE(esp_rom_crc8_le = 0x40000804);
PROVIDE(esp_rom_mbedtls_md5_starts_ret = 0x40002be4);
PROVIDE(esp_rom_mbedtls_md5_update_ret = 0x40002be8);
PROVIDE(esp_rom_mbedtls_md5_finish_ret = 0x40002bec);
memset = 0x40000488;
memcpy = 0x4000048c;
memmove = 0x40000490;
memcmp = 0x40000494;
INCLUDE "rom/additional.ld"

View File

@ -0,0 +1,15 @@
memset = 0x40000488;
memcpy = 0x4000048c;
memmove = 0x40000490;
memcmp = 0x40000494;
strcpy = 0x40000498;
strncpy = 0x4000049c;
strncmp = 0x400004a4;
PROVIDE ( strcat = 0x4000050c );
PROVIDE ( strcmp = 0x400004a0 );
PROVIDE ( strchr = 0x40000514 );
PROVIDE ( strlcpy = 0x40000524 );
PROVIDE ( strstr = 0x400004ac );
PROVIDE ( strcasecmp = 0x40000504 );

View File

@ -0,0 +1,69 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** ROM APIs
*/
PROVIDE ( esp_rom_crc32_le = crc32_le );
PROVIDE ( esp_rom_crc16_le = crc16_le );
PROVIDE ( esp_rom_crc8_le = crc8_le );
PROVIDE ( esp_rom_crc32_be = crc32_be );
PROVIDE ( esp_rom_crc16_be = crc16_be );
PROVIDE ( esp_rom_crc8_be = crc8_be );
PROVIDE ( esp_rom_gpio_pad_select_gpio = gpio_pad_select_gpio );
PROVIDE ( esp_rom_gpio_pad_pullup_only = gpio_pad_pullup );
PROVIDE ( esp_rom_gpio_pad_set_drv = gpio_pad_set_drv );
PROVIDE ( esp_rom_gpio_pad_unhold = gpio_pad_unhold );
PROVIDE ( esp_rom_gpio_connect_in_signal = gpio_matrix_in );
PROVIDE ( esp_rom_gpio_connect_out_signal = gpio_matrix_out );
PROVIDE ( esp_rom_efuse_mac_address_crc8 = esp_crc8 );
PROVIDE ( esp_rom_efuse_is_secure_boot_enabled = ets_efuse_secure_boot_enabled );
PROVIDE ( esp_rom_uart_flush_tx = uart_tx_flush );
PROVIDE ( esp_rom_uart_tx_one_char = uart_tx_one_char );
PROVIDE ( esp_rom_uart_tx_wait_idle = uart_tx_wait_idle );
PROVIDE ( esp_rom_uart_rx_one_char = uart_rx_one_char );
PROVIDE ( esp_rom_uart_rx_string = UartRxString );
PROVIDE ( esp_rom_uart_set_as_console = uart_tx_switch );
PROVIDE ( esp_rom_uart_putc = ets_write_char_uart );
PROVIDE ( esp_rom_output_flush_tx = uart_tx_flush );
PROVIDE ( esp_rom_output_tx_one_char = uart_tx_one_char );
PROVIDE ( esp_rom_output_tx_wait_idle = uart_tx_wait_idle );
PROVIDE ( esp_rom_output_rx_one_char = uart_rx_one_char );
PROVIDE ( esp_rom_output_rx_string = UartRxString );
PROVIDE ( esp_rom_output_set_as_console = uart_tx_switch );
PROVIDE ( esp_rom_output_putc = ets_write_char_uart );
PROVIDE ( esp_rom_mbedtls_md5_starts_ret = mbedtls_md5_starts_ret );
PROVIDE ( esp_rom_mbedtls_md5_update_ret = mbedtls_md5_update_ret );
PROVIDE ( esp_rom_mbedtls_md5_finish_ret = mbedtls_md5_finish_ret );
PROVIDE ( esp_rom_software_reset_system = software_reset );
PROVIDE ( esp_rom_software_reset_cpu = software_reset_cpu );
PROVIDE ( esp_rom_printf = ets_printf );
PROVIDE ( esp_rom_install_uart_printf = ets_install_uart_printf );
PROVIDE ( esp_rom_delay_us = ets_delay_us );
PROVIDE ( esp_rom_get_reset_reason = rtc_get_reset_reason );
PROVIDE ( esp_rom_route_intr_matrix = intr_matrix_set );
PROVIDE ( esp_rom_get_cpu_ticks_per_us = ets_get_cpu_frequency );
PROVIDE ( esp_rom_set_cpu_ticks_per_us = ets_update_cpu_frequency );
PROVIDE ( esp_rom_spiflash_attach = spi_flash_attach );
PROVIDE ( esp_rom_spiflash_clear_bp = esp_rom_spiflash_unlock );
PROVIDE ( esp_rom_spiflash_write_enable = SPI_write_enable);
PROVIDE ( esp_rom_spiflash_erase_area = SPIEraseArea );
PROVIDE ( esp_rom_spiflash_fix_dummylen = spi_dummy_len_fix );
PROVIDE ( esp_rom_spiflash_set_drvs = SetSpiDrvs);
PROVIDE ( esp_rom_spiflash_select_padsfunc = SelectSpiFunction );
PROVIDE ( esp_rom_spiflash_common_cmd = SPI_Common_Command );
PROVIDE ( esp_rom_regi2c_read = rom_i2c_readReg );
PROVIDE ( esp_rom_regi2c_read_mask = rom_i2c_readReg_Mask );
PROVIDE ( esp_rom_regi2c_write = rom_i2c_writeReg );
PROVIDE ( esp_rom_regi2c_write_mask = rom_i2c_writeReg_Mask );

View File

@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/***************************************
Group heap
***************************************/
/* Functions */
PROVIDE( tlsf_create = 0x400002dc );
PROVIDE( tlsf_create_with_pool = 0x400002e0 );
PROVIDE( tlsf_get_pool = 0x400002e4 );
PROVIDE( tlsf_add_pool = 0x400002e8 );
PROVIDE( tlsf_remove_pool = 0x400002ec );
PROVIDE( tlsf_malloc = 0x400002f0 );
PROVIDE( tlsf_memalign = 0x400002f4 );
PROVIDE( tlsf_memalign_offs = 0x400002f8 );
PROVIDE( tlsf_realloc = 0x400002fc );
PROVIDE( tlsf_free = 0x40000300 );
PROVIDE( tlsf_block_size = 0x40000304 );
PROVIDE( tlsf_size = 0x40000308 );
PROVIDE( tlsf_align_size = 0x4000030c );
PROVIDE( tlsf_block_size_min = 0x40000310 );
PROVIDE( tlsf_block_size_max = 0x40000314 );
PROVIDE( tlsf_pool_overhead = 0x40000318 );
PROVIDE( tlsf_alloc_overhead = 0x4000031c );
PROVIDE( tlsf_walk_pool = 0x40000320 );
PROVIDE( tlsf_check = 0x40000324 );
PROVIDE( tlsf_check_pool = 0x40000328 );
PROVIDE( tlsf_poison_fill_pfunc_set = 0x4000032c );
PROVIDE( multi_heap_get_block_address_impl = 0x40000330 );
PROVIDE( multi_heap_get_allocated_size_impl = 0x40000334 );
PROVIDE( multi_heap_register_impl = 0x40000338 );
PROVIDE( multi_heap_set_lock = 0x4000033c );
PROVIDE( multi_heap_os_funcs_init = 0x40000340 );
PROVIDE( multi_heap_internal_lock = 0x40000344 );
PROVIDE( multi_heap_internal_unlock = 0x40000348 );
PROVIDE( multi_heap_get_first_block = 0x4000034c );
PROVIDE( multi_heap_get_next_block = 0x40000350 );
PROVIDE( multi_heap_is_free = 0x40000354 );
PROVIDE( multi_heap_malloc_impl = 0x40000358 );
PROVIDE( multi_heap_free_impl = 0x4000035c );
PROVIDE( multi_heap_realloc_impl = 0x40000360 );
PROVIDE( multi_heap_aligned_alloc_impl_offs = 0x40000364 );
PROVIDE( multi_heap_aligned_alloc_impl = 0x40000368 );
PROVIDE( multi_heap_check = 0x4000036c );
PROVIDE( multi_heap_dump = 0x40000370 );
PROVIDE( multi_heap_free_size_impl = 0x40000374 );
PROVIDE( multi_heap_minimum_free_size_impl = 0x40000378 );
PROVIDE( multi_heap_get_info_impl = 0x4000037c );
/* Data (.data, .bss, .rodata) */
PROVIDE( heap_tlsf_table_ptr = 0x3fcdffec );
/**
* Multi heap function
*/
PROVIDE (multi_heap_malloc = multi_heap_malloc_impl);
PROVIDE (multi_heap_free = multi_heap_free_impl);
PROVIDE (multi_heap_realloc = multi_heap_realloc_impl);
PROVIDE (multi_heap_get_allocated_size = multi_heap_get_allocated_size_impl);
PROVIDE (multi_heap_register = multi_heap_register_impl);
PROVIDE (multi_heap_get_info = multi_heap_get_info_impl);
PROVIDE (multi_heap_free_size = multi_heap_free_size_impl);
PROVIDE (multi_heap_minimum_free_size = multi_heap_minimum_free_size_impl);
PROVIDE (multi_heap_get_block_address = multi_heap_get_block_address_impl);
PROVIDE (multi_heap_aligned_alloc = multi_heap_aligned_alloc_impl);
PROVIDE (multi_heap_aligned_free = multi_heap_aligned_free_impl);
PROVIDE (multi_heap_check = multi_heap_check);
PROVIDE (multi_heap_set_lock = multi_heap_set_lock);
PROVIDE (multi_heap_internal_lock = multi_heap_internal_lock);
PROVIDE (multi_heap_internal_unlock = multi_heap_internal_unlock);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ROM function interface esp32c2.rom.libgcc.ld for esp32c2
*
*
* Generated from ./interface-esp32c2.yml md5sum c679b6ed5e9f0a9c3e7b93e5e0f2a1a3
*
* Compatible with ROM where ECO version equal or greater to 1.
*
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
*/
/***************************************
Group libgcc
***************************************/
/* Functions */
__absvdi2 = 0x400008a8;
__absvsi2 = 0x400008ac;
__adddf3 = 0x400008b0;
__addsf3 = 0x400008b4;
__addvdi3 = 0x400008b8;
__addvsi3 = 0x400008bc;
__ashldi3 = 0x400008c0;
__ashrdi3 = 0x400008c4;
__bswapdi2 = 0x400008c8;
__bswapsi2 = 0x400008cc;
__clear_cache = 0x400008d0;
__clrsbdi2 = 0x400008d4;
__clrsbsi2 = 0x400008d8;
__clzdi2 = 0x400008dc;
__clzsi2 = 0x400008e0;
__cmpdi2 = 0x400008e4;
__ctzdi2 = 0x400008e8;
__ctzsi2 = 0x400008ec;
__divdc3 = 0x400008f0;
__divdf3 = 0x400008f4;
__divdi3 = 0x400008f8;
__divsc3 = 0x400008fc;
__divsf3 = 0x40000900;
__divsi3 = 0x40000904;
__eqdf2 = 0x40000908;
__eqsf2 = 0x4000090c;
__extendsfdf2 = 0x40000910;
__ffsdi2 = 0x40000914;
__ffssi2 = 0x40000918;
__fixdfdi = 0x4000091c;
__fixdfsi = 0x40000920;
__fixsfdi = 0x40000924;
__fixsfsi = 0x40000928;
__fixunsdfsi = 0x4000092c;
__fixunssfdi = 0x40000930;
__fixunssfsi = 0x40000934;
__floatdidf = 0x40000938;
__floatdisf = 0x4000093c;
__floatsidf = 0x40000940;
__floatsisf = 0x40000944;
__floatundidf = 0x40000948;
__floatundisf = 0x4000094c;
__floatunsidf = 0x40000950;
__floatunsisf = 0x40000954;
__gcc_bcmp = 0x40000958;
__gedf2 = 0x4000095c;
__gesf2 = 0x40000960;
__gtdf2 = 0x40000964;
__gtsf2 = 0x40000968;
__ledf2 = 0x4000096c;
__lesf2 = 0x40000970;
__lshrdi3 = 0x40000974;
__ltdf2 = 0x40000978;
__ltsf2 = 0x4000097c;
__moddi3 = 0x40000980;
__modsi3 = 0x40000984;
__muldc3 = 0x40000988;
__muldf3 = 0x4000098c;
__muldi3 = 0x40000990;
__mulsc3 = 0x40000994;
__mulsf3 = 0x40000998;
__mulsi3 = 0x4000099c;
__mulvdi3 = 0x400009a0;
__mulvsi3 = 0x400009a4;
__nedf2 = 0x400009a8;
__negdf2 = 0x400009ac;
__negdi2 = 0x400009b0;
__negsf2 = 0x400009b4;
__negvdi2 = 0x400009b8;
__negvsi2 = 0x400009bc;
__nesf2 = 0x400009c0;
__paritysi2 = 0x400009c4;
__popcountdi2 = 0x400009c8;
__popcountsi2 = 0x400009cc;
__powidf2 = 0x400009d0;
__powisf2 = 0x400009d4;
__subdf3 = 0x400009d8;
__subsf3 = 0x400009dc;
__subvdi3 = 0x400009e0;
__subvsi3 = 0x400009e4;
__truncdfsf2 = 0x400009e8;
__ucmpdi2 = 0x400009ec;
__udivdi3 = 0x400009f0;
__udivmoddi4 = 0x400009f4;
__udivsi3 = 0x400009f8;
__udiv_w_sdiv = 0x400009fc;
__umoddi3 = 0x40000a00;
__umodsi3 = 0x40000a04;
__unorddf2 = 0x40000a08;
__unordsf2 = 0x40000a0c;
__extenddftf2 = 0x40000a10;
__trunctfdf2 = 0x40000a14;

View File

@ -0,0 +1,118 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ROM function interface esp32c2.rom.rvfp.ld esp32c2
*
*
* Generated from ./interface-esp32c2.yml md5sum c679b6ed5e9f0a9c3e7b93e5e0f2a1a3
*
* Compatible with ROM where ECO version equal or greater to 1.
*
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
*/
/***************************************
Group rvfplib
***************************************/
/* Functions */
__adddf3 = 0x40000a18;
__addsf3 = 0x40000a1c;
__divsf3 = 0x40000a20;
__eqdf2 = 0x40000a24;
__eqsf2 = 0x40000a28;
__extendsfdf2 = 0x40000a2c;
__fixdfdi = 0x40000a30;
__fixdfsi = 0x40000a34;
__fixsfdi = 0x40000a38;
__fixsfsi = 0x40000a3c;
__fixunsdfsi = 0x40000a40;
__fixunssfdi = 0x40000a44;
__fixunssfsi = 0x40000a48;
__floatdidf = 0x40000a4c;
__floatdisf = 0x40000a50;
__floatsidf = 0x40000a54;
__floatsisf = 0x40000a58;
__floatundidf = 0x40000a5c;
__floatundisf = 0x40000a60;
__floatunsidf = 0x40000a64;
__floatunsisf = 0x40000a68;
__gedf2 = 0x40000a6c;
__gesf2 = 0x40000a70;
__gtdf2 = 0x40000a74;
__gtsf2 = 0x40000a78;
__ledf2 = 0x40000a7c;
__lesf2 = 0x40000a80;
__ltdf2 = 0x40000a84;
__ltsf2 = 0x40000a88;
__muldf3 = 0x40000a8c;
__mulsf3 = 0x40000a90;
__nedf2 = 0x40000a94;
__nesf2 = 0x40000a98;
__subdf3 = 0x40000a9c;
__subsf3 = 0x40000aa0;
__truncdfsf2 = 0x40000aa4;
/***************************************
Group libgcc
***************************************/
/* Functions */
__absvdi2 = 0x400008a8;
__absvsi2 = 0x400008ac;
__addvdi3 = 0x400008b8;
__addvsi3 = 0x400008bc;
__ashldi3 = 0x400008c0;
__ashrdi3 = 0x400008c4;
__bswapdi2 = 0x400008c8;
__bswapsi2 = 0x400008cc;
__clear_cache = 0x400008d0;
__clrsbdi2 = 0x400008d4;
__clrsbsi2 = 0x400008d8;
__clzdi2 = 0x400008dc;
__clzsi2 = 0x400008e0;
__cmpdi2 = 0x400008e4;
__ctzdi2 = 0x400008e8;
__ctzsi2 = 0x400008ec;
__divdc3 = 0x400008f0;
__divdf3 = 0x400008f4;
__divdi3 = 0x400008f8;
__divsc3 = 0x400008fc;
__divsi3 = 0x40000904;
__ffsdi2 = 0x40000914;
__ffssi2 = 0x40000918;
__gcc_bcmp = 0x40000958;
__lshrdi3 = 0x40000974;
__moddi3 = 0x40000980;
__modsi3 = 0x40000984;
__muldc3 = 0x40000988;
__muldi3 = 0x40000990;
__mulsc3 = 0x40000994;
__mulsi3 = 0x4000099c;
__mulvdi3 = 0x400009a0;
__mulvsi3 = 0x400009a4;
__negdf2 = 0x400009ac;
__negdi2 = 0x400009b0;
__negsf2 = 0x400009b4;
__negvdi2 = 0x400009b8;
__negvsi2 = 0x400009bc;
__paritysi2 = 0x400009c4;
__popcountdi2 = 0x400009c8;
__popcountsi2 = 0x400009cc;
__powidf2 = 0x400009d0;
__powisf2 = 0x400009d4;
__subvdi3 = 0x400009e0;
__subvsi3 = 0x400009e4;
__ucmpdi2 = 0x400009ec;
__udivdi3 = 0x400009f0;
__udivmoddi4 = 0x400009f4;
__udivsi3 = 0x400009f8;
__udiv_w_sdiv = 0x400009fc;
__umoddi3 = 0x40000a00;
__umodsi3 = 0x40000a04;
__unorddf2 = 0x40000a08;
__unordsf2 = 0x40000a0c;
__extenddftf2 = 0x40000a10;
__trunctfdf2 = 0x40000a14;

View File

@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ROM version variables for esp32c2
*
* These addresses should be compatible with any ROM version for this chip.
*
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
*/
_rom_chip_id = 0x40000010;
_rom_eco_version = 0x40000014;

View File

@ -36,14 +36,6 @@ PROVIDE(_mp_hook = default_mp_hook);
PROVIDE(_start_trap = default_start_trap);
/* esp32c3 fixups */
SECTIONS {
.text.dummy (NOLOAD) :
{
/* This section is intended to make _stext address work */
. = ABSOLUTE(_stext);
} > ROTEXT
}
INSERT BEFORE .text;
SECTIONS {
.trap : ALIGN(4)
@ -88,12 +80,13 @@ PROVIDE(__global_pointer$ = _data_start + 0x800);
/* end of esp32c3 fixups */
/* Shared sections - ordering matters */
INCLUDE "text.x"
INCLUDE "rodata.x"
INCLUDE "rwtext.x"
INCLUDE "text.x"
INCLUDE "rwdata.x"
INCLUDE "rodata.x"
INCLUDE "rtc_fast.x"
INCLUDE "stack.x"
INCLUDE "dram2.x"
/* End of Shared sections */
INCLUDE "debug.x"

View File

@ -13,14 +13,15 @@ MEMORY
[0x50000000, 0x50002000, "RTC_IRAM"],
[0x50000000, 0x50002000, "RTC_DRAM"],
[0x600FE000, 0x60100000, "MEM_INTERNAL2"]]
*/
/* 400K of on soc RAM, 16K reserved for cache */
ICACHE : ORIGIN = 0x4037C000, LENGTH = 0x4000
/* Instruction RAM */
IRAM : ORIGIN = 0x4037C000 + 0x4000, LENGTH = 400K - 0x4000
IRAM : ORIGIN = 0x4037C000 + 0x4000, LENGTH = 313K - 0x4000
/* Data RAM */
DRAM : ORIGIN = 0x3FC80000, LENGTH = 0x50000
DRAM : ORIGIN = 0x3FC80000, LENGTH = 313K
/* memory available after the 2nd stage bootloader is finished */
dram2_seg ( RW ) : ORIGIN = ORIGIN(DRAM) + LENGTH(DRAM), len = 0x3fcde710 - (ORIGIN(DRAM) + LENGTH(DRAM))
/* External flash */
/* Instruction ROM */

View File

@ -1,30 +1,10 @@
ets_printf = 0x40000040;
PROVIDE(esp_rom_printf = ets_printf);
PROVIDE(cache_invalidate_icache_all = 0x400004d8);
PROVIDE(cache_suspend_icache = 0x40000524);
PROVIDE(cache_resume_icache = 0x40000528);
PROVIDE(cache_ibus_mmu_set = 0x40000560);
PROVIDE(cache_dbus_mmu_set = 0x40000564);
PROVIDE(ets_delay_us = 0x40000050);
PROVIDE(ets_update_cpu_frequency_rom = 0x40000588);
PROVIDE(rom_i2c_writeReg = 0x4000195c);
PROVIDE(rom_i2c_writeReg_Mask = 0x40001960);
PROVIDE(rtc_get_reset_reason = 0x40000018);
PROVIDE(software_reset = 0x40000090);
PROVIDE(software_reset_cpu = 0x40000094);
INCLUDE "rom/esp32c3.rom.api.ld"
INCLUDE "rom/esp32c3.rom.eco3.ld"
/* TODO
INCLUDE "rom/esp32c3.rom.eco7.ld"
*/
INCLUDE "rom/esp32c3.rom.ld"
INCLUDE "rom/esp32c3.rom.libgcc.ld"
INCLUDE "rom/esp32c3.rom.version.ld"
PROVIDE(esp_rom_crc32_be = 0x4000062c);
PROVIDE(esp_rom_crc16_be = 0x40000634);
PROVIDE(esp_rom_crc8_be = 0x4000063c);
PROVIDE(esp_rom_crc32_le = 0x40000628);
PROVIDE(esp_rom_crc16_le = 0x40000630);
PROVIDE(esp_rom_crc8_le = 0x40000638);
PROVIDE(esp_rom_md5_init = 0x40000614);
PROVIDE(esp_rom_md5_update = 0x40000618);
PROVIDE(esp_rom_md5_final = 0x4000061c);
memset = 0x40000354;
memcpy = 0x40000358;
memmove = 0x4000035c;
memcmp = 0x40000360;
INCLUDE "rom/additional.ld"

View File

@ -0,0 +1,21 @@
memset = 0x40000354;
memcpy = 0x40000358;
memmove = 0x4000035c;
memcmp = 0x40000360;
strncmp = 0x40000370;
strncpy = 0x40000368;
strcpy = 0x40000364;
abs = 0x40000424;
PROVIDE(cache_dbus_mmu_set = 0x40000564);
PROVIDE( strcat = 0x400003d8 );
PROVIDE( strcmp = 0x4000036c );
PROVIDE( strchr = 0x400003e0 );
PROVIDE( strlcpy = 0x400003f0 );
PROVIDE( strstr = 0x40000378 );
PROVIDE( strcasecmp = 0x400003d0 );
PROVIDE( memchr = 0x400003c8 );

View File

@ -0,0 +1,61 @@
/**
* ROM APIs
*/
PROVIDE ( esp_rom_crc32_le = crc32_le );
PROVIDE ( esp_rom_crc16_le = crc16_le );
PROVIDE ( esp_rom_crc8_le = crc8_le );
PROVIDE ( esp_rom_crc32_be = crc32_be );
PROVIDE ( esp_rom_crc16_be = crc16_be );
PROVIDE ( esp_rom_crc8_be = crc8_be );
PROVIDE ( esp_rom_gpio_pad_select_gpio = gpio_pad_select_gpio );
PROVIDE ( esp_rom_gpio_pad_pullup_only = gpio_pad_pullup );
PROVIDE ( esp_rom_gpio_pad_set_drv = gpio_pad_set_drv );
PROVIDE ( esp_rom_gpio_pad_unhold = gpio_pad_unhold );
PROVIDE ( esp_rom_gpio_connect_in_signal = gpio_matrix_in );
PROVIDE ( esp_rom_gpio_connect_out_signal = gpio_matrix_out );
PROVIDE ( esp_rom_efuse_mac_address_crc8 = esp_crc8 );
PROVIDE ( esp_rom_efuse_get_flash_gpio_info = ets_efuse_get_spiconfig );
PROVIDE ( esp_rom_efuse_is_secure_boot_enabled = ets_efuse_secure_boot_enabled );
PROVIDE ( esp_rom_efuse_get_flash_wp_gpio = ets_efuse_get_wp_pad );
PROVIDE ( esp_rom_uart_flush_tx = uart_tx_flush );
PROVIDE ( esp_rom_uart_tx_one_char = uart_tx_one_char );
PROVIDE ( esp_rom_uart_tx_wait_idle = uart_tx_wait_idle );
PROVIDE ( esp_rom_uart_rx_one_char = uart_rx_one_char );
PROVIDE ( esp_rom_uart_rx_string = UartRxString );
PROVIDE ( esp_rom_output_flush_tx = uart_tx_flush );
PROVIDE ( esp_rom_output_tx_one_char = uart_tx_one_char );
PROVIDE ( esp_rom_output_tx_wait_idle = uart_tx_wait_idle );
PROVIDE ( esp_rom_output_rx_one_char = uart_rx_one_char );
PROVIDE ( esp_rom_output_rx_string = UartRxString );
PROVIDE ( esp_rom_md5_init = MD5Init );
PROVIDE ( esp_rom_md5_update = MD5Update );
PROVIDE ( esp_rom_md5_final = MD5Final );
PROVIDE ( esp_rom_software_reset_system = software_reset );
PROVIDE ( esp_rom_software_reset_cpu = software_reset_cpu );
PROVIDE ( esp_rom_printf = ets_printf );
PROVIDE ( esp_rom_delay_us = ets_delay_us );
PROVIDE ( esp_rom_get_reset_reason = rtc_get_reset_reason );
PROVIDE ( esp_rom_route_intr_matrix = intr_matrix_set );
PROVIDE ( esp_rom_get_cpu_ticks_per_us = ets_get_cpu_frequency );
PROVIDE ( esp_rom_set_cpu_ticks_per_us = ets_update_cpu_frequency );
PROVIDE ( esp_rom_spiflash_clear_bp = esp_rom_spiflash_unlock );
PROVIDE ( esp_rom_spiflash_write_enable = SPI_write_enable );
PROVIDE ( esp_rom_spiflash_erase_area = SPIEraseArea );
PROVIDE ( esp_rom_spiflash_fix_dummylen = spi_dummy_len_fix );
PROVIDE ( esp_rom_spiflash_set_drvs = SetSpiDrvs);
PROVIDE ( esp_rom_spiflash_select_padsfunc = SelectSpiFunction );
PROVIDE ( esp_rom_spiflash_common_cmd = SPI_Common_Command );
PROVIDE ( esp_rom_regi2c_read = rom_i2c_readReg );
PROVIDE ( esp_rom_regi2c_read_mask = rom_i2c_readReg_Mask );
PROVIDE ( esp_rom_regi2c_write = rom_i2c_writeReg );
PROVIDE ( esp_rom_regi2c_write_mask = rom_i2c_writeReg_Mask );

View File

@ -0,0 +1,129 @@
/*
ESP32C3 ECO3 ROM address table
Version 3 API's imported from the ROM
*/
/*esf_buf_alloc_dynamic = 0x400015c0;*/
/*esf_buf_recycle = 0x400015c4;*/
/*lmacTxDone = 0x4000162c;*/
/*ppMapTxQueue = 0x400016d8;*/
/*rcGetSched = 0x40001764;*/
wDevCheckBlockError = 0x400017b4;
/*ppProcTxDone = 0x40001804;*/
/*sta_input = rom_sta_input;*/
/***************************************
Group rom_phy
***************************************/
/* Functions */
rom_index_to_txbbgain = 0x40001964;
rom_pbus_xpd_tx_on = 0x400019b0;
rom_set_tx_dig_gain = 0x400019f0;
rom_set_txcap_reg = 0x400019f4;
rom_txbbgain_to_index = 0x40001a0c;
rom_agc_reg_init = 0x40001a54;
rom_bb_reg_init = 0x40001a58;
rom_set_pbus_reg = 0x40001a70;
rom_phy_xpd_rf = 0x40001a78;
rom_write_txrate_power_offset = 0x40001a8c;
rom_temp_to_power = 0x40001ab4;
rom_open_i2c_xpd = 0x40001af8;
rom_tsens_read_init = 0x40001b00;
rom_tsens_code_read = 0x40001b04;
rom_tsens_dac_cal = 0x40001b10;
rom_pll_vol_cal = 0x40001b28;
/***************************************
Group eco3_wifi
***************************************/
/* Functions */
wdev_is_data_in_rxlist = 0x40001b2c;
ppProcTxCallback = 0x40001b30;
ieee80211_gettid = 0x40001b34;
/***************************************
Group eco3_bluetooth
***************************************/
/* Functions */
r_lld_legacy_adv_dynamic_pti_get = 0x40001b38;
r_lld_legacy_adv_dynamic_pti_process = 0x40001b3c;
r_lld_ext_adv_dynamic_pti_get = 0x40001b40;
r_lld_ext_adv_dynamic_aux_pti_process = 0x40001b44;
r_lld_ext_adv_dynamic_pti_process = 0x40001b48;
r_lld_adv_ext_pkt_prepare_set = 0x40001b4c;
r_lld_adv_ext_chain_connectable_construct = 0x40001b54;
r_lld_adv_pkt_rx_connect_post = 0x40001b5c;
r_lld_adv_start_init_evt_param = 0x40001b60;
r_lld_adv_start_set_cs = 0x40001b64;
/* r_lld_adv_start_update_filter_policy = 0x40001b68; */
r_lld_adv_start_schedule_asap = 0x40001b6c;
r_lld_con_tx_prog_new_packet_coex = 0x40001b70;
r_lld_per_adv_dynamic_pti_get = 0x40001b78;
r_lld_per_adv_evt_start_chm_upd = 0x40001b7c;
r_lld_ext_scan_dynamic_pti_get = 0x40001b80;
r_lld_sync_insert = 0x40001b88;
r_sch_prog_ble_push = 0x40001b8c;
r_sch_prog_bt_push = 0x40001b90;
r_lld_init_evt_end_type_set = 0x40001b94;
r_lld_init_evt_end_type_get = 0x40001b98;
r_lld_adv_direct_adv_use_rpa_addr_state_set = 0x40001b9c;
r_lld_adv_direct_adv_use_rpa_addr_state_get = 0x40001ba0;
r_lld_init_evt_end_type_check_state_set = 0x40001ba4;
r_lld_init_evt_end_type_check_state_get = 0x40001ba8;
/***************************************
Group eco3_phy
***************************************/
/* Functions */
rom_wrtie_pll_cap = 0x40001bac;
rom_set_tx_gain_mem = 0x40001bb0;
rom_bt_tx_dig_gain = 0x40001bb4;
rom_bt_get_tx_gain = 0x40001bb8;
rom_get_chan_target_power = 0x40001bbc;
rom_get_tx_gain_value = 0x40001bc0;
rom_wifi_tx_dig_gain = 0x40001bc4;
rom_wifi_get_tx_gain = 0x40001bc8;
rom_fe_i2c_reg_renew = 0x40001bcc;
rom_wifi_agc_sat_gain = 0x40001bd0;
rom_i2c_master_reset = 0x40001bd4;
rom_bt_filter_reg = 0x40001bd8;
rom_phy_bbpll_cal = 0x40001bdc;
rom_i2c_sar2_init_code = 0x40001be0;
rom_phy_param_addr = 0x40001be4;
rom_phy_reg_init = 0x40001be8;
rom_set_chan_reg = 0x40001bec;
rom_phy_wakeup_init = 0x40001bf0;
rom_phy_i2c_init1 = 0x40001bf4;
rom_tsens_temp_read = 0x40001bf8;
rom_bt_track_pll_cap = 0x40001bfc;
rom_wifi_track_pll_cap = 0x40001c00;
rom_wifi_set_tx_gain = 0x40001c04;
rom_txpwr_cal_track = 0x40001c08;
rom_tx_pwctrl_background = 0x40001c0c;
rom_bt_set_tx_gain = 0x40001c10;
rom_noise_check_loop = 0x40001c14;
rom_phy_close_rf = 0x40001c18;
rom_phy_xpd_tsens = 0x40001c1c;
rom_phy_freq_mem_backup = 0x40001c20;
rom_phy_ant_init = 0x40001c24;
rom_bt_track_tx_power = 0x40001c28;
rom_wifi_track_tx_power = 0x40001c2c;
rom_phy_dig_reg_backup = 0x40001c30;
chip726_phyrom_version_num = 0x40001c34;
/* Data (.data, .bss, .rodata) */
phy_param_rom = 0x3fcdf830;
/***************************************
Group eco3_esp_flash
***************************************/
/* Functions */
PROVIDE( esp_flash_read_chip_id = 0x40001c38 );
PROVIDE( detect_spi_flash_chip = 0x40001c3c );
PROVIDE( esp_rom_spiflash_write_disable = 0x40001c40 );

View File

@ -0,0 +1,240 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
esf_buf_alloc = 0x400015bc;
esf_buf_alloc_dynamic = 0x400015c0;
esf_buf_recycle = 0x400015c4;
/*hal_mac_tx_set_ppdu = 0x400015d4;*/
ic_mac_deinit = 0x400015dc;
lmacDiscardMSDU = 0x400015f4;
/*lmacSetTxFrame = 0x40001628;*/
lmacTxDone = 0x4000162c;
lmacTxFrame = 0x40001630;
mac_tx_set_htsig = 0x40001638;
mac_tx_set_plcp1 = 0x40001640;
pm_check_state = 0x40001648;
/*pm_on_beacon_rx = 0x4000167c;*/
/*pm_parse_beacon = 0x40001688;*/
pm_process_tim = 0x4000168c;
pm_rx_beacon_process = 0x40001690;
pm_rx_data_process = 0x40001694;
/* pm_sleep = 0x40001698;*/
/* pm_tbtt_process = 0x400016a0;*/
ppMapTxQueue = 0x400016d8;
ppProcTxSecFrame = 0x400016dc;
/*ppRxFragmentProc = 0x40001704;*/
/* rcGetSched = 0x40001764;*/
rcTxUpdatePer = 0x40001770;
rcUpdateTxDone = 0x4000177c;
wDevCheckBlockError = 0x400017b4;
/* wDev_IndicateFrame = 0x400017c8;*/
wDev_ProcessFiq = 0x400017f0;
/*wDev_ProcessRxSucData = 0x400017f4;*/
/*ppProcTxDone = 0x40001804;*/
/*pm_tx_data_done_process = 0x40001808;*/
ppMapWaitTxq = 0x40001810;
/*ieee80211_encap_esfbuf = 0x4000185c;*/
/*sta_input = 0x40001870;*/
ieee80211_crypto_decap = 0x4000189c;
ieee80211_decap = 0x400018a0;
/*coex_core_timer_idx_get = 0x400018d0;*/
rom1_chip_i2c_readReg = 0x40001924;
rom1_chip_i2c_writeReg = 0x40001928;
rom_index_to_txbbgain = 0x40001964;
rom_pbus_xpd_tx_on = 0x400019b0;
rom1_set_noise_floor = 0x400019e8;
rom_set_tx_dig_gain = 0x400019f0;
rom_set_txcap_reg = 0x400019f4;
rom_txbbgain_to_index = 0x40001a0c;
rom1_disable_wifi_agc = 0x40001a1c;
rom1_enable_wifi_agc = 0x40001a20;
rom1_tx_paon_set = 0x40001a44;
rom_agc_reg_init = 0x40001a54;
rom_bb_reg_init = 0x40001a58;
rom1_set_pbus_reg = 0x40001a70;
rom_phy_xpd_rf = 0x40001a78;
rom_write_txrate_power_offset = 0x40001a8c;
rom1_get_rate_fcc_index = 0x40001a90;
rom1_read_sar2_code = 0x40001aa4;
rom2_temp_to_power1 = 0x40001ab4;
rom1_get_i2c_hostid = 0x40001ac8;
rom_open_i2c_xpd = 0x40001af8;
rom2_tsens_read_init1 = 0x40001b00;
rom_tsens_code_read = 0x40001b04;
rom_tsens_dac_cal = 0x40001b10;
rom1_phy_en_hw_set_freq = 0x40001b20;
rom1_phy_dis_hw_set_freq = 0x40001b24;
rom_pll_vol_cal = 0x40001b28;
rom1_bt_get_tx_gain = 0x40001bb8;
rom1_get_chan_target_power = 0x40001bbc;
rom2_get_tx_gain_value1 = 0x40001bc0;
rom1_wifi_tx_dig_gain = 0x40001bc4;
rom1_wifi_get_tx_gain = 0x40001bc8;
rom1_fe_i2c_reg_renew = 0x40001bcc;
rom1_i2c_master_reset = 0x40001bd4;
rom1_phy_wakeup_init = 0x40001bf0;
rom1_phy_i2c_init1 = 0x40001bf4;
rom1_tsens_temp_read = 0x40001bf8;
rom1_bt_track_pll_cap = 0x40001bfc;
rom1_wifi_set_tx_gain = 0x40001c04;
rom1_txpwr_cal_track = 0x40001c08;
rom1_bt_set_tx_gain = 0x40001c10;
rom1_phy_close_rf = 0x40001c18;
/***************************************
Group eco7_uart
***************************************/
/* Functions */
uart_tx_switch = 0x40001c44;
/***************************************
Group eco7_bluetooth
***************************************/
/* Functions */
r_lld_con_count_get = 0x40001c48;
r_lld_update_con_offset = 0x40001c4c;
r_lld_con_update_last_clock = 0x40001c50;
r_lld_con_llcp_ind_info_clear = 0x40001c54;
r_lld_con_update_terminte_info_init = 0x40001c58;
r_lld_con_terminate_max_evt_update = 0x40001c5c;
r_llc_pref_param_compute_eco = 0x40001ce8;
r_llc_hci_con_upd_info_send_eco = 0x40001cec;
r_llc_rem_encrypt_proc_continue_eco = 0x40001cf0;
r_llc_start_eco = 0x40001cf8;
r_lld_ext_adv_dynamic_aux_pti_process_eco = 0x40001cfc;
r_lld_adv_start_eco = 0x40001d04;
r_lld_con_evt_canceled_cbk_eco = 0x40001d08;
r_lld_con_evt_time_update_eco = 0x40001d0c;
r_lld_con_start_eco = 0x40001d10;
r_lld_con_frm_isr_eco = 0x40001d14;
r_lld_con_tx_eco = 0x40001d18;
r_lld_ext_scan_dynamic_pti_process_eco = 0x40001d28;
r_lld_scan_frm_eof_isr_eco = 0x40001d2c;
r_lld_sync_start_eco = 0x40001d30;
r_lld_sync_insert_eco = 0x40001d34;
r_llm_adv_rep_flow_control_update_eco = 0x40001d38;
r_llm_env_adv_dup_filt_init_eco = 0x40001d3c;
r_llm_env_adv_dup_filt_deinit_eco = 0x40001d40;
r_llm_adv_rep_flow_control_check_eco = 0x40001d44;
r_llm_scan_start_eco = 0x40001d48;
r_llm_update_duplicate_scan_count = 0x40001d4c;
r_llc_hci_command_handler_pre = 0x40001d50;
r_llc_hci_command_handler_get = 0x40001d54;
r_llc_hci_command_handler_search = 0x40001d58;
r_llc_llcp_pdu_handler_get_overwrite = 0x40001d5c;
r_llc_llcp_pdu_handler_pre = 0x40001d60;
r_llc_llcp_pdu_handler_end = 0x40001d64;
r_llc_con_conflict_check = 0x40001d6c;
r_sch_prog_hw_reset_try = 0x40001d70;
r_sch_prog_et_state_reset = 0x40001d74;
r_sch_prog_end_isr_handler = 0x40001d78;
r_sch_plan_conflict_check = 0x40001d7c;
r_rwble_isr_hw_fixed = 0x40001d80;
r_bt_bb_recorrect_is_dead = 0x40001d84;
r_bt_bb_restart_hw_recorrect = 0x40001d88;
r_ke_task_handler_pre = 0x40001da0;
r_ke_task_handler_end = 0x40001da4;
r_lld_scan_frm_skip_isr_eco = 0x40001db0;
r_lld_ext_scan_dynamic_pti_reset = 0x40001db4;
r_llc_rem_phy_upd_proc_continue_eco = 0x40001db8;
r_llm_get_preferred_phys = 0x40001dbc;
r_lld_hw_cca_isr_eco = 0x40001dc0;
r_lld_sw_cca_isr_eco = 0x40001dc4;
r_lld_cca_chan_prn_e = 0x40001dc8;
r_lld_cca_chan_prn_s = 0x40001dcc;
r_lld_cca_chan_sel_remap = 0x40001dd0;
r_lld_cca_chan_sel_1 = 0x40001dd4;
r_lld_cca_chan_sel_2 = 0x40001dd8;
r_lld_cca_set_thresh = 0x40001ddc;
r_lld_cca_con_start = 0x40001de0;
r_lld_cca_con_end = 0x40001de4;
r_lld_cca_chm_restore = 0x40001de8;
r_lld_cca_chan_unused_check = 0x40001dec;
r_lld_cca_chm_update_check = 0x40001df0;
r_lld_cca_busy_mode_handle = 0x40001df4;
r_lld_cca_lbt_handle = 0x40001df8;
r_lld_cca_scst_timeout_check = 0x40001dfc;
r_lld_cca_chan_avl_timeout_check = 0x40001e00;
r_lld_con_start_hook = 0x40001ca8;
/* ble Functions eco */
r_bt_bb_isr = 0x40000b9c;
r_bt_rf_coex_conn_phy_coded_data_time_limit_en_get = 0x40000ba8;
r_bt_rtp_get_txpwr_idx_by_act = 0x40000c00;
r_btdm_task_post = 0x40000c14;
r_btdm_task_post_from_isr = 0x40000c18;
r_btdm_task_recycle = 0x40000c1c;
r_hci_register_vendor_desc_tab = 0x40000d9c;
r_ke_task_schedule = 0x40000e80;
r_llc_hci_command_handler = 0x40000ef0;
r_llc_loc_con_upd_proc_continue = 0x40000f60;
r_llc_loc_phy_upd_proc_continue = 0x40000f78;
r_llc_rem_con_upd_proc_continue = 0x40000fb4;
r_lld_con_sched = 0x40001118;
r_lld_con_stop = 0x40001124;
r_lld_llcp_rx_ind_handler = 0x400011b0;
r_lld_per_adv_sched = 0x400011f8;
r_lld_scan_process_pkt_rx_adv_rep = 0x40001284;
r_register_esp_vendor_cmd_handler = 0x40001400;
r_rf_txpwr_cs_get = 0x40001428;
r_rf_txpwr_dbm_get = 0x4000142c;
r_sch_arb_event_start_isr = 0x400014f8;
r_sch_plan_set = 0x40001534;
r_sch_prog_end_isr = 0x40001538;
r_lld_adv_ext_chain_scannable_construct = 0x40001b58;
r_lld_scan_process_pkt_rx = 0x40001280;
r_llm_le_features_get = 0x400013b0;
/* ble functions rename */
r_lld_init_start_hack = 0x400011a4;
/* ble functions disable */
/*
r_lld_adv_frm_isr_eco = 0x40001d00;
r_lld_res_list_clear = 0x40004638;
r_lld_res_list_rem = 0x40004680;
r_lld_adv_start_hook = 0x40001c80;
r_lld_con_evt_start_cbk_eco = 0x40001d1c;
r_lld_con_tx_prog_new_packet = 0x40001b74;
r_lld_adv_ext_chain_none_construct = 0x40001b50;
r_llc_llcp_send_eco = 0x40001cf4;
r_llc_llcp_channel_map_ind_ack = 0x40001d68;
r_rwble_isr = 0x40001464;
r_lld_scan_start_eco = 0x40001d24;
r_lld_scan_try_sched_eco = 0x40001dac;
r_lld_scan_start_hook = 0x40001c74;
r_lld_init_start_hook = 0x40001cb8;
r_lld_scan_evt_start_cbk_eco = 0x40001d20;
r_ke_task_handler_get_overwrite = 0x40001da8;
*/
/***************************************
Group eco7_phy
***************************************/
/* Functions */
rom2_pll_cap_mem_update = 0x40001e04;
rom2_phy_i2c_enter_critical = 0x40001e08;
rom2_phy_i2c_exit_critical = 0x40001e0c;
rom2_rfpll_cap_correct = 0x40001e10;
rom2_write_pll_cap = 0x40001e14;
rom2_read_pll_cap = 0x40001e18;
rom2_tester_wifi_cali = 0x40001e1c;
rom2_wait_hw_freq_busy = 0x40001e20;
rom2_rfpll_cap_track = 0x40001e24;
rom2_ulp_code_track = 0x40001e28;
rom2_ulp_ext_code_set = 0x40001e2c;
rom2_phy_set_tsens_power = 0x40001e30;
rom2_phy_get_tsens_value = 0x40001e34;
rom_mac_tx_chan_offset = 0x40001e38;
rom_rx_gain_force = 0x40001e3c;

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