Add initial support for the ESP32-P4 (#1101)

* Add `esp32p4` feature to `esp-hal-procmacros`

* Add `esp32p4` feature to `esp-hal-common`

* Create the `esp32p4-hal` package

* Add ESP32-P4 to CI workflow

* Fix a silly typo :)

* Update `CHANGELOG.md`
This commit is contained in:
Jesse Braham 2024-01-22 15:28:05 +00:00 committed by GitHub
parent 8ac075a0aa
commit e5cd1bd33e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 829 additions and 67 deletions

View File

@ -429,6 +429,38 @@ jobs:
- name: rustdoc
run: cd esp32h2-hal/ && cargo doc --features=eh1
esp32p4-hal:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@v1
with:
target: riscv32imafc-unknown-none-elf
toolchain: nightly
components: rust-src
- uses: Swatinem/rust-cache@v2
# Perform a full build initially to verify that the examples not only
# build, but also link successfully.
# We also use this as an opportunity to verify that the examples link
# for each supported image format.
- name: build esp32p4-hal (no features)
run: cd esp32p4-hal/ && cargo +nightly build --examples
# Subsequent steps can just check the examples instead, as we're already
# confident that they link.
- name: check esp32p4-hal (common features)
run: |
cd esp32p4-hal/
cargo +nightly build --examples --features=eh1,ufmt,log
cargo +nightly build --examples --features=eh1,ufmt,defmt
# Make sure we can build without default features enabled, too!
- name: check esp32p4-hal (no default features)
run: cd esp32p4-hal/ && cargo build --no-default-features
# Ensure documentation can be built
- name: rustdoc
run: cd esp32p4-hal/ && cargo doc --features=eh1
esp32s2-hal:
runs-on: ubuntu-latest
@ -604,7 +636,7 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@v1
with:
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf
target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf #,riscv32imafc-unknown-none-elf
toolchain: ${{ env.MSRV }}
components: rust-src
- uses: Swatinem/rust-cache@v2
@ -639,6 +671,11 @@ jobs:
cd esp32h2-hal/
cargo build --features=eh1,ufmt,log
cargo build --features=defmt
# - name: msrv (esp32p4-hal)
# run: |
# cd esp32p4-hal/
# cargo build --features=eh1,ufmt,log
# cargo build --features=defmt
msrv-xtensa:
runs-on: ubuntu-latest
@ -712,6 +749,8 @@ jobs:
run: cd esp32c6-lp-hal && cargo clippy -- -D warnings
- name: clippy (esp32h2-hal)
run: cd esp32h2-hal && cargo clippy -- -D warnings
- name: clippy (esp32p4-hal)
run: cd esp32p4-hal && cargo clippy -- -D warnings
clippy-xtensa:
runs-on: ubuntu-latest
@ -767,6 +806,8 @@ jobs:
run: cargo fmt --all --manifest-path=esp32c6-lp-hal/Cargo.toml -- --check
- name: rustfmt (esp32h2-hal)
run: cargo fmt --all --manifest-path=esp32h2-hal/Cargo.toml -- --check
- name: rustfmt (esp32p4-hal)
run: cargo fmt --all --manifest-path=esp32p4-hal/Cargo.toml -- --check
- name: rustfmt (esp32s2-hal)
run: cargo fmt --all --manifest-path=esp32s2-hal/Cargo.toml -- --check
- name: rustfmt (esp32s3-hal)

15
.vscode/settings.json vendored
View File

@ -13,13 +13,14 @@
// This makes rust-analyzer work on the HAL crate and all its dependencies.
"rust-analyzer.linkedProjects": [
"esp32-hal/Cargo.toml"
// "esp32c2-hal/Cargo.toml",
// "esp32c3-hal/Cargo.toml",
// "esp32c6-hal/Cargo.toml",
// "esp32c6-lp-hal/Cargo.toml",
// "esp32h2-hal/Cargo.toml",
// "esp32s2-hal/Cargo.toml",
// "esp32s3-hal/Cargo.toml",
// "esp32c2-hal/Cargo.toml"
// "esp32c3-hal/Cargo.toml"
// "esp32c6-hal/Cargo.toml"
// "esp32c6-lp-hal/Cargo.toml"
// "esp32h2-hal/Cargo.toml"
// "esp32p4-hal/Cargo.toml"
// "esp32s2-hal/Cargo.toml"
// "esp32s3-hal/Cargo.toml"
],
"[toml]": {

View File

@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add initial support for the ESP32-P4 (#1101)
### Fixed
### Changed

View File

@ -4,7 +4,7 @@
![MIT/Apache-2.0 licensed](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue?style=flat-square)
[![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&color=BEC5C9&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org)
**H**ardware **A**bstraction **L**ayer crates for the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, and **ESP32-S2/S3** from Espressif. Additionally provides support for programming the low-power RISC-V cores found on the **ESP32-C6** and **ESP32-S2/S3**.
**H**ardware **A**bstraction **L**ayer crates for the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, and **ESP32-S2/S3** from Espressif. Additionally provides support for programming the low-power RISC-V cores found on the **ESP32-C6** and **ESP32-S2/S3**.
These HALs are `no_std`; if you are looking for `std` support, please use [esp-idf-hal] instead.
@ -40,24 +40,26 @@ For information about the HAL and how to use it in your own projects, please ref
### High-Power Cores
| Crate | Documentation | Technical Reference Manual | Target | MSRV |
| :-----------: | :------------------------------------------------: | :------------------------: | :----------------------------: | :---------: |
| [esp32-hal] | [![esp32-hal-docs]](https://docs.rs/esp32-hal) | [ESP32] | `xtensa-esp32-none-elf` | ![esp] |
| [esp32c2-hal] | [![esp32c2-hal-docs]](https://docs.rs/esp32c2-hal) | [ESP32-C2] | `riscv32imc-unknown-none-elf` | ![nightly] |
| [esp32c3-hal] | [![esp32c3-hal-docs]](https://docs.rs/esp32c3-hal) | [ESP32-C3] | `riscv32imc-unknown-none-elf` | ![nightly] |
| [esp32c6-hal] | [![esp32c6-hal-docs]](https://docs.rs/esp32c6-hal) | [ESP32-C6] | `riscv32imac-unknown-none-elf` | ![nightly] |
| [esp32h2-hal] | [![esp32h2-hal-docs]](https://docs.rs/esp32h2-hal) | [ESP32-H2] | `riscv32imac-unknown-none-elf` | ![nightly] |
| [esp32s2-hal] | [![esp32s2-hal-docs]](https://docs.rs/esp32s2-hal) | [ESP32-S2] | `xtensa-esp32s2-none-elf` | ![esp] |
| [esp32s3-hal] | [![esp32s3-hal-docs]](https://docs.rs/esp32s3-hal) | [ESP32-S3] | `xtensa-esp32s3-none-elf` | ![esp] |
| Crate | Documentation | Technical Reference Manual | Target | MSRV |
| :-----------: | :------------------------------------------------: | :------------------------: | :-----------------------------: | :--------: |
| [esp32-hal] | [![esp32-hal-docs]](https://docs.rs/esp32-hal) | [ESP32] | `xtensa-esp32-none-elf` | ![esp] |
| [esp32c2-hal] | [![esp32c2-hal-docs]](https://docs.rs/esp32c2-hal) | [ESP32-C2] | `riscv32imc-unknown-none-elf` | ![nightly] |
| [esp32c3-hal] | [![esp32c3-hal-docs]](https://docs.rs/esp32c3-hal) | [ESP32-C3] | `riscv32imc-unknown-none-elf` | ![nightly] |
| [esp32c6-hal] | [![esp32c6-hal-docs]](https://docs.rs/esp32c6-hal) | [ESP32-C6] | `riscv32imac-unknown-none-elf` | ![nightly] |
| [esp32h2-hal] | [![esp32h2-hal-docs]](https://docs.rs/esp32h2-hal) | [ESP32-H2] | `riscv32imac-unknown-none-elf` | ![nightly] |
| [esp32p4-hal] | [![esp32p4-hal-docs]](https://docs.rs/esp32p4-hal) | [ESP32-P4] | `riscv32imafc-unknown-none-elf` | ![nightly] |
| [esp32s2-hal] | [![esp32s2-hal-docs]](https://docs.rs/esp32s2-hal) | [ESP32-S2] | `xtensa-esp32s2-none-elf` | ![esp] |
| [esp32s3-hal] | [![esp32s3-hal-docs]](https://docs.rs/esp32s3-hal) | [ESP32-S3] | `xtensa-esp32s3-none-elf` | ![esp] |
[esp]: https://img.shields.io/badge/rustc-esp%201.74+-red.svg
[nightly]: https://img.shields.io/badge/rustc-nightly%202023/11/30+-red.svg
[nightly]: https://img.shields.io/badge/rustc-nightly%202023/11/30+-red.svg
[esp32-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32-hal
[esp32c2-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32c2-hal
[esp32c3-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32c3-hal
[esp32c6-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32c6-hal
[esp32h2-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32h2-hal
[esp32p4-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32p4-hal
[esp32s2-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32s2-hal
[esp32s3-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32s3-hal
[esp32-hal-docs]: https://img.shields.io/docsrs/esp32-hal?color=C96329&logo=rust&style=flat-square
@ -65,6 +67,7 @@ For information about the HAL and how to use it in your own projects, please ref
[esp32c3-hal-docs]: https://img.shields.io/docsrs/esp32c3-hal?color=C96329&logo=rust&style=flat-square
[esp32c6-hal-docs]: https://img.shields.io/docsrs/esp32c6-hal?color=C96329&logo=rust&style=flat-square
[esp32h2-hal-docs]: https://img.shields.io/docsrs/esp32h2-hal?color=C96329&logo=rust&style=flat-square
[esp32p4-hal-docs]: https://img.shields.io/docsrs/esp32p4-hal?color=C96329&logo=rust&style=flat-square
[esp32s2-hal-docs]: https://img.shields.io/docsrs/esp32s2-hal?color=C96329&logo=rust&style=flat-square
[esp32s3-hal-docs]: https://img.shields.io/docsrs/esp32s3-hal?color=C96329&logo=rust&style=flat-square
[esp32]: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
@ -72,13 +75,14 @@ For information about the HAL and how to use it in your own projects, please ref
[esp32-c3]: https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf
[esp32-c6]: https://www.espressif.com/sites/default/files/documentation/esp32-c6_technical_reference_manual_en.pdf
[esp32-h2]: https://www.espressif.com/sites/default/files/documentation/esp32-h2_technical_reference_manual_en.pdf
[esp32-p4]: https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf
[esp32-s2]: https://www.espressif.com/sites/default/files/documentation/esp32-s2_technical_reference_manual_en.pdf
[esp32-s3]: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf
### Low-Power Cores
| Crate | Documentation | Target |
| :-----------------: | :------------------------: | :----------------------------: |
| Crate | Documentation | Target |
| :-----------------: | :-----------------------: | :----------------------------: |
| [esp-ulp-riscv-hal] | N/A (_Not yet published_) | `riscv32imc-unknown-none-elf` |
| [esp32c6-lp-hal] | N/A (_Not yet published_) | `riscv32imac-unknown-none-elf` |

View File

@ -66,6 +66,7 @@ esp32c2 = { version = "0.17.0", features = ["critical-section"], optional = true
esp32c3 = { version = "0.20.0", features = ["critical-section"], optional = true }
esp32c6 = { version = "0.11.0", features = ["critical-section"], optional = true }
esp32h2 = { version = "0.7.0", features = ["critical-section"], optional = true }
esp32p4 = { git = "https://github.com/esp-rs/esp-pacs", rev = "4c0dfd5", optional = true }
esp32s2 = { version = "0.19.0", features = ["critical-section"], optional = true }
esp32s3 = { version = "0.23.0", features = ["critical-section"], optional = true }
@ -79,6 +80,7 @@ esp32c2 = ["dep:esp32c2", "riscv", "procmacros/esp32c2", "portable-atomic/unsaf
esp32c3 = ["dep:esp32c3", "riscv", "procmacros/esp32c3", "portable-atomic/unsafe-assume-single-core"]
esp32c6 = ["dep:esp32c6", "riscv", "procmacros/esp32c6"]
esp32h2 = ["dep:esp32h2", "riscv", "procmacros/esp32h2"]
esp32p4 = ["dep:esp32p4", "riscv", "procmacros/esp32p4"]
esp32s2 = ["dep:esp32s2", "xtensa", "procmacros/esp32s2", "xtensa-lx/esp32s2", "xtensa-lx-rt?/esp32s2", "usb-otg", "portable-atomic/critical-section"]
esp32s3 = ["dep:esp32s3", "xtensa", "procmacros/esp32s3", "xtensa-lx/esp32s3", "xtensa-lx-rt?/esp32s3", "usb-otg"]
@ -87,7 +89,7 @@ xtal-26mhz = []
xtal-40mhz = []
# Runetime support
rt-riscv = ["esp-riscv-rt/zero-bss", "esp32c2?/rt", "esp32c3?/rt", "esp32c6?/rt", "esp32h2?/rt"]
rt-riscv = ["esp-riscv-rt/zero-bss", "esp32c2?/rt", "esp32c3?/rt", "esp32c6?/rt", "esp32h2?/rt", "esp32p4?/rt"]
rt-xtensa = ["dep:xtensa-lx-rt", "esp32?/rt", "esp32s2?/rt", "esp32s3?/rt"]
# Only certain chips support flip-link (ESP32-C6 and ESPS32-H2)
@ -167,6 +169,7 @@ debug = [
"esp32c3?/impl-register-debug",
"esp32c6?/impl-register-debug",
"esp32h2?/impl-register-debug",
"esp32p4?/impl-register-debug",
"esp32s2?/impl-register-debug",
"esp32s3?/impl-register-debug",
]

View File

@ -104,7 +104,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// NOTE: update when adding new device support!
// Ensure that exactly one chip has been specified:
assert_unique_used_features!(
"esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3"
"esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32p4", "esp32s2", "esp32s3"
);
// Handle the features for the ESP32's and ESP32-C2's different crystal
@ -143,6 +143,8 @@ fn main() -> Result<(), Box<dyn Error>> {
"esp32c6"
} else if cfg!(feature = "esp32h2") {
"esp32h2"
} else if cfg!(feature = "esp32p4") {
"esp32p4"
} else if cfg!(feature = "esp32s2") {
"esp32s2"
} else if cfg!(feature = "esp32s3") {

View File

@ -0,0 +1,96 @@
[device]
arch = "riscv"
cores = "multi_core"
peripherals = [
# Peripherals available in the PAC:
# "adc",
# "aes",
# "assist_debug",
# "axi_dma",
# "axi_icm",
# "bitscrambler",
# "cache",
# "dma",
# "ds",
# "ecc",
# "ecdsa",
# "efuse",
# "gpio_sd",
# "gpio",
# "h264_dma",
# "h264",
# "hmac",
# "hp_sys_clkrst",
"hp_sys",
# "i2c0",
# "i2c1",
# "i2s0",
# "i2s1",
# "i2s2",
# "i3c_mst_mem",
# "i3c_mst",
# "i3c_slv",
"interrupt_core0",
"interrupt_core1",
# "io_mux",
# "isp",
# "jpeg",
# "lcd_cam",
# "ledc",
# "lp_adc",
# "lp_ana_peri",
# "lp_aon_clkrst",
# "lp_gpio",
# "lp_huk",
# "lp_i2c_ana_mst",
# "lp_i2c0",
# "lp_i2s0",
# "lp_intr",
# "lp_io_mux",
# "lp_peri",
# "lp_sys",
# "lp_timer",
# "lp_touch",
# "lp_tsens",
# "lp_uart",
# "lp_wdt",
# "mcpwm0",
# "mcpwm1",
# "mipi_csi_bridge",
# "mipi_csi_host",
# "mipi_dsi_bridge",
# "mipi_dsi_host",
# "parl_io",
# "pau",
# "pcnt",
# "pmu",
# "ppa",
# "pvt",
# "rmt",
# "rsa",
# "sdhost",
# "sha",
# "soc_etm",
# "spi0",
# "spi1",
# "spi2",
# "spi3",
# "systimer",
# "timg0",
# "timg1",
# "trace0",
# "trace1",
# "twai0",
# "twai1",
# "twai2",
# "uart0",
# "uhci0",
# "usb_device",
# "usb_wrap",
]
symbols = [
# Additional peripherals defined by us (the developers):
"plic",
]

View File

@ -0,0 +1,125 @@
# field_name, | efuse_block, | bit_start, | bit_count, |comment #
# | (EFUSE_BLK0 | (0..255) | (1-256) | #
# | EFUSE_BLK1 | | | #
# | ...) | | | #
##########################################################################
# !!!!!!!!!!! #
# After editing this file, run the command manually "idf.py efuse-common-table"
# this will generate new source files, next rebuild all the sources.
# !!!!!!!!!!! #
# This file was generated by regtools.py based on the efuses.yaml file with the version: 552d7a824581925566213ca4f4d488dc
WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses
WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS
WR_DIS.SPI_BOOT_CRYPT_CNT, EFUSE_BLK0, 4, 1, [] wr_dis of SPI_BOOT_CRYPT_CNT
WR_DIS.SECURE_BOOT_KEY_REVOKE0, EFUSE_BLK0, 5, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE0
WR_DIS.SECURE_BOOT_KEY_REVOKE1, EFUSE_BLK0, 6, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE1
WR_DIS.SECURE_BOOT_KEY_REVOKE2, EFUSE_BLK0, 7, 1, [] wr_dis of SECURE_BOOT_KEY_REVOKE2
WR_DIS.KEY_PURPOSE_0, EFUSE_BLK0, 8, 1, [WR_DIS.KEY0_PURPOSE] wr_dis of KEY_PURPOSE_0
WR_DIS.KEY_PURPOSE_1, EFUSE_BLK0, 9, 1, [WR_DIS.KEY1_PURPOSE] wr_dis of KEY_PURPOSE_1
WR_DIS.KEY_PURPOSE_2, EFUSE_BLK0, 10, 1, [WR_DIS.KEY2_PURPOSE] wr_dis of KEY_PURPOSE_2
WR_DIS.KEY_PURPOSE_3, EFUSE_BLK0, 11, 1, [WR_DIS.KEY3_PURPOSE] wr_dis of KEY_PURPOSE_3
WR_DIS.KEY_PURPOSE_4, EFUSE_BLK0, 12, 1, [WR_DIS.KEY4_PURPOSE] wr_dis of KEY_PURPOSE_4
WR_DIS.KEY_PURPOSE_5, EFUSE_BLK0, 13, 1, [WR_DIS.KEY5_PURPOSE] wr_dis of KEY_PURPOSE_5
WR_DIS.SECURE_BOOT_EN, EFUSE_BLK0, 15, 1, [] wr_dis of SECURE_BOOT_EN
WR_DIS.BLK1, EFUSE_BLK0, 20, 1, [] wr_dis of BLOCK1
WR_DIS.MAC, EFUSE_BLK0, 20, 1, [WR_DIS.MAC_FACTORY] wr_dis of MAC
WR_DIS.MAC_EXT, EFUSE_BLK0, 20, 1, [] wr_dis of MAC_EXT
WR_DIS.BLOCK_SYS_DATA1, EFUSE_BLK0, 21, 1, [WR_DIS.SYS_DATA_PART1] wr_dis of BLOCK_SYS_DATA1
WR_DIS.BLOCK_USR_DATA, EFUSE_BLK0, 22, 1, [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA
WR_DIS.BLOCK_KEY0, EFUSE_BLK0, 23, 1, [WR_DIS.KEY0] wr_dis of BLOCK_KEY0
WR_DIS.BLOCK_KEY1, EFUSE_BLK0, 24, 1, [WR_DIS.KEY1] wr_dis of BLOCK_KEY1
WR_DIS.BLOCK_KEY2, EFUSE_BLK0, 25, 1, [WR_DIS.KEY2] wr_dis of BLOCK_KEY2
WR_DIS.BLOCK_KEY3, EFUSE_BLK0, 26, 1, [WR_DIS.KEY3] wr_dis of BLOCK_KEY3
WR_DIS.BLOCK_KEY4, EFUSE_BLK0, 27, 1, [WR_DIS.KEY4] wr_dis of BLOCK_KEY4
WR_DIS.BLOCK_KEY5, EFUSE_BLK0, 28, 1, [WR_DIS.KEY5] wr_dis of BLOCK_KEY5
WR_DIS.BLOCK_SYS_DATA2, EFUSE_BLK0, 29, 1, [WR_DIS.SYS_DATA_PART2] wr_dis of BLOCK_SYS_DATA2
RD_DIS, EFUSE_BLK0, 32, 7, [] Disable reading from BlOCK4-10
RD_DIS.BLOCK_KEY0, EFUSE_BLK0, 32, 1, [RD_DIS.KEY0] rd_dis of BLOCK_KEY0
RD_DIS.BLOCK_KEY1, EFUSE_BLK0, 33, 1, [RD_DIS.KEY1] rd_dis of BLOCK_KEY1
RD_DIS.BLOCK_KEY2, EFUSE_BLK0, 34, 1, [RD_DIS.KEY2] rd_dis of BLOCK_KEY2
RD_DIS.BLOCK_KEY3, EFUSE_BLK0, 35, 1, [RD_DIS.KEY3] rd_dis of BLOCK_KEY3
RD_DIS.BLOCK_KEY4, EFUSE_BLK0, 36, 1, [RD_DIS.KEY4] rd_dis of BLOCK_KEY4
RD_DIS.BLOCK_KEY5, EFUSE_BLK0, 37, 1, [RD_DIS.KEY5] rd_dis of BLOCK_KEY5
RD_DIS.BLOCK_SYS_DATA2, EFUSE_BLK0, 38, 1, [RD_DIS.SYS_DATA_PART2] rd_dis of BLOCK_SYS_DATA2
USB_DEVICE_EXCHG_PINS, EFUSE_BLK0, 39, 1, [] Enable usb device exchange pins of D+ and D-
USB_OTG11_EXCHG_PINS, EFUSE_BLK0, 40, 1, [] Enable usb otg11 exchange pins of D+ and D-
DIS_USB_JTAG, EFUSE_BLK0, 41, 1, [] Represents whether the function of usb switch to jtag is disabled or enabled. 1: disabled. 0: enabled
POWERGLITCH_EN, EFUSE_BLK0, 42, 1, [] Represents whether power glitch function is enabled. 1: enabled. 0: disabled
DIS_FORCE_DOWNLOAD, EFUSE_BLK0, 44, 1, [] Represents whether the function that forces chip into download mode is disabled or enabled. 1: disabled. 0: enabled
SPI_DOWNLOAD_MSPI_DIS, EFUSE_BLK0, 45, 1, [] Set this bit to disable accessing MSPI flash/MSPI ram by SYS AXI matrix during boot_mode_download
DIS_TWAI, EFUSE_BLK0, 46, 1, [] Represents whether TWAI function is disabled or enabled. 1: disabled. 0: enabled
JTAG_SEL_ENABLE, EFUSE_BLK0, 47, 1, [] Represents whether the selection between usb_to_jtag and pad_to_jtag through strapping gpio15 when both EFUSE_DIS_PAD_JTAG and EFUSE_DIS_USB_JTAG are equal to 0 is enabled or disabled. 1: enabled. 0: disabled
SOFT_DIS_JTAG, EFUSE_BLK0, 48, 3, [] Represents whether JTAG is disabled in soft way. Odd number: disabled. Even number: enabled
DIS_PAD_JTAG, EFUSE_BLK0, 51, 1, [] Represents whether JTAG is disabled in the hard way(permanently). 1: disabled. 0: enabled
DIS_DOWNLOAD_MANUAL_ENCRYPT, EFUSE_BLK0, 52, 1, [] Represents whether flash encrypt function is disabled or enabled(except in SPI boot mode). 1: disabled. 0: enabled
USB_PHY_SEL, EFUSE_BLK0, 57, 1, [] TBD
KM_HUK_GEN_STATE_LOW, EFUSE_BLK0, 58, 6, [] Set this bit to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is valid
KM_HUK_GEN_STATE_HIGH, EFUSE_BLK0, 64, 3, [] Set this bit to control validation of HUK generate mode. Odd of 1 is invalid; even of 1 is valid
KM_RND_SWITCH_CYCLE, EFUSE_BLK0, 67, 2, [] Set bits to control key manager random number switch cycle. 0: control by register. 1: 8 km clk cycles. 2: 16 km cycles. 3: 32 km cycles
KM_DEPLOY_ONLY_ONCE, EFUSE_BLK0, 69, 4, [] Set each bit to control whether corresponding key can only be deployed once. 1 is true; 0 is false. Bit0: ecdsa. Bit1: xts. Bit2: hmac. Bit3: ds
FORCE_USE_KEY_MANAGER_KEY, EFUSE_BLK0, 73, 4, [] Set each bit to control whether corresponding key must come from key manager.. 1 is true; 0 is false. Bit0: ecdsa. Bit1: xts. Bit2: hmac. Bit3: ds
FORCE_DISABLE_SW_INIT_KEY, EFUSE_BLK0, 77, 1, [] Set this bit to disable software written init key; and force use efuse_init_key
XTS_KEY_LENGTH_256, EFUSE_BLK0, 78, 1, [] Set this bit to configure flash encryption use xts-128 key; else use xts-256 key
WDT_DELAY_SEL, EFUSE_BLK0, 80, 2, [] Represents whether RTC watchdog timeout threshold is selected at startup. 1: selected. 0: not selected
SPI_BOOT_CRYPT_CNT, EFUSE_BLK0, 82, 3, [] Enables flash encryption when 1 or 3 bits are set and disables otherwise {0: "Disable"; 1: "Enable"; 3: "Disable"; 7: "Enable"}
SECURE_BOOT_KEY_REVOKE0, EFUSE_BLK0, 85, 1, [] Revoke 1st secure boot key
SECURE_BOOT_KEY_REVOKE1, EFUSE_BLK0, 86, 1, [] Revoke 2nd secure boot key
SECURE_BOOT_KEY_REVOKE2, EFUSE_BLK0, 87, 1, [] Revoke 3rd secure boot key
KEY_PURPOSE_0, EFUSE_BLK0, 88, 4, [KEY0_PURPOSE] Represents the purpose of Key0
KEY_PURPOSE_1, EFUSE_BLK0, 92, 4, [KEY1_PURPOSE] Represents the purpose of Key1
KEY_PURPOSE_2, EFUSE_BLK0, 96, 4, [KEY2_PURPOSE] Represents the purpose of Key2
KEY_PURPOSE_3, EFUSE_BLK0, 100, 4, [KEY3_PURPOSE] Represents the purpose of Key3
KEY_PURPOSE_4, EFUSE_BLK0, 104, 4, [KEY4_PURPOSE] Represents the purpose of Key4
KEY_PURPOSE_5, EFUSE_BLK0, 108, 4, [KEY5_PURPOSE] Represents the purpose of Key5
SEC_DPA_LEVEL, EFUSE_BLK0, 112, 2, [] Represents the spa secure level by configuring the clock random divide mode
ECDSA_ENABLE_SOFT_K, EFUSE_BLK0, 114, 1, [] Represents whether hardware random number k is forced used in ESDCA. 1: force used. 0: not force used
CRYPT_DPA_ENABLE, EFUSE_BLK0, 115, 1, [] Represents whether anti-dpa attack is enabled. 1:enabled. 0: disabled
SECURE_BOOT_EN, EFUSE_BLK0, 116, 1, [] Represents whether secure boot is enabled or disabled. 1: enabled. 0: disabled
SECURE_BOOT_AGGRESSIVE_REVOKE, EFUSE_BLK0, 117, 1, [] Represents whether revoking aggressive secure boot is enabled or disabled. 1: enabled. 0: disabled
FLASH_TYPE, EFUSE_BLK0, 119, 1, [] The type of interfaced flash. 0: four data lines; 1: eight data lines
FLASH_PAGE_SIZE, EFUSE_BLK0, 120, 2, [] Set flash page size
FLASH_ECC_EN, EFUSE_BLK0, 122, 1, [] Set this bit to enable ecc for flash boot
DIS_USB_OTG_DOWNLOAD_MODE, EFUSE_BLK0, 123, 1, [] Set this bit to disable download via USB-OTG
FLASH_TPUW, EFUSE_BLK0, 124, 4, [] Represents the flash waiting time after power-up; in unit of ms. When the value less than 15; the waiting time is the programmed value. Otherwise; the waiting time is 2 times the programmed value
DIS_DOWNLOAD_MODE, EFUSE_BLK0, 128, 1, [] Represents whether Download mode is disabled or enabled. 1: disabled. 0: enabled
DIS_DIRECT_BOOT, EFUSE_BLK0, 129, 1, [] Represents whether direct boot mode is disabled or enabled. 1: disabled. 0: enabled
DIS_USB_SERIAL_JTAG_ROM_PRINT, EFUSE_BLK0, 130, 1, [] Represents whether print from USB-Serial-JTAG is disabled or enabled. 1: disabled. 0: enabled
LOCK_KM_KEY, EFUSE_BLK0, 131, 1, [] TBD
DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE, EFUSE_BLK0, 132, 1, [] Represents whether the USB-Serial-JTAG download function is disabled or enabled. 1: disabled. 0: enabled
ENABLE_SECURITY_DOWNLOAD, EFUSE_BLK0, 133, 1, [] Represents whether security download is enabled or disabled. 1: enabled. 0: disabled
UART_PRINT_CONTROL, EFUSE_BLK0, 134, 2, [] Represents the type of UART printing. 00: force enable printing. 01: enable printing when GPIO8 is reset at low level. 10: enable printing when GPIO8 is reset at high level. 11: force disable printing
FORCE_SEND_RESUME, EFUSE_BLK0, 136, 1, [] Represents whether ROM code is forced to send a resume command during SPI boot. 1: forced. 0:not forced
SECURE_VERSION, EFUSE_BLK0, 137, 16, [] Represents the version used by ESP-IDF anti-rollback feature
SECURE_BOOT_DISABLE_FAST_WAKE, EFUSE_BLK0, 153, 1, [] Represents whether FAST VERIFY ON WAKE is disabled or enabled when Secure Boot is enabled. 1: disabled. 0: enabled
HYS_EN_PAD, EFUSE_BLK0, 154, 1, [] Represents whether the hysteresis function of corresponding PAD is enabled. 1: enabled. 0:disabled
DCDC_VSET, EFUSE_BLK0, 155, 5, [] Set the dcdc voltage default
PXA0_TIEH_SEL_0, EFUSE_BLK0, 160, 2, [] TBD
PXA0_TIEH_SEL_1, EFUSE_BLK0, 162, 2, [] TBD
PXA0_TIEH_SEL_2, EFUSE_BLK0, 164, 2, [] TBD
PXA0_TIEH_SEL_3, EFUSE_BLK0, 166, 2, [] TBD
KM_DISABLE_DEPLOY_MODE, EFUSE_BLK0, 168, 4, [] TBD
HP_PWR_SRC_SEL, EFUSE_BLK0, 178, 1, [] HP system power source select. 0:LDO. 1: DCDC
DCDC_VSET_EN, EFUSE_BLK0, 179, 1, [] Select dcdc vset use efuse_dcdc_vset
DIS_WDT, EFUSE_BLK0, 180, 1, [] Set this bit to disable watch dog
DIS_SWD, EFUSE_BLK0, 181, 1, [] Set this bit to disable super-watchdog
MAC, EFUSE_BLK1, 40, 8, [MAC_FACTORY] MAC address
# , EFUSE_BLK1, 32, 8, [MAC_FACTORY] MAC address
# , EFUSE_BLK1, 24, 8, [MAC_FACTORY] MAC address
# , EFUSE_BLK1, 16, 8, [MAC_FACTORY] MAC address
# , EFUSE_BLK1, 8, 8, [MAC_FACTORY] MAC address
# , EFUSE_BLK1, 0, 8, [MAC_FACTORY] MAC address
MAC_EXT, EFUSE_BLK1, 48, 8, [] Stores the extended bits of MAC address [0]
# , EFUSE_BLK1, 56, 8, [] Stores the extended bits of MAC address [1]
BLOCK_SYS_DATA1, EFUSE_BLK2, 0, 256, [SYS_DATA_PART1] System data part 1
USER_DATA, EFUSE_BLK3, 0, 256, [BLOCK_USR_DATA] User data
USER_DATA.MAC_CUSTOM, EFUSE_BLK3, 200, 48, [MAC_CUSTOM CUSTOM_MAC] Custom MAC (TODO, not defined yet)
KEY0, EFUSE_BLK4, 0, 256, [BLOCK_KEY0] Key0 or user data
KEY1, EFUSE_BLK5, 0, 256, [BLOCK_KEY1] Key1 or user data
KEY2, EFUSE_BLK6, 0, 256, [BLOCK_KEY2] Key2 or user data
KEY3, EFUSE_BLK7, 0, 256, [BLOCK_KEY3] Key3 or user data
KEY4, EFUSE_BLK8, 0, 256, [BLOCK_KEY4] Key4 or user data
KEY5, EFUSE_BLK9, 0, 256, [BLOCK_KEY5] Key5 or user data
SYS_DATA_PART2, EFUSE_BLK10, 0, 256, [BLOCK_SYS_DATA2] System data part 2 (reserved)
Can't render this file because it contains an unexpected character in line 8 and column 53.

View File

@ -0,0 +1,75 @@
ENTRY(_start)
PROVIDE(_stext = ORIGIN(ROTEXT));
PROVIDE(_max_hart_id = 1);
PROVIDE(UserSoft = DefaultHandler);
PROVIDE(SupervisorSoft = DefaultHandler);
PROVIDE(MachineSoft = DefaultHandler);
PROVIDE(UserTimer = DefaultHandler);
PROVIDE(SupervisorTimer = DefaultHandler);
PROVIDE(MachineTimer = DefaultHandler);
PROVIDE(UserExternal = DefaultHandler);
PROVIDE(SupervisorExternal = DefaultHandler);
PROVIDE(MachineExternal = DefaultHandler);
PROVIDE(ExceptionHandler = DefaultExceptionHandler);
/* The ESP32-C2 and ESP32-C3 have interrupt IDs 1-31, while the ESP32-C6,
ESP32-H2, and ESP32-P4 have IDs 0-31, so we much define the handler for the
one additional interrupt ID: */
PROVIDE(interrupt0 = DefaultHandler);
PROVIDE(__post_init = default_post_init);
/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
PROVIDE(_setup_interrupts = default_setup_interrupts);
/* # Multi-processing hook function
fn _mp_hook() -> bool;
This function is called from all the harts and must return true only for one hart,
which will perform memory initialization. For other harts it must return false
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
*/
PROVIDE(_mp_hook = default_mp_hook);
/* # Start trap function override
By default uses the riscv crates default trap handler
but by providing the `_start_trap` symbol external crates can override.
*/
PROVIDE(_start_trap = default_start_trap);
/* Must be called __global_pointer$ for linker relaxations to work. */
PROVIDE(__global_pointer$ = _data_start + 0x800);
SECTIONS {
.trap : ALIGN(4)
{
KEEP(*(.trap));
*(.trap.*);
} > RWTEXT
}
INSERT BEFORE .rwtext;
SECTIONS {
/**
* Bootloader really wants to have separate segments for ROTEXT and RODATA
* It also needs to be located in a separate 64k flash segment.
*/
.text_gap (NOLOAD): {
. = ALIGN(0x10000) + 0x20;
} > ROM
}
INSERT BEFORE .rodata;
/* Shared sections - ordering matters */
INCLUDE "text.x"
INCLUDE "rwtext.x"
INCLUDE "rodata.x"
INCLUDE "rwdata.x"
INCLUDE "rtc_fast.x"
INCLUDE "stack.x"
/* End of Shared sections */
INCLUDE "debug.x"

View File

@ -0,0 +1,14 @@
INCLUDE "memory.x"
REGION_ALIAS("ROTEXT", ROM);
REGION_ALIAS("RODATA", ROM);
REGION_ALIAS("RWTEXT", RAM);
REGION_ALIAS("RWDATA", RAM);
REGION_ALIAS("RTC_FAST_RWTEXT", RTC_FAST);
REGION_ALIAS("RTC_FAST_RWDATA", RTC_FAST);
INCLUDE "esp32p4.x"
INCLUDE "hal-defaults.x"
INCLUDE "rom-functions.x"

View File

@ -0,0 +1,26 @@
MEMORY
{
/* MEMORY_MAP = [
[0x00000000, 0x00010000, "PADDING"],
[0x40000000, 0x4C000000, "DROM"],
[0x4FF00000, 0x4FFA0000, "DRAM"],
[0x4FF00000, 0x4FFA0000, "BYTE_ACCESSIBLE"],
[0x4FC00000, 0x4FC20000, "DROM_MASK"],
[0x4FC00000, 0x4FC20000, "IROM_MASK"],
[0x40000000, 0x4C000000, "IROM"],
[0x4FF00000, 0x4FFA0000, "IRAM"],
[0x50108000, 0x50110000, "RTC_IRAM"],
[0x50108000, 0x50110000, "RTC_DRAM"],
[0x600FE000, 0x60100000, "MEM_INTERNAL2"],
] */
/* 768K of on soc RAM */
RAM : ORIGIN = 0x4FF00000, LENGTH = 0xC0000
/* External flash */
/* Instruction and Data ROM */
ROM : ORIGIN = 0x40000000 + 0x20, LENGTH = 0x400000 - 0x20
/* RTC fast memory (executable). Persists over deep sleep. */
RTC_FAST : ORIGIN = 0x50108000, LENGTH = 32K /*- ESP_BOOTLOADER_RESERVE_RTC*/
}

View File

@ -0,0 +1 @@

View File

@ -65,6 +65,7 @@ use crate::{
#[cfg_attr(esp32c3, path = "clocks_ll/esp32c3.rs")]
#[cfg_attr(esp32c6, path = "clocks_ll/esp32c6.rs")]
#[cfg_attr(esp32h2, path = "clocks_ll/esp32h2.rs")]
#[cfg_attr(esp32p4, path = "clocks_ll/esp32p4.rs")]
#[cfg_attr(esp32s2, path = "clocks_ll/esp32s2.rs")]
#[cfg_attr(esp32s3, path = "clocks_ll/esp32s3.rs")]
pub(crate) mod clocks_ll;

View File

@ -10,6 +10,7 @@
//! - [esp32c3-hal]
//! - [esp32c6-hal]
//! - [esp32h2-hal]
//! - [esp32p4-hal]
//! - [esp32s2-hal]
//! - [esp32s3-hal]
//!
@ -19,6 +20,7 @@
//! [esp32c3-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32c3-hal
//! [esp32c6-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32c6-hal
//! [esp32h2-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32h2-hal
//! [esp32p4-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32p4-hal
//! [esp32s2-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32s2-hal
//! [esp32s3-hal]: https://github.com/esp-rs/esp-hal/tree/main/esp32s3-hal
@ -85,6 +87,7 @@ pub mod aes;
pub mod analog;
#[cfg(assist_debug)]
pub mod assist_debug;
#[cfg(any(dport, hp_sys, pcr, system))]
pub mod clock;
#[cfg(any(xtensa, all(riscv, systimer)))]
pub mod delay;
@ -123,6 +126,7 @@ pub mod peripheral;
pub mod prelude;
#[cfg(any(hmac, sha))]
mod reg_access;
#[cfg(any(lp_clkrst, rtc_cntl))]
pub mod reset;
#[cfg(rmt)]
pub mod rmt;
@ -137,7 +141,7 @@ pub mod rtc_cntl;
pub mod sha;
#[cfg(any(spi0, spi1, spi2, spi3))]
pub mod spi;
#[cfg(any(dport, pcr, system))]
#[cfg(any(dport, hp_sys, pcr, system))]
pub mod system;
#[cfg(systimer)]
pub mod systimer;
@ -195,34 +199,29 @@ extern "C" fn EspDefaultHandler(_interrupt: peripherals::Interrupt) {
/// Available CPU cores
///
/// The actual number of available cores depends on the target.
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, strum::FromRepr)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Cpu {
/// The first core
ProCpu = 0,
/// The second core
#[cfg(multi_core)]
AppCpu,
}
#[cfg(all(xtensa, multi_core))]
fn get_raw_core() -> u32 {
xtensa_lx::get_processor_id() & 0x2000
AppCpu = 1,
}
/// Which core the application is currently executing on
#[cfg(all(xtensa, multi_core))]
pub fn get_core() -> Cpu {
match get_raw_core() {
0 => Cpu::ProCpu,
_ => Cpu::AppCpu,
}
Cpu::from_repr(get_raw_core()).unwrap()
}
/// Which core the application is currently executing on
#[cfg(not(all(xtensa, multi_core)))]
pub fn get_core() -> Cpu {
Cpu::ProCpu
#[cfg(riscv)]
fn get_raw_core() -> usize {
riscv::register::mhartid::read()
}
#[cfg(xtensa)]
fn get_raw_core() -> usize {
xtensa_lx::get_processor_id() as usize & 0x2000
}
mod critical_section_impl {
@ -282,16 +281,18 @@ mod critical_section_impl {
#[cfg(riscv)]
mod riscv {
#[cfg(multi_core)]
// The restore state is a u8 that is casted from a bool, so it has a value of
// 0x00 or 0x01 before we add the reentry flag to it.
#[cfg(multi_core)]
const REENTRY_FLAG: u8 = 1 << 7;
unsafe impl critical_section::Impl for super::CriticalSection {
unsafe fn acquire() -> critical_section::RawRestoreState {
let mut mstatus = 0u32;
core::arch::asm!("csrrci {0}, mstatus, 8", inout(reg) mstatus);
let tkn = ((mstatus & 0b1000) != 0) as critical_section::RawRestoreState;
#[cfg_attr(single_core, allow(unused_mut))]
let mut tkn = ((mstatus & 0b1000) != 0) as critical_section::RawRestoreState;
#[cfg(multi_core)]
{
@ -333,8 +334,9 @@ mod critical_section_impl {
// We're using a value that we know get_raw_core() will never return. This
// avoids an unnecessary increment of the core ID.
#[cfg(xtensa)] // TODO: first multi-core RISC-V target will show if this value is OK
// globally or only for Xtensa
//
// TODO: First multi-core RISC-V target will show if this value is OK globally
// or only for Xtensa...
const UNUSED_THREAD_ID_VALUE: usize = 0x0001;
fn thread_id() -> usize {
@ -424,6 +426,7 @@ mod critical_section_impl {
/// ```
pub struct FlashSafeDma<T, const SIZE: usize> {
inner: T,
#[allow(unused)]
buffer: [u8; SIZE],
}

View File

@ -29,6 +29,8 @@ pub use nb;
#[cfg(any(apb_saradc, sens))]
pub use crate::analog::AnalogExt as _esp_hal_analog_AnalogExt;
#[cfg(any(dport, pcr, system))]
pub use crate::clock::Clock as _esp_hal_clock_Clock;
#[cfg(any(gdma, pdma))]
pub use crate::dma::{
DmaTransfer as _esp_hal_dma_DmaTransfer,
@ -52,6 +54,7 @@ pub use crate::ledc::{
},
timer::{TimerHW as _esp_hal_ledc_timer_TimerHW, TimerIFace as _esp_hal_ledc_timer_TimerIFace},
};
pub use crate::macros::*;
#[cfg(any(dport, pcr, system))]
pub use crate::system::SystemExt as _esp_hal_system_SystemExt;
#[cfg(any(timg0, timg1))]
@ -61,4 +64,3 @@ pub use crate::timer::{
};
#[cfg(any(uart0, uart1, uart2))]
pub use crate::uart::{Instance as _esp_hal_uart_Instance, UartPins as _esp_hal_uart_UartPins};
pub use crate::{clock::Clock as _esp_hal_clock_Clock, macros::*};

View File

@ -23,7 +23,9 @@
//! [CRC (Cyclic Redundancy Check)]: ./crc/index.html
//! [MD5 (Message Digest 5)]: ./md5/index.html
#[cfg(any(rom_crc_be, rom_crc_le))]
pub mod crc;
#[cfg(any(rom_md5_bsd, rom_md5_mbedtls))]
pub mod md5;
#[allow(unused)]

View File

@ -0,0 +1,58 @@
//! # Reading of eFuses (ESP32-P4)
use crate::peripherals::EFUSE;
pub use crate::soc::efuse_field::*;
pub struct Efuse;
impl Efuse {
/// Reads chip's MAC address from the eFuse storage.
pub fn read_base_mac_address() -> [u8; 6] {
Self::read_field_be(MAC)
}
/// Get status of SPI boot encryption.
pub fn get_flash_encryption() -> bool {
(Self::read_field_le::<u8>(SPI_BOOT_CRYPT_CNT).count_ones() % 2) != 0
}
/// Get the multiplier for the timeout value of the RWDT STAGE 0 register.
pub fn get_rwdt_multiplier() -> u8 {
Self::read_field_le::<u8>(WDT_DELAY_SEL)
}
}
#[derive(Clone, Copy)]
pub(crate) enum EfuseBlock {
Block0,
Block1,
Block2,
Block3,
Block4,
Block5,
Block6,
Block7,
Block8,
Block9,
Block10,
}
impl EfuseBlock {
pub(crate) fn address(self) -> *const u32 {
use EfuseBlock::*;
let efuse = unsafe { &*EFUSE::PTR };
match self {
Block0 => efuse.rd_wr_dis().as_ptr(),
Block1 => efuse.rd_mac_sys_0().as_ptr(),
Block2 => efuse.rd_sys_part1_data0().as_ptr(),
Block3 => efuse.rd_usr_data0().as_ptr(),
Block4 => efuse.rd_key0_data0().as_ptr(),
Block5 => efuse.rd_key1_data0().as_ptr(),
Block6 => efuse.rd_key2_data0().as_ptr(),
Block7 => efuse.rd_key3_data0().as_ptr(),
Block8 => efuse.rd_key4_data0().as_ptr(),
Block9 => efuse.rd_key5_data0().as_ptr(),
Block10 => efuse.rd_sys_part2_data0().as_ptr(),
}
}
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,17 @@
pub mod efuse;
pub mod gpio;
pub mod peripherals;
pub(crate) mod registers {
pub const INTERRUPT_MAP_BASE: u32 = 0x500D_6000;
}
pub(crate) mod constants {
pub const SOC_DRAM_LOW: u32 = 0x4FF0_0000;
pub const SOC_DRAM_HIGH: u32 = 0x4FFC_0000;
}
#[export_name = "__post_init"]
unsafe fn post_init() {
// TODO: Disable watchdog timers
}

View File

@ -0,0 +1,116 @@
//! # Peripheral instance singletons (ESP32-P4)
//!
//! ## Overview
//!
//! The `Peripherals` module provides singleton instances of various peripherals
//! and allows users to access and use them in their applications.
//!
//! These peripherals provide various functionalities and interfaces for
//! interacting with different hardware components on the `ESP32-P4` chip, such
//! as timers, `GPIO` pins, `I2C`, `SPI`, `UART`, and more. Users can access and
//! utilize these peripherals by importing the respective singleton instances
//! from this module.
//!
//! It's important to note that the module also exports the `Interrupt` enum
//! from the `ESP32-P4` `PAC (Peripheral Access Crate)` for users to handle
//! interrupts associated with these peripherals.
//!
//! ⚠️ NOTE: notice that `radio` and `lp_core` are marked with `false` in the
//! `peripherals!` macro. Basically, that means that there's no real peripheral
//! (no `RADIO` nor `LP_CORE` peripheral in the PACs) but we're
//! creating "virtual peripherals" for them in order to ensure the uniqueness of
//! the instances (Singletons).
use esp32p4 as pac;
// We need to export this for users to use
pub use pac::Interrupt;
// We need to export this in the hal for the drivers to use
pub(crate) use self::peripherals::*;
crate::peripherals! {
ADC <= ADC,
AES <= AES,
ASSIST_DEBUG <= ASSIST_DEBUG,
AXI_DMA <= AXI_DMA,
AXI_ICM <= AXI_ICM,
BITSCRAMBLER <= BITSCRAMBLER,
CACHE <= CACHE,
DMA <= DMA,
DS <= DS,
ECC <= ECC,
ECDSA <= ECDSA,
EFUSE <= EFUSE,
GPIO <= GPIO,
GPIO_SD <= GPIO_SD,
H264 <= H264,
H264_DMA <= H264_DMA,
HMAC <= HMAC,
HP_SYS_CLKRST <= HP_SYS_CLKRST,
I2C0 <= I2C0,
I2C1 <= I2C1,
I2S0 <= I2S0,
I2S1 <= I2S1,
I2S2 <= I2S2,
I3C_MST <= I3C_MST,
I3C_MST_MEM <= I3C_MST_MEM,
I3C_SLV <= I3C_SLV,
INTERRUPT_CORE0 <= INTERRUPT_CORE0,
INTERRUPT_CORE1 <= INTERRUPT_CORE1,
IO_MUX <= IO_MUX,
ISP <= ISP,
JPEG <= JPEG,
LCD_CAM <= LCD_CAM,
LEDC <= LEDC,
LP_ADC <= LP_ADC,
LP_ANA_PERI <= LP_ANA_PERI,
LP_AON_CLKRST <= LP_AON_CLKRST,
LP_GPIO <= LP_GPIO,
LP_HUK <= LP_HUK,
LP_I2C_ANA_MST <= LP_I2C_ANA_MST,
LP_I2C0 <= LP_I2C0,
LP_I2S0 <= LP_I2S0,
LP_INTR <= LP_INTR,
LP_IO_MUX <= LP_IO_MUX,
LP_PERI <= LP_PERI,
LP_SYS <= LP_SYS,
LP_TIMER <= LP_TIMER,
LP_TOUCH <= LP_TOUCH,
LP_TSENS <= LP_TSENS,
LP_UART <= LP_UART,
LP_WDT <= LP_WDT,
MCPWM0 <= MCPWM0,
MCPWM1 <= MCPWM1,
MIPI_CSI_BRIDGE <= MIPI_CSI_BRIDGE,
MIPI_CSI_HOST <= MIPI_CSI_HOST,
MIPI_DSI_BRIDGE <= MIPI_DSI_BRIDGE,
MIPI_DSI_HOST <= MIPI_DSI_HOST,
PARL_IO <= PARL_IO,
PAU <= PAU,
PCNT <= PCNT,
PMU <= PMU,
PPA <= PPA,
PVT <= PVT,
RMT <= RMT,
RSA <= RSA,
SDHOST <= SDHOST,
SHA <= SHA,
SOC_ETM <= SOC_ETM,
SPI0 <= SPI0,
SPI1 <= SPI1,
SPI2 <= SPI2,
SPI3 <= SPI3,
SYSTEM <= HP_SYS,
SYSTIMER <= SYSTIMER,
TIMG0 <= TIMG0,
TIMG1 <= TIMG1,
TRACE0 <= TRACE0,
TRACE1 <= TRACE1,
TWAI0 <= TWAI0,
TWAI1 <= TWAI1,
TWAI2 <= TWAI2,
UART0 <= UART0,
UHCI0 <= UHCI0,
USB_DEVICE <= USB_DEVICE,
USB_WRAP <= USB_WRAP,
}

View File

@ -7,6 +7,7 @@ pub use self::soc::*;
#[cfg_attr(esp32c3, path = "esp32c3/mod.rs")]
#[cfg_attr(esp32c6, path = "esp32c6/mod.rs")]
#[cfg_attr(esp32h2, path = "esp32h2/mod.rs")]
#[cfg_attr(esp32p4, path = "esp32p4/mod.rs")]
#[cfg_attr(esp32s2, path = "esp32s2/mod.rs")]
#[cfg_attr(esp32s3, path = "esp32s3/mod.rs")]
mod soc;

View File

@ -30,9 +30,6 @@
use crate::{peripheral::PeripheralRef, peripherals::SYSTEM};
#[cfg(any(esp32c6, esp32h2))]
type IntPri = crate::peripherals::INTPRI;
pub enum SoftwareInterrupt {
SoftwareInterrupt0,
SoftwareInterrupt1,
@ -117,28 +114,28 @@ impl SoftwareInterruptControl {
#[cfg(not(any(esp32c6, esp32h2)))]
let system = unsafe { &*SYSTEM::PTR };
#[cfg(any(esp32c6, esp32h2))]
let system = unsafe { &*IntPri::PTR };
let system = unsafe { &*crate::peripherals::INTPRI::PTR };
match interrupt {
SoftwareInterrupt::SoftwareInterrupt0 => {
system
.cpu_intr_from_cpu_0()
.write(|w| w.cpu_intr_from_cpu_0().bit(true));
.write(|w| w.cpu_intr_from_cpu_0().set_bit());
}
SoftwareInterrupt::SoftwareInterrupt1 => {
system
.cpu_intr_from_cpu_1()
.write(|w| w.cpu_intr_from_cpu_1().bit(true));
.write(|w| w.cpu_intr_from_cpu_1().set_bit());
}
SoftwareInterrupt::SoftwareInterrupt2 => {
system
.cpu_intr_from_cpu_2()
.write(|w| w.cpu_intr_from_cpu_2().bit(true));
.write(|w| w.cpu_intr_from_cpu_2().set_bit());
}
SoftwareInterrupt::SoftwareInterrupt3 => {
system
.cpu_intr_from_cpu_3()
.write(|w| w.cpu_intr_from_cpu_3().bit(true));
.write(|w| w.cpu_intr_from_cpu_3().set_bit());
}
}
}
@ -147,28 +144,28 @@ impl SoftwareInterruptControl {
#[cfg(not(any(esp32c6, esp32h2)))]
let system = unsafe { &*SYSTEM::PTR };
#[cfg(any(esp32c6, esp32h2))]
let system = unsafe { &*IntPri::PTR };
let system = unsafe { &*crate::peripherals::INTPRI::PTR };
match interrupt {
SoftwareInterrupt::SoftwareInterrupt0 => {
system
.cpu_intr_from_cpu_0()
.write(|w| w.cpu_intr_from_cpu_0().bit(false));
.write(|w| w.cpu_intr_from_cpu_0().clear_bit());
}
SoftwareInterrupt::SoftwareInterrupt1 => {
system
.cpu_intr_from_cpu_1()
.write(|w| w.cpu_intr_from_cpu_1().bit(false));
.write(|w| w.cpu_intr_from_cpu_1().clear_bit());
}
SoftwareInterrupt::SoftwareInterrupt2 => {
system
.cpu_intr_from_cpu_2()
.write(|w| w.cpu_intr_from_cpu_2().bit(false));
.write(|w| w.cpu_intr_from_cpu_2().clear_bit());
}
SoftwareInterrupt::SoftwareInterrupt3 => {
system
.cpu_intr_from_cpu_3()
.write(|w| w.cpu_intr_from_cpu_3().bit(false));
.write(|w| w.cpu_intr_from_cpu_3().clear_bit());
}
}
}
@ -183,8 +180,6 @@ impl PeripheralClockControl {
pub(crate) fn enable(peripheral: Peripheral) {
let system = unsafe { &*SYSTEM::PTR };
#[cfg(not(esp32))]
let (perip_clk_en0, perip_rst_en0) = { (&system.perip_clk_en0(), &system.perip_rst_en0()) };
#[cfg(esp32)]
let (perip_clk_en0, perip_rst_en0, peri_clk_en, peri_rst_en) = {
(
@ -194,6 +189,8 @@ impl PeripheralClockControl {
&system.peri_rst_en(),
)
};
#[cfg(not(any(esp32, esp32p4)))]
let (perip_clk_en0, perip_rst_en0) = { (&system.perip_clk_en0(), &system.perip_rst_en0()) };
#[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))]
let (perip_clk_en1, perip_rst_en1) = { (&system.perip_clk_en1(), &system.perip_rst_en1()) };
@ -209,12 +206,12 @@ impl PeripheralClockControl {
perip_clk_en0.modify(|_, w| w.spi3_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.spi3_rst().clear_bit());
}
#[cfg(esp32)]
#[cfg(all(i2c0, esp32))]
Peripheral::I2cExt0 => {
perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().clear_bit());
}
#[cfg(not(esp32))]
#[cfg(all(i2c0, not(esp32)))]
Peripheral::I2cExt0 => {
perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().clear_bit());
@ -229,6 +226,7 @@ impl PeripheralClockControl {
perip_clk_en0.modify(|_, w| w.rmt_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.rmt_rst().clear_bit());
}
#[cfg(ledc)]
Peripheral::Ledc => {
perip_clk_en0.modify(|_, w| w.ledc_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.ledc_rst().clear_bit());
@ -326,6 +324,7 @@ impl PeripheralClockControl {
perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit());
perip_rst_en0.modify(|_, w| w.timergroup1_rst().clear_bit());
}
#[cfg(sha)]
Peripheral::Sha => {
#[cfg(not(esp32))]
perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().set_bit());
@ -342,10 +341,12 @@ impl PeripheralClockControl {
perip_clk_en1.modify(|_, w| w.usb_device_clk_en().set_bit());
perip_rst_en1.modify(|_, w| w.usb_device_rst().clear_bit());
}
#[cfg(uart0)]
Peripheral::Uart0 => {
perip_clk_en0.modify(|_, w| w.uart_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.uart_rst().clear_bit());
}
#[cfg(uart1)]
Peripheral::Uart1 => {
perip_clk_en0.modify(|_, w| w.uart1_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.uart1_rst().clear_bit());
@ -360,12 +361,12 @@ impl PeripheralClockControl {
perip_clk_en0.modify(|_, w| w.uart2_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.uart2_rst().clear_bit());
}
#[cfg(esp32)]
#[cfg(all(rsa, esp32))]
Peripheral::Rsa => {
peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | 1 << 2) });
peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << 2)) });
}
#[cfg(any(esp32c3, esp32s2, esp32s3))]
#[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))]
Peripheral::Rsa => {
perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().set_bit());
perip_rst_en1.modify(|_, w| w.crypto_rsa_rst().clear_bit());

View File

@ -31,6 +31,7 @@ esp32c3 = []
esp32c6 = ["dep:object"]
esp32c6-lp = []
esp32h2 = []
esp32p4 = []
esp32s2 = ["dep:object"]
esp32s2-ulp = []
esp32s3 = ["dep:object"]

View File

@ -76,7 +76,6 @@
#[cfg(feature = "ram")]
use darling::{ast::NestedMeta, Error as DarlingError, FromMeta};
use proc_macro::TokenStream;
use proc_macro_crate::FoundCrate;
use proc_macro_error::proc_macro_error;
use quote::quote;
use syn::parse_macro_input;
@ -101,7 +100,7 @@ mod lp_core;
feature = "interrupt"
))]
fn get_hal_crate() -> (
Result<FoundCrate, proc_macro_crate::Error>,
Result<proc_macro_crate::FoundCrate, proc_macro_crate::Error>,
proc_macro2::Ident,
) {
use proc_macro::Span;
@ -121,6 +120,8 @@ fn get_hal_crate() -> (
let hal_crate = crate_name("esp32c6-lp-hal");
#[cfg(feature = "esp32h2")]
let hal_crate = crate_name("esp32h2-hal");
#[cfg(feature = "esp32p4")]
let hal_crate = crate_name("esp32p4-hal");
#[cfg(feature = "esp32s2")]
let hal_crate = crate_name("esp32s2-hal");
#[cfg(feature = "esp32s2-ulp")]
@ -143,6 +144,8 @@ fn get_hal_crate() -> (
let hal_crate_name = Ident::new("esp32c6_lp_hal", Span::call_site().into());
#[cfg(feature = "esp32h2")]
let hal_crate_name = Ident::new("esp32h2_hal", Span::call_site().into());
#[cfg(feature = "esp32p4")]
let hal_crate_name = Ident::new("esp32p4_hal", Span::call_site().into());
#[cfg(feature = "esp32s2")]
let hal_crate_name = Ident::new("esp32s2_hal", Span::call_site().into());
#[cfg(feature = "esp32s2-ulp")]
@ -282,6 +285,7 @@ pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream {
use proc_macro::Span;
use proc_macro2::Ident;
use proc_macro_crate::FoundCrate;
use proc_macro_error::abort;
use syn::{
parse::Error as ParseError,
@ -498,6 +502,7 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
use object::{Object, ObjectSection, ObjectSymbol};
use proc_macro::Span;
use proc_macro_crate::FoundCrate;
use syn::{parse, Ident};
let (hal_crate, hal_crate_name) = get_hal_crate();
@ -667,7 +672,7 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
#[proc_macro_attribute]
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
use proc_macro2::{Ident, Span};
use proc_macro_crate::crate_name;
use proc_macro_crate::{crate_name, FoundCrate};
use quote::{format_ident, quote};
use syn::{parse, parse_macro_input, spanned::Spanned, FnArg, ItemFn};

View File

@ -0,0 +1,12 @@
[target.riscv32imafc-unknown-none-elf]
runner = "espflash flash --monitor"
rustflags = [
"-C", "link-arg=-Tlinkall.x",
"-C", "force-frame-pointers",
]
[build]
target = "riscv32imafc-unknown-none-elf"
[unstable]
build-std = ["core"]

63
esp32p4-hal/Cargo.toml Normal file
View File

@ -0,0 +1,63 @@
[package]
name = "esp32p4-hal"
version = "0.1.0"
edition = "2021"
rust-version = "1.67.0"
description = "HAL for ESP32-P4 microcontrollers"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
keywords = [
"embedded",
"embedded-hal",
"esp",
"esp32p4",
"no-std",
]
categories = [
"embedded",
"hardware-support",
"no-std",
]
[dependencies]
esp-hal-common = { version = "0.15.0", features = ["esp32p4"], path = "../esp-hal-common" }
[dev-dependencies]
embassy-time = "0.3.0"
esp-backtrace = { version = "0.10.0", features = ["esp32p4", "exception-handler", "panic-handler", "print-uart"] }
esp-println = { version = "0.8.0", features = ["esp32p4"] }
[features]
default = ["rt", "vectored", "zero-rtc-bss"]
async = ["esp-hal-common/async"]
debug = ["esp-hal-common/debug"]
defmt = ["esp-hal-common/defmt", "esp-println/defmt-espflash"]
direct-vectoring = ["esp-hal-common/direct-vectoring"]
eh1 = ["esp-hal-common/eh1"]
embedded-io = ["esp-hal-common/embedded-io"]
interrupt-preemption = ["esp-hal-common/interrupt-preemption"]
log = ["esp-hal-common/log", "esp-println/log"]
rt = ["esp-hal-common/rt-riscv"]
ufmt = ["esp-hal-common/ufmt"]
vectored = ["esp-hal-common/vectored"]
# Initialize / clear data sections and RTC memory
zero-rtc-bss = ["esp-hal-common/rv-zero-rtc-bss"]
init-data = ["esp-hal-common/rv-init-data"]
init-rtc-data = ["esp-hal-common/rv-init-rtc-data"]
# Embassy support
embassy = ["esp-hal-common/embassy"]
embassy-executor-interrupt = ["esp-hal-common/embassy-executor-interrupt"]
embassy-executor-thread = ["esp-hal-common/embassy-executor-thread"]
embassy-integrated-timers = ["esp-hal-common/embassy-integrated-timers"]
embassy-time-systick = ["esp-hal-common/embassy-time-systick", "embassy-time/tick-hz-16_000_000"]
embassy-time-timg0 = ["esp-hal-common/embassy-time-timg0", "embassy-time/tick-hz-1_000_000"]
[profile.release]
debug = true
[patch.crates-io]
esp-backtrace = { git = "https://github.com/jessebraham/esp-backtrace", branch = "feature/esp32p4" }
esp-println = { git = "https://github.com/esp-rs/esp-println", rev = "1f628e3" }

51
esp32p4-hal/README.md Normal file
View File

@ -0,0 +1,51 @@
# esp32p4-hal
[![Crates.io](https://img.shields.io/crates/v/esp32p4-hal?labelColor=1C2C2E&color=C96329&logo=Rust&style=flat-square)](https://crates.io/crates/esp32p4-hal)
[![docs.rs](https://img.shields.io/docsrs/esp32p4-hal?labelColor=1C2C2E&color=C96329&logo=rust&style=flat-square)](https://docs.rs/esp32p4-hal)
![Crates.io](https://img.shields.io/crates/l/esp32p4-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)
`no_std` HAL for the ESP32-P4 from Espressif.
Implements a number of the traits defined in [embedded-hal](https://github.com/rust-embedded/embedded-hal).
This device uses the RISC-V ISA, which is officially supported by the Rust compiler via the `riscv32imafc-unknown-none-elf` target.
Please refer to the documentation for more information.
## [Documentation]
[documentation]: https://docs.rs/esp32p4-hal/
## Resources
- [Datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-p4_datasheet_en.pdf)
- [Technical Reference Manual](https://www.espressif.com/sites/default/files/documentation/esp32-p4_technical_reference_manual_en.pdf)
- [The Rust Programming Language](https://doc.rust-lang.org/book/)
- [The Embedded Rust Book](https://docs.rust-embedded.org/book/index.html)
- [The Rust on ESP Book](https://esp-rs.github.io/book/)
## Getting Started
### Installing the Rust Compiler Target
The compilation target for this device is officially supported by the mainline Rust compiler and can be installed using [rustup](https://rustup.rs/):
```shell
rustup target add riscv32imafc-unknown-none-elf
```
## 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.

16
esp32p4-hal/build.rs Normal file
View File

@ -0,0 +1,16 @@
use std::{env, error::Error, path::PathBuf};
fn main() -> Result<(), Box<dyn Error>> {
// Put the linker script somewhere the linker can find it
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
println!("cargo:rustc-link-search={}", out.display());
// Only re-run the build script when memory.x is changed,
// instead of when any part of the source code changes.
println!("cargo:rerun-if-changed=ld/memory.x");
#[cfg(feature = "defmt")]
println!("cargo:rustc-link-arg=-Tdefmt.x");
Ok(())
}

View File

@ -0,0 +1,11 @@
#![no_std]
#![no_main]
use esp32p4_hal::prelude::*;
use esp_backtrace as _;
#[entry]
fn main() -> ! {
esp_println::println!("Hello, world!");
loop {}
}

11
esp32p4-hal/src/lib.rs Normal file
View File

@ -0,0 +1,11 @@
//! `no_std` HAL for the ESP32-P4 from Espressif.
//!
//! Implements a number of the traits defined by the various packages in the
//! [embedded-hal] repository.
//!
//! [embedded-hal]: https://github.com/rust-embedded/embedded-hal
#![no_std]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
pub use esp_hal_common::*;