Bump edition to 2024, bump MSRV to 1.85 (#3391)

* inter-state

* inter-state (2)

* warnings fix

* fix warnings

* fmt + changelogs

* another unsafe extern "C" doode

* real fmt now

* MSRV + format

* Ignore unsafe_op_in_unsafe_fn lint for now in esp-hal and esp-wifi

* msrv + fmt

* ugh....

* get lcd_cam example right

* expr_2021 -> expr experiment

* gagagugu

* reviews

* more unneeded unsafes (help)

* finish esp-hal unsafe cleanup

* each unsafe call is marked separately

fmt

* should be good now (?)

* piece was never an option...

* dumb
This commit is contained in:
Kirill Mikhailov 2025-04-22 12:39:11 +02:00 committed by GitHub
parent df6aa9c18f
commit b33b877592
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
301 changed files with 2569 additions and 2105 deletions

View File

@ -24,7 +24,7 @@ on:
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MSRV: "1.84.0" MSRV: "1.85.0"
DEFMT_LOG: trace DEFMT_LOG: trace
# Cancel any currently running workflows from the same PR, branch, or # Cancel any currently running workflows from the same PR, branch, or

View File

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `AnyMemory`, `InternalMemory`, `ExternalMemory` allocators. (#3318) - `AnyMemory`, `InternalMemory`, `ExternalMemory` allocators. (#3318)
### Changed ### Changed
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Fixed ### Fixed

View File

@ -1,8 +1,8 @@
[package] [package]
name = "esp-alloc" name = "esp-alloc"
version = "0.7.0" version = "0.7.0"
edition = "2021" edition = "2024"
rust-version = "1.84.0" rust-version = "1.85.0"
description = "A heap allocator for Espressif devices" description = "A heap allocator for Espressif devices"
documentation = "https://docs.espressif.com/projects/rust/esp-alloc/latest/" documentation = "https://docs.espressif.com/projects/rust/esp-alloc/latest/"
keywords = ["allocator", "embedded", "esp32", "espressif", "memory"] keywords = ["allocator", "embedded", "esp32", "espressif", "memory"]
@ -14,6 +14,10 @@ license = "MIT OR Apache-2.0"
default-target = "riscv32imc-unknown-none-elf" default-target = "riscv32imc-unknown-none-elf"
features = ["nightly"] features = ["nightly"]
[lib]
bench = false
test = false
[dependencies] [dependencies]
allocator-api2 = { version = "0.2.0", default-features = false } allocator-api2 = { version = "0.2.0", default-features = false }
defmt = { version = "0.3.10", optional = true } defmt = { version = "0.3.10", optional = true }

View File

@ -24,7 +24,9 @@ unsafe impl Allocator for EspHeap {
} }
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
crate::HEAP.dealloc(ptr.as_ptr(), layout); unsafe {
crate::HEAP.dealloc(ptr.as_ptr(), layout);
}
} }
} }
@ -37,7 +39,9 @@ unsafe impl Allocator for AnyMemory {
} }
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
crate::HEAP.dealloc(ptr.as_ptr(), layout); unsafe {
crate::HEAP.dealloc(ptr.as_ptr(), layout);
}
} }
} }
@ -50,7 +54,9 @@ unsafe impl Allocator for InternalMemory {
} }
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
crate::HEAP.dealloc(ptr.as_ptr(), layout); unsafe {
crate::HEAP.dealloc(ptr.as_ptr(), layout);
}
} }
} }
@ -63,6 +69,8 @@ unsafe impl Allocator for ExternalMemory {
} }
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
crate::HEAP.dealloc(ptr.as_ptr(), layout); unsafe {
crate::HEAP.dealloc(ptr.as_ptr(), layout);
}
} }
} }

View File

@ -275,10 +275,12 @@ impl HeapRegion {
size: usize, size: usize,
capabilities: EnumSet<MemoryCapability>, capabilities: EnumSet<MemoryCapability>,
) -> Self { ) -> Self {
let mut heap = Heap::empty(); unsafe {
heap.init(heap_bottom, size); let mut heap = Heap::empty();
heap.init(heap_bottom, size);
Self { heap, capabilities } Self { heap, capabilities }
}
} }
/// Return stats for the current memory region /// Return stats for the current memory region
@ -599,35 +601,37 @@ impl EspHeap {
unsafe impl GlobalAlloc for EspHeap { unsafe impl GlobalAlloc for EspHeap {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 { unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
self.alloc_caps(EnumSet::empty(), layout) unsafe { self.alloc_caps(EnumSet::empty(), layout) }
} }
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
if ptr.is_null() { unsafe {
return; if ptr.is_null() {
} return;
}
critical_section::with(|cs| { critical_section::with(|cs| {
#[cfg(feature = "internal-heap-stats")] #[cfg(feature = "internal-heap-stats")]
let before = self.used(); let before = self.used();
let mut regions = self.heap.borrow_ref_mut(cs); let mut regions = self.heap.borrow_ref_mut(cs);
let mut iter = (*regions).iter_mut(); let mut iter = (*regions).iter_mut();
while let Some(Some(region)) = iter.next() { while let Some(Some(region)) = iter.next() {
if region.heap.bottom() <= ptr && region.heap.top() >= ptr { if region.heap.bottom() <= ptr && region.heap.top() >= ptr {
region.heap.deallocate(NonNull::new_unchecked(ptr), layout); region.heap.deallocate(NonNull::new_unchecked(ptr), layout);
}
} }
}
#[cfg(feature = "internal-heap-stats")] #[cfg(feature = "internal-heap-stats")]
{ {
let mut internal_heap_stats = self.internal_heap_stats.borrow_ref_mut(cs); let mut internal_heap_stats = self.internal_heap_stats.borrow_ref_mut(cs);
drop(regions); drop(regions);
// We need to call `used()` because [linked_list_allocator::Heap] does internal // We need to call `used()` because [linked_list_allocator::Heap] does internal
// size alignment so we cannot use the size provided by the // size alignment so we cannot use the size provided by the
// layout. // layout.
internal_heap_stats.total_freed += before - self.used(); internal_heap_stats.total_freed += before - self.used();
} }
}) })
}
} }
} }

View File

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- The `arch::backtrace` function now returns a `Backtrace` struct (#3280) - The `arch::backtrace` function now returns a `Backtrace` struct (#3280)
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Fixed ### Fixed

View File

@ -1,8 +1,8 @@
[package] [package]
name = "esp-backtrace" name = "esp-backtrace"
version = "0.15.1" version = "0.15.1"
edition = "2021" edition = "2024"
rust-version = "1.84.0" rust-version = "1.85.0"
description = "Bare-metal backtrace support for Espressif devices" description = "Bare-metal backtrace support for Espressif devices"
documentation = "https://docs.espressif.com/projects/rust/esp-backtrace/latest/" documentation = "https://docs.espressif.com/projects/rust/esp-backtrace/latest/"
keywords = ["backtrace", "embedded", "esp32", "espressif"] keywords = ["backtrace", "embedded", "esp32", "espressif"]
@ -14,6 +14,10 @@ license = "MIT OR Apache-2.0"
default-target = "riscv32imc-unknown-none-elf" default-target = "riscv32imc-unknown-none-elf"
features = ["esp32c3", "panic-handler", "exception-handler", "println", "esp-println/uart"] features = ["esp32c3", "panic-handler", "exception-handler", "println", "esp-println/uart"]
[lib]
bench = false
test = false
[dependencies] [dependencies]
cfg-if = "1.0.0" cfg-if = "1.0.0"
defmt = { version = "0.3.10", optional = true } defmt = { version = "0.3.10", optional = true }

View File

@ -1,5 +1,5 @@
use esp_build::assert_unique_used_features; use esp_build::assert_unique_used_features;
use esp_config::{generate_config, ConfigOption, Stability, Value}; use esp_config::{ConfigOption, Stability, Value, generate_config};
fn main() { fn main() {
// Ensure that only a single chip is specified: // Ensure that only a single chip is specified:

View File

@ -90,7 +90,9 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
let backtrace = Backtrace::capture(); let backtrace = Backtrace::capture();
#[cfg(target_arch = "riscv32")] #[cfg(target_arch = "riscv32")]
if backtrace.frames().is_empty() { if backtrace.frames().is_empty() {
println!("No backtrace available - make sure to force frame-pointers. (see https://crates.io/crates/esp-backtrace)"); println!(
"No backtrace available - make sure to force frame-pointers. (see https://crates.io/crates/esp-backtrace)"
);
} }
for frame in backtrace.frames() { for frame in backtrace.frames() {
println!("0x{:x}", frame.program_counter()); println!("0x{:x}", frame.program_counter());
@ -100,8 +102,8 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
} }
#[cfg(all(feature = "exception-handler", target_arch = "xtensa"))] #[cfg(all(feature = "exception-handler", target_arch = "xtensa"))]
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".rwtext"] #[unsafe(link_section = ".rwtext")]
unsafe fn __user_exception(cause: arch::ExceptionCause, context: arch::Context) { unsafe fn __user_exception(cause: arch::ExceptionCause, context: arch::Context) {
pre_backtrace(); pre_backtrace();
@ -117,7 +119,7 @@ unsafe fn __user_exception(cause: arch::ExceptionCause, context: arch::Context)
} }
#[cfg(all(feature = "exception-handler", target_arch = "riscv32"))] #[cfg(all(feature = "exception-handler", target_arch = "riscv32"))]
#[export_name = "ExceptionHandler"] #[unsafe(export_name = "ExceptionHandler")]
fn exception_handler(context: &arch::TrapFrame) -> ! { fn exception_handler(context: &arch::TrapFrame) -> ! {
pre_backtrace(); pre_backtrace();
@ -163,7 +165,9 @@ fn exception_handler(context: &arch::TrapFrame) -> ! {
let backtrace = Backtrace::from_sp(context.s0 as u32); let backtrace = Backtrace::from_sp(context.s0 as u32);
let frames = backtrace.frames(); let frames = backtrace.frames();
if frames.is_empty() { if frames.is_empty() {
println!("No backtrace available - make sure to force frame-pointers. (see https://crates.io/crates/esp-backtrace)"); println!(
"No backtrace available - make sure to force frame-pointers. (see https://crates.io/crates/esp-backtrace)"
);
} }
for frame in backtrace.frames() { for frame in backtrace.frames() {
println!("0x{:x}", frame.program_counter()); println!("0x{:x}", frame.program_counter());
@ -233,7 +237,7 @@ fn halt() -> ! {
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(feature = "custom-halt")] { if #[cfg(feature = "custom-halt")] {
// call custom code // call custom code
extern "Rust" { unsafe extern "Rust" {
fn custom_halt() -> !; fn custom_halt() -> !;
} }
unsafe { custom_halt() } unsafe { custom_halt() }
@ -285,7 +289,7 @@ fn halt() -> ! {
fn pre_backtrace() { fn pre_backtrace() {
#[cfg(feature = "custom-pre-backtrace")] #[cfg(feature = "custom-pre-backtrace")]
{ {
extern "Rust" { unsafe extern "Rust" {
fn custom_pre_backtrace(); fn custom_pre_backtrace();
} }
unsafe { custom_pre_backtrace() } unsafe { custom_pre_backtrace() }

View File

@ -102,7 +102,10 @@ pub enum ExceptionCause {
impl Display for ExceptionCause { impl Display for ExceptionCause {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if *self == Self::Cp0Disabled { 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.)") 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 { } else {
write!(f, "{:?}", self) write!(f, "{:?}", self)
} }

View File

@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Fixed ### Fixed
### Removed ### Removed

View File

@ -1,8 +1,8 @@
[package] [package]
name = "esp-bootloader-esp-idf" name = "esp-bootloader-esp-idf"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2024"
rust-version = "1.84.0" rust-version = "1.85.0"
description = "Functionality related to the esp-idf bootloader" description = "Functionality related to the esp-idf bootloader"
documentation = "https://docs.espressif.com/projects/rust/esp-bootloader-esp-idf/latest/" documentation = "https://docs.espressif.com/projects/rust/esp-bootloader-esp-idf/latest/"
keywords = ["esp32", "espressif", "no-std"] keywords = ["esp32", "espressif", "no-std"]
@ -13,6 +13,10 @@ license = "MIT OR Apache-2.0"
[package.metadata.docs.rs] [package.metadata.docs.rs]
default-target = "riscv32imac-unknown-none-elf" default-target = "riscv32imac-unknown-none-elf"
[lib]
bench = false
test = false
[dependencies] [dependencies]
defmt = { version = "0.3.10", optional = true } defmt = { version = "0.3.10", optional = true }
document-features = "0.2.11" document-features = "0.2.11"

View File

@ -1,7 +1,7 @@
use std::env; use std::env;
use chrono::{TimeZone, Utc}; use chrono::{TimeZone, Utc};
use esp_config::{generate_config, ConfigOption, Stability, Validator, Value}; use esp_config::{ConfigOption, Stability, Validator, Value, generate_config};
fn main() { fn main() {
let build_time = match env::var("SOURCE_DATE_EPOCH") { let build_time = match env::var("SOURCE_DATE_EPOCH") {

View File

@ -43,9 +43,9 @@ pub mod ota;
// We run tests on the host which happens to be MacOS machines and mach-o // We run tests on the host which happens to be MacOS machines and mach-o
// doesn't like `link-sections` this way // doesn't like `link-sections` this way
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
#[link_section = ".espressif.metadata"] #[unsafe(link_section = ".espressif.metadata")]
#[used] #[used]
#[export_name = "bootloader.NAME"] #[unsafe(export_name = "bootloader.NAME")]
static OTA_FEATURE: [u8; 7] = *b"ESP-IDF"; static OTA_FEATURE: [u8; 7] = *b"ESP-IDF";
/// ESP-IDF compatible application descriptor /// ESP-IDF compatible application descriptor
@ -305,8 +305,8 @@ macro_rules! esp_app_desc {
$min_efuse_blk_rev_full: expr, $min_efuse_blk_rev_full: expr,
$max_efuse_blk_rev_full: expr $max_efuse_blk_rev_full: expr
) => { ) => {
#[export_name = "esp_app_desc"] #[unsafe(export_name = "esp_app_desc")]
#[link_section = ".rodata_desc.appdesc"] #[unsafe(link_section = ".rodata_desc.appdesc")]
pub static ESP_APP_DESC: $crate::EspAppDesc = $crate::EspAppDesc::new_internal( pub static ESP_APP_DESC: $crate::EspAppDesc = $crate::EspAppDesc::new_internal(
$version, $version,
$project_name, $project_name,

View File

@ -6,7 +6,7 @@ impl Crc32 {
} }
pub fn crc(&self, data: &[u8]) -> u32 { pub fn crc(&self, data: &[u8]) -> u32 {
extern "C" { unsafe extern "C" {
fn esp_rom_crc32_le(crc: u32, buf: *const u8, len: u32) -> u32; fn esp_rom_crc32_le(crc: u32, buf: *const u8, len: u32) -> u32;
} }

View File

@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Fixed ### Fixed
### Removed ### Removed

View File

@ -1,8 +1,8 @@
[package] [package]
name = "esp-build" name = "esp-build"
version = "0.2.0" version = "0.2.0"
edition = "2021" edition = "2024"
rust-version = "1.84.0" rust-version = "1.85.0"
description = "Build utilities for esp-hal" description = "Build utilities for esp-hal"
documentation = "https://docs.espressif.com/projects/rust/esp-build/latest/" documentation = "https://docs.espressif.com/projects/rust/esp-build/latest/"
repository = "https://github.com/esp-rs/esp-hal" repository = "https://github.com/esp-rs/esp-hal"

View File

@ -6,7 +6,7 @@ use std::io::Write as _;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::ToTokens; use quote::ToTokens;
use syn::{parse_macro_input, punctuated::Punctuated, LitStr, Token}; use syn::{LitStr, Token, parse_macro_input, punctuated::Punctuated};
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
/// Print a build error and terminate the process. /// Print a build error and terminate the process.
@ -113,7 +113,7 @@ pub fn assert_unique_used_features(input: TokenStream) -> TokenStream {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Helper Functions // Helper Functions
fn impl_unique_features(features: &[LitStr], expectation: &str) -> impl ToTokens { fn impl_unique_features(features: &[LitStr], expectation: &str) -> impl ToTokens + use<> {
let pairs = unique_pairs(features); let pairs = unique_pairs(features);
let unique_cfgs = pairs let unique_cfgs = pairs
.iter() .iter()
@ -133,7 +133,7 @@ ERROR: expected {expectation} enabled feature from feature group:
} }
} }
fn impl_used_features(features: &[LitStr], expectation: &str) -> impl ToTokens { fn impl_used_features(features: &[LitStr], expectation: &str) -> impl ToTokens + use<> {
let message = format!( let message = format!(
r#" r#"
ERROR: expected {expectation} enabled feature from feature group: ERROR: expected {expectation} enabled feature from feature group:

View File

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- `generate_config` now takes a slice of `ConfigOption`s instead of tuples. (#3362) - `generate_config` now takes a slice of `ConfigOption`s instead of tuples. (#3362)
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Fixed ### Fixed

View File

@ -1,13 +1,17 @@
[package] [package]
name = "esp-config" name = "esp-config"
version = "0.3.1" version = "0.3.1"
edition = "2021" edition = "2024"
rust-version = "1.84.0" rust-version = "1.85.0"
description = "Configure projects using esp-hal and related packages" description = "Configure projects using esp-hal and related packages"
documentation = "https://docs.espressif.com/projects/rust/esp-config/latest/" documentation = "https://docs.espressif.com/projects/rust/esp-config/latest/"
repository = "https://github.com/esp-rs/esp-hal" repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
[lib]
bench = false
test = false
[dependencies] [dependencies]
document-features = "0.2.10" document-features = "0.2.10"
serde = { version = "1.0.197", features = ["derive"], optional = true } serde = { version = "1.0.197", features = ["derive"], optional = true }

View File

@ -2,7 +2,7 @@ use std::{io::Write, ops::Range};
use serde::Serialize; use serde::Serialize;
use super::{snake_case, value::Value, Error}; use super::{Error, snake_case, value::Value};
type CustomValidatorFn = Box<dyn Fn(&Value) -> Result<(), Error>>; type CustomValidatorFn = Box<dyn Fn(&Value) -> Result<(), Error>>;

View File

@ -25,7 +25,7 @@ impl Value {
_ => { _ => {
return Err(Error::parse(format!( return Err(Error::parse(format!(
"Expected 'true' or 'false', found: '{s}'" "Expected 'true' or 'false', found: '{s}'"
))) )));
} }
}, },
Value::Integer(_) => { Value::Integer(_) => {

View File

@ -9,12 +9,12 @@
mod generate; mod generate;
#[cfg(feature = "build")] #[cfg(feature = "build")]
pub use generate::{ pub use generate::{
generate_config,
validator::Validator,
value::Value,
ConfigOption, ConfigOption,
Error, Error,
Stability, Stability,
generate_config,
validator::Validator,
value::Value,
}; };
/// Parse the value of an environment variable as a [bool] at compile time. /// Parse the value of an environment variable as a [bool] at compile time.

View File

@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Re-added the `multiple-integrated` timer queue flavour (#3166) - Re-added the `multiple-integrated` timer queue flavour (#3166)
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Changed ### Changed
### Fixed ### Fixed

View File

@ -1,8 +1,8 @@
[package] [package]
name = "esp-hal-embassy" name = "esp-hal-embassy"
version = "0.7.0" version = "0.7.0"
edition = "2021" edition = "2024"
rust-version = "1.84.0" rust-version = "1.85.0"
description = "Embassy support for esp-hal" description = "Embassy support for esp-hal"
documentation = "https://docs.espressif.com/projects/rust/esp-hal-embassy/latest/" documentation = "https://docs.espressif.com/projects/rust/esp-hal-embassy/latest/"
keywords = ["async", "embedded", "esp32", "espressif"] keywords = ["async", "embedded", "esp32", "espressif"]
@ -14,6 +14,10 @@ license = "MIT OR Apache-2.0"
default-target = "riscv32imac-unknown-none-elf" default-target = "riscv32imac-unknown-none-elf"
features = ["esp32c6"] features = ["esp32c6"]
[lib]
bench = false
test = false
[dependencies] [dependencies]
critical-section = "1.2.0" critical-section = "1.2.0"
defmt = { version = "0.3.10", optional = true } defmt = { version = "0.3.10", optional = true }

View File

@ -1,7 +1,7 @@
use std::{error::Error as StdError, str::FromStr}; use std::{error::Error as StdError, str::FromStr};
use esp_build::assert_unique_used_features; use esp_build::assert_unique_used_features;
use esp_config::{generate_config, ConfigOption, Stability, Validator, Value}; use esp_config::{ConfigOption, Stability, Validator, Value, generate_config};
use esp_metadata::{Chip, Config}; use esp_metadata::{Chip, Config};
fn main() -> Result<(), Box<dyn StdError>> { fn main() -> Result<(), Box<dyn StdError>> {

View File

@ -4,7 +4,7 @@ use core::{cell::UnsafeCell, mem::MaybeUninit};
use embassy_executor::SendSpawner; use embassy_executor::SendSpawner;
use esp_hal::{ use esp_hal::{
interrupt::{self, software::SoftwareInterrupt, InterruptHandler}, interrupt::{self, InterruptHandler, software::SoftwareInterrupt},
system::Cpu, system::Cpu,
}; };
use portable_atomic::{AtomicUsize, Ordering}; use portable_atomic::{AtomicUsize, Ordering};

View File

@ -8,7 +8,7 @@ use crate::timer_queue::TimerQueue;
mod interrupt; mod interrupt;
mod thread; mod thread;
#[export_name = "__pender"] #[unsafe(export_name = "__pender")]
fn __pender(context: *mut ()) { fn __pender(context: *mut ()) {
use esp_hal::interrupt::software::SoftwareInterrupt; use esp_hal::interrupt::software::SoftwareInterrupt;

View File

@ -54,7 +54,7 @@ mod fmt;
#[cfg(not(feature = "esp32"))] #[cfg(not(feature = "esp32"))]
use esp_hal::timer::systimer::Alarm; use esp_hal::timer::systimer::Alarm;
use esp_hal::timer::{timg::Timer as TimgTimer, AnyTimer}; use esp_hal::timer::{AnyTimer, timg::Timer as TimgTimer};
pub use macros::embassy_main as main; pub use macros::embassy_main as main;
#[cfg(feature = "executors")] #[cfg(feature = "executors")]

View File

@ -8,11 +8,11 @@ use core::cell::Cell;
use embassy_time_driver::Driver; use embassy_time_driver::Driver;
use esp_hal::{ use esp_hal::{
Blocking,
interrupt::{InterruptHandler, Priority}, interrupt::{InterruptHandler, Priority},
sync::Locked, sync::Locked,
time::{Duration, Instant}, time::{Duration, Instant},
timer::OneShotTimer, timer::OneShotTimer,
Blocking,
}; };
pub type Timer = OneShotTimer<'static, Blocking>; pub type Timer = OneShotTimer<'static, Blocking>;
@ -228,40 +228,42 @@ impl EmbassyTimer {
/// When using a single timer queue, the `priority` parameter is always the /// When using a single timer queue, the `priority` parameter is always the
/// highest value possible. /// highest value possible.
pub(crate) unsafe fn allocate_alarm(&self, priority: Priority) -> Option<AlarmHandle> { pub(crate) unsafe fn allocate_alarm(&self, priority: Priority) -> Option<AlarmHandle> {
for (i, alarm) in self.alarms.iter().enumerate() { unsafe {
let handle = alarm.inner.with(|alarm| { for (i, alarm) in self.alarms.iter().enumerate() {
let AlarmState::Created(interrupt_handler) = alarm.state else { let handle = alarm.inner.with(|alarm| {
return None; let AlarmState::Created(interrupt_handler) = alarm.state else {
}; return None;
};
let timer = self.available_timers.with(|available_timers| { let timer = self.available_timers.with(|available_timers| {
if let Some(timers) = available_timers.take() { if let Some(timers) = available_timers.take() {
// If the driver is initialized, we can allocate a timer. // If the driver is initialized, we can allocate a timer.
// If this fails, we can't do anything about it. // If this fails, we can't do anything about it.
let Some((timer, rest)) = timers.split_first_mut() else { let Some((timer, rest)) = timers.split_first_mut() else {
not_enough_timers(); not_enough_timers();
}; };
*available_timers = Some(rest); *available_timers = Some(rest);
timer timer
} else { } else {
panic!("schedule_wake called before esp_hal_embassy::init()") panic!("schedule_wake called before esp_hal_embassy::init()")
} }
});
alarm.state = AlarmState::initialize(
timer,
InterruptHandler::new(interrupt_handler, priority),
);
Some(AlarmHandle::new(i))
}); });
alarm.state = AlarmState::initialize( if handle.is_some() {
timer, return handle;
InterruptHandler::new(interrupt_handler, priority), }
);
Some(AlarmHandle::new(i))
});
if handle.is_some() {
return handle;
} }
}
None None
}
} }
/// Set an alarm to fire at a certain timestamp. /// Set an alarm to fire at a certain timestamp.
@ -362,7 +364,9 @@ fn not_enough_timers() -> ! {
// This is wrapped in a separate function because rustfmt does not like // 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 // extremely long strings. Also, if log is used, this avoids storing the string
// twice. // 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 either using the `single-integrated` or the `generic` timer queue flavors."); panic!(
"There are not enough timers to allocate a new alarm. Call esp_hal_embassy::init() with the correct number of timers, or consider either using the `single-integrated` or the `generic` timer queue flavors."
);
} }
pub(crate) fn set_up_alarm(priority: Priority, _ctx: *mut ()) -> AlarmHandle { pub(crate) fn set_up_alarm(priority: Priority, _ctx: *mut ()) -> AlarmHandle {

View File

@ -12,7 +12,7 @@ use embassy_sync::blocking_mutex::Mutex;
use esp_hal::{interrupt::Priority, sync::RawPriorityLimitedMutex}; use esp_hal::{interrupt::Priority, sync::RawPriorityLimitedMutex};
use queue_impl::RawQueue; use queue_impl::RawQueue;
use crate::time_driver::{set_up_alarm, AlarmHandle}; use crate::time_driver::{AlarmHandle, set_up_alarm};
struct TimerQueueInner { struct TimerQueueInner {
queue: RawQueue, queue: RawQueue,

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Using the `#handler` macro with a priority of `None` will fail at compile time (#3304) - Using the `#handler` macro with a priority of `None` will fail at compile time (#3304)
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Fixed ### Fixed

View File

@ -1,8 +1,8 @@
[package] [package]
name = "esp-hal-procmacros" name = "esp-hal-procmacros"
version = "0.17.0" version = "0.17.0"
edition = "2021" edition = "2024"
rust-version = "1.84.0" rust-version = "1.85.0"
description = "Procedural macros for esp-hal" description = "Procedural macros for esp-hal"
documentation = "https://docs.espressif.com/projects/rust/esp-hal-procmacros/latest/" documentation = "https://docs.espressif.com/projects/rust/esp-hal-procmacros/latest/"
repository = "https://github.com/esp-rs/esp-hal" repository = "https://github.com/esp-rs/esp-hal"

View File

@ -3,9 +3,9 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::Span; use proc_macro2::Span;
use syn::{ use syn::{
ItemFn,
parse::{self}, parse::{self},
parse_macro_input, parse_macro_input,
ItemFn,
}; };
pub fn main(args: TokenStream, input: TokenStream) -> TokenStream { pub fn main(args: TokenStream, input: TokenStream) -> TokenStream {

View File

@ -1,9 +1,6 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use syn::{ use syn::{
parse::Error as ParseError,
punctuated::Punctuated,
spanned::Spanned,
Attribute, Attribute,
Data, Data,
DataStruct, DataStruct,
@ -14,6 +11,9 @@ use syn::{
PathSegment, PathSegment,
Token, Token,
Type, Type,
parse::Error as ParseError,
punctuated::Punctuated,
spanned::Spanned,
}; };
const KNOWN_HELPERS: &[&str] = &[ const KNOWN_HELPERS: &[&str] = &[

View File

@ -2,9 +2,9 @@ use darling::ast::NestedMeta;
use main_mod::*; use main_mod::*;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use syn::{ use syn::{
Token,
parse::{Parse, ParseBuffer}, parse::{Parse, ParseBuffer},
punctuated::Punctuated, punctuated::Punctuated,
Token,
}; };
pub struct Args { pub struct Args {
@ -30,9 +30,9 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
pub mod main_mod { pub mod main_mod {
use std::{cell::RefCell, fmt::Display, thread}; use std::{cell::RefCell, fmt::Display, thread};
use darling::{export::NestedMeta, FromMeta}; use darling::{FromMeta, export::NestedMeta};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{quote, ToTokens}; use quote::{ToTokens, quote};
use syn::{ReturnType, Type}; use syn::{ReturnType, Type};
#[derive(Debug, FromMeta)] #[derive(Debug, FromMeta)]

View File

@ -1,15 +1,15 @@
use darling::{ast::NestedMeta, FromMeta}; use darling::{FromMeta, ast::NestedMeta};
use proc_macro::{Span, TokenStream}; use proc_macro::{Span, TokenStream};
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::Ident; use proc_macro2::Ident;
use proc_macro_crate::{crate_name, FoundCrate};
use syn::{ use syn::{
parse::Error as SynError,
spanned::Spanned,
AttrStyle, AttrStyle,
Attribute, Attribute,
ItemFn, ItemFn,
ReturnType, ReturnType,
Type, Type,
parse::Error as SynError,
spanned::Spanned,
}; };
pub enum WhiteListCaller { pub enum WhiteListCaller {
@ -40,18 +40,20 @@ pub fn handler(args: TokenStream, input: TokenStream) -> TokenStream {
}; };
let root = Ident::new( let root = Ident::new(
if let Ok(FoundCrate::Name(ref name)) = crate_name("esp-hal") { match crate_name("esp-hal") {
name Ok(FoundCrate::Name(ref name)) => name,
} else { _ => "crate",
"crate"
}, },
Span::call_site().into(), Span::call_site().into(),
); );
let priority = if let Some(priority) = args.priority { let priority = match args.priority {
quote::quote!( #priority ) Some(priority) => {
} else { quote::quote!( #priority )
quote::quote! { #root::interrupt::Priority::min() } }
_ => {
quote::quote! { #root::interrupt::Priority::min() }
}
}; };
// XXX should we blacklist other attributes? // XXX should we blacklist other attributes?

View File

@ -4,19 +4,19 @@ use quote::quote;
#[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))] #[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))]
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::{Ident, Span}; use proc_macro2::{Ident, Span};
use proc_macro_crate::{crate_name, FoundCrate};
use quote::format_ident; use quote::format_ident;
use syn::{ use syn::{
parse::Error,
parse_macro_input,
spanned::Spanned,
FnArg, FnArg,
GenericArgument, GenericArgument,
ItemFn, ItemFn,
PatType, PatType,
PathArguments, PathArguments,
Type, Type,
parse::Error,
parse_macro_input,
spanned::Spanned,
}; };
pub(crate) fn make_magic_symbol_name(args: &Vec<&PatType>) -> String { pub(crate) fn make_magic_symbol_name(args: &Vec<&PatType>) -> String {
@ -181,9 +181,9 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
quote!( quote!(
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[export_name = "main"] #[unsafe(export_name = "main")]
pub fn __risc_v_rt__main() -> ! { pub fn __risc_v_rt__main() -> ! {
#[export_name = #magic_symbol_name] #[unsafe(export_name = #magic_symbol_name)]
static ULP_MAGIC: [u32; 0] = [0u32; 0]; static ULP_MAGIC: [u32; 0] = [0u32; 0];
unsafe { ULP_MAGIC.as_ptr().read_volatile(); } unsafe { ULP_MAGIC.as_ptr().read_volatile(); }
@ -209,8 +209,8 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
use object::{File, Object, ObjectSection, ObjectSymbol, Section, SectionKind}; use object::{File, Object, ObjectSection, ObjectSymbol, Section, SectionKind};
use parse::Error; use parse::Error;
use proc_macro::Span; use proc_macro::Span;
use proc_macro_crate::{crate_name, FoundCrate}; use proc_macro_crate::{FoundCrate, crate_name};
use syn::{parse, Ident}; use syn::{Ident, parse};
let hal_crate = if cfg!(any(feature = "is-lp-core", feature = "is-ulp-core")) { let hal_crate = if cfg!(any(feature = "is-lp-core", feature = "is-ulp-core")) {
crate_name("esp-lp-hal") crate_name("esp-lp-hal")
@ -349,7 +349,7 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
static LP_CODE: &[u8] = &[#(#binary),*]; static LP_CODE: &[u8] = &[#(#binary),*];
extern "C" { unsafe extern "C" {
static #rtc_code_start: u32; static #rtc_code_start: u32;
} }

View File

@ -1,8 +1,8 @@
use darling::{ast::NestedMeta, Error, FromMeta}; use darling::{Error, FromMeta, ast::NestedMeta};
use proc_macro::{Span, TokenStream}; use proc_macro::{Span, TokenStream};
use proc_macro2::Ident;
use proc_macro_error2::abort; use proc_macro_error2::abort;
use syn::{parse, Item}; use proc_macro2::Ident;
use syn::{Item, parse};
#[derive(Debug, Default, darling::FromMeta)] #[derive(Debug, Default, darling::FromMeta)]
#[darling(default)] #[darling(default)]
@ -64,11 +64,11 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
let section = match (is_fn, section_name) { let section = match (is_fn, section_name) {
(true, Ok(section_name)) => quote::quote! { (true, Ok(section_name)) => quote::quote! {
#[link_section = #section_name] #[unsafe(link_section = #section_name)]
#[inline(never)] // make certain function is not inlined #[inline(never)] // make certain function is not inlined
}, },
(false, Ok(section_name)) => quote::quote! { (false, Ok(section_name)) => quote::quote! {
#[link_section = #section_name] #[unsafe(link_section = #section_name)]
}, },
(_, Err(_)) => { (_, Err(_)) => {
abort!(Span::call_site(), "Invalid combination of ram arguments"); abort!(Span::call_site(), "Invalid combination of ram arguments");
@ -83,13 +83,12 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
None None
}; };
let trait_check = trait_check.map(|name| { let trait_check = trait_check.map(|name| {
use proc_macro_crate::{crate_name, FoundCrate}; use proc_macro_crate::{FoundCrate, crate_name};
let hal = Ident::new( let hal = Ident::new(
if let Ok(FoundCrate::Name(ref name)) = crate_name("esp-hal") { match crate_name("esp-hal") {
name Ok(FoundCrate::Name(ref name)) => name,
} else { _ => "crate",
"crate"
}, },
Span::call_site().into(), Span::call_site().into(),
); );

View File

@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- ESP32-S2: Support for light-/deep-sleep (#3341) - ESP32-S2: Support for light-/deep-sleep (#3341)
- Add DMA memcpy support to the S2 (#3352) - Add DMA memcpy support to the S2 (#3352)
- Some config options can now only be set when the `unstable` feature in enabled (#3365) - Some config options can now only be set when the `unstable` feature in enabled (#3365)
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Changed ### Changed

View File

@ -1,8 +1,8 @@
[package] [package]
name = "esp-hal" name = "esp-hal"
version = "1.0.0-beta.0" version = "1.0.0-beta.0"
edition = "2021" edition = "2024"
rust-version = "1.84.0" rust-version = "1.85.0"
description = "Bare-metal HAL for Espressif devices" description = "Bare-metal HAL for Espressif devices"
documentation = "https://docs.espressif.com/projects/rust/esp-hal/latest/" documentation = "https://docs.espressif.com/projects/rust/esp-hal/latest/"
keywords = ["embedded", "embedded-hal", "esp32", "espressif", "hal"] keywords = ["embedded", "embedded-hal", "esp32", "espressif", "hal"]
@ -16,6 +16,10 @@ default-target = "riscv32imac-unknown-none-elf"
features = ["esp32c6"] features = ["esp32c6"]
rustdoc-args = ["--cfg", "docsrs"] rustdoc-args = ["--cfg", "docsrs"]
[lib]
bench = false
test = false
[dependencies] [dependencies]
bitflags = "2.8.0" bitflags = "2.8.0"
bytemuck = "1.21.0" bytemuck = "1.21.0"

View File

@ -9,7 +9,7 @@ use std::{
}; };
use esp_build::assert_unique_used_features; use esp_build::assert_unique_used_features;
use esp_config::{generate_config, ConfigOption, Stability, Validator, Value}; use esp_config::{ConfigOption, Stability, Validator, Value, generate_config};
use esp_metadata::{Chip, Config}; use esp_metadata::{Chip, Config};
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
@ -139,8 +139,7 @@ fn main() -> Result<(), Box<dyn Error>> {
}, },
ConfigOption { ConfigOption {
name: "flip-link", name: "flip-link",
description: description: "Move the stack to start of RAM to get zero-cost stack overflow protection.",
"Move the stack to start of RAM to get zero-cost stack overflow protection.",
default_value: Value::Bool(false), default_value: Value::Bool(false),
constraint: None, constraint: None,
stability: Stability::Unstable, stability: Stability::Unstable,

View File

@ -1,4 +1,4 @@
use crate::aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, Mode, ALIGN_SIZE}; use crate::aes::{ALIGN_SIZE, Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, Mode};
impl Aes<'_> { impl Aes<'_> {
pub(super) fn init(&mut self) { pub(super) fn init(&mut self) {

View File

@ -1,4 +1,4 @@
use crate::aes::{Aes, Aes128, Aes256, AesFlavour, Mode, ALIGN_SIZE}; use crate::aes::{ALIGN_SIZE, Aes, Aes128, Aes256, AesFlavour, Mode};
impl Aes<'_> { impl Aes<'_> {
pub(super) fn init(&mut self) { pub(super) fn init(&mut self) {

View File

@ -1,4 +1,4 @@
use crate::aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, Mode, ALIGN_SIZE}; use crate::aes::{ALIGN_SIZE, Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, Mode};
impl Aes<'_> { impl Aes<'_> {
pub(super) fn init(&mut self) { pub(super) fn init(&mut self) {

View File

@ -1,4 +1,4 @@
use crate::aes::{Aes, Aes128, Aes256, AesFlavour, Mode, ALIGN_SIZE}; use crate::aes::{ALIGN_SIZE, Aes, Aes128, Aes256, AesFlavour, Mode};
impl Aes<'_> { impl Aes<'_> {
pub(super) fn init(&mut self) { pub(super) fn init(&mut self) {

View File

@ -108,10 +108,10 @@ impl Key {
/// Returns a slice representation of the AES key. /// Returns a slice representation of the AES key.
fn as_slice(&self) -> &[u8] { fn as_slice(&self) -> &[u8] {
match self { match self {
Key::Key16(ref key) => key, Key::Key16(key) => key,
#[cfg(any(esp32, esp32s2))] #[cfg(any(esp32, esp32s2))]
Key::Key24(ref key) => key, Key::Key24(key) => key,
Key::Key32(ref key) => key, Key::Key32(key) => key,
} }
} }
} }
@ -235,6 +235,7 @@ pub mod dma {
use core::mem::ManuallyDrop; use core::mem::ManuallyDrop;
use crate::{ use crate::{
Blocking,
aes::{Key, Mode}, aes::{Key, Mode},
dma::{ dma::{
Channel, Channel,
@ -245,7 +246,6 @@ pub mod dma {
PeripheralDmaChannel, PeripheralDmaChannel,
}, },
peripherals::AES, peripherals::AES,
Blocking,
}; };
const ALIGN_SIZE: usize = core::mem::size_of::<u32>(); const ALIGN_SIZE: usize = core::mem::size_of::<u32>();

View File

@ -14,13 +14,13 @@ use super::{AdcCalSource, AdcConfig, Attenuation};
#[cfg(any(esp32c2, esp32c3, esp32c6))] #[cfg(any(esp32c2, esp32c3, esp32c6))]
use crate::efuse::Efuse; use crate::efuse::Efuse;
use crate::{ use crate::{
analog::adc::asynch::AdcFuture,
interrupt::{InterruptConfigurable, InterruptHandler},
peripherals::{Interrupt, APB_SARADC},
soc::regi2c,
system::{GenericPeripheralGuard, Peripheral},
Async, Async,
Blocking, Blocking,
analog::adc::asynch::AdcFuture,
interrupt::{InterruptConfigurable, InterruptHandler},
peripherals::{APB_SARADC, Interrupt},
soc::regi2c,
system::{GenericPeripheralGuard, Peripheral},
}; };
mod calibration; mod calibration;
@ -573,7 +573,7 @@ pub(crate) mod asynch {
use portable_atomic::{AtomicU32, Ordering}; use portable_atomic::{AtomicU32, Ordering};
use procmacros::handler; use procmacros::handler;
use crate::{asynch::AtomicWaker, peripherals::APB_SARADC, Async}; use crate::{Async, asynch::AtomicWaker, peripherals::APB_SARADC};
#[cfg(all(adc1, adc2))] #[cfg(all(adc1, adc2))]
static ASYNC_ADC_COUNT: AtomicU32 = AtomicU32::new(0); static ASYNC_ADC_COUNT: AtomicU32 = AtomicU32::new(0);

View File

@ -26,7 +26,7 @@
use crate::{ use crate::{
interrupt::InterruptHandler, interrupt::InterruptHandler,
pac, pac,
peripherals::{Interrupt, ASSIST_DEBUG}, peripherals::{ASSIST_DEBUG, Interrupt},
}; };
/// The debug assist driver instance. /// The debug assist driver instance.

View File

@ -221,11 +221,7 @@ fn regi2c_enable_block(block: u8) -> usize {
} }
}); });
if i2c_sel { if i2c_sel { 0 } else { 1 }
0
} else {
1
}
} }
pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) { pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) {

View File

@ -229,11 +229,7 @@ impl InternalBurstConfig {
} }
const fn max(a: usize, b: usize) -> usize { const fn max(a: usize, b: usize) -> usize {
if a > b { if a > b { a } else { b }
a
} else {
b
}
} }
impl BurstConfig { impl BurstConfig {

View File

@ -22,7 +22,7 @@ use crate::{
dma::*, dma::*,
handler, handler,
interrupt::Priority, interrupt::Priority,
peripherals::{pac, Interrupt, DMA}, peripherals::{DMA, Interrupt, pac},
}; };
/// An arbitrary GDMA channel /// An arbitrary GDMA channel

View File

@ -12,6 +12,9 @@ use crate::dma::{
DmaEligible, DmaEligible,
}; };
use crate::{ use crate::{
Async,
Blocking,
DriverMode,
dma::{ dma::{
BurstConfig, BurstConfig,
Channel, Channel,
@ -27,9 +30,6 @@ use crate::{
DmaTxBuffer, DmaTxBuffer,
DmaTxInterrupt, DmaTxInterrupt,
}, },
Async,
Blocking,
DriverMode,
}; };
#[cfg(esp32s2)] #[cfg(esp32s2)]
use crate::{ use crate::{

View File

@ -61,14 +61,14 @@ pub use self::m2m::*;
#[cfg(pdma)] #[cfg(pdma)]
pub use self::pdma::*; pub use self::pdma::*;
use crate::{ use crate::{
Async,
Blocking,
DriverMode,
interrupt::InterruptHandler, interrupt::InterruptHandler,
peripherals::Interrupt, peripherals::Interrupt,
soc::{is_slice_in_dram, is_valid_memory_address, is_valid_ram_address}, soc::{is_slice_in_dram, is_valid_memory_address, is_valid_ram_address},
system, system,
system::Cpu, system::Cpu,
Async,
Blocking,
DriverMode,
}; };
trait Word: crate::private::Sealed {} trait Word: crate::private::Sealed {}
@ -579,9 +579,7 @@ pub use as_mut_byte_array; // TODO: can be removed as soon as DMA is stabilized
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! dma_buffers_chunk_size { macro_rules! dma_buffers_chunk_size {
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ ($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ $crate::dma_buffers_impl!($rx_size, $tx_size, $chunk_size, is_circular = false) }};
$crate::dma_buffers_impl!($rx_size, $tx_size, $chunk_size, is_circular = false)
}};
($size:expr, $chunk_size:expr) => { ($size:expr, $chunk_size:expr) => {
$crate::dma_buffers_chunk_size!($size, $size, $chunk_size) $crate::dma_buffers_chunk_size!($size, $size, $chunk_size)
@ -605,13 +603,9 @@ macro_rules! dma_buffers_chunk_size {
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! dma_circular_buffers_chunk_size { macro_rules! dma_circular_buffers_chunk_size {
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ ($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ $crate::dma_buffers_impl!($rx_size, $tx_size, $chunk_size, is_circular = true) }};
$crate::dma_buffers_impl!($rx_size, $tx_size, $chunk_size, is_circular = true)
}};
($size:expr, $chunk_size:expr) => {{ ($size:expr, $chunk_size:expr) => {{ $crate::dma_circular_buffers_chunk_size!($size, $size, $chunk_size) }};
$crate::dma_circular_buffers_chunk_size!($size, $size, $chunk_size)
}};
} }
/// Convenience macro to create DMA descriptors with specific chunk size /// Convenience macro to create DMA descriptors with specific chunk size
@ -630,9 +624,7 @@ macro_rules! dma_circular_buffers_chunk_size {
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! dma_descriptors_chunk_size { macro_rules! dma_descriptors_chunk_size {
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ ($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ $crate::dma_descriptors_impl!($rx_size, $tx_size, $chunk_size, is_circular = false) }};
$crate::dma_descriptors_impl!($rx_size, $tx_size, $chunk_size, is_circular = false)
}};
($size:expr, $chunk_size:expr) => { ($size:expr, $chunk_size:expr) => {
$crate::dma_descriptors_chunk_size!($size, $size, $chunk_size) $crate::dma_descriptors_chunk_size!($size, $size, $chunk_size)
@ -656,9 +648,7 @@ macro_rules! dma_descriptors_chunk_size {
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! dma_circular_descriptors_chunk_size { macro_rules! dma_circular_descriptors_chunk_size {
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ ($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ $crate::dma_descriptors_impl!($rx_size, $tx_size, $chunk_size, is_circular = true) }};
$crate::dma_descriptors_impl!($rx_size, $tx_size, $chunk_size, is_circular = true)
}};
($size:expr, $chunk_size:expr) => { ($size:expr, $chunk_size:expr) => {
$crate::dma_circular_descriptors_chunk_size!($size, $size, $chunk_size) $crate::dma_circular_descriptors_chunk_size!($size, $size, $chunk_size)
@ -1137,7 +1127,7 @@ impl<'a> DescriptorSet<'a> {
} }
/// Returns an iterator over the linked descriptors. /// Returns an iterator over the linked descriptors.
fn linked_iter_mut(&mut self) -> impl Iterator<Item = &mut DmaDescriptor> { fn linked_iter_mut(&mut self) -> impl Iterator<Item = &mut DmaDescriptor> + use<'_> {
let mut was_last = false; let mut was_last = false;
self.descriptors.iter_mut().take_while(move |d| { self.descriptors.iter_mut().take_while(move |d| {
if was_last { if was_last {
@ -1916,7 +1906,7 @@ where
for des in chain.descriptors.iter() { for des in chain.descriptors.iter() {
// we are forcing the DMA alignment to the cache line size // we are forcing the DMA alignment to the cache line size
// required when we are using dcache // required when we are using dcache
let alignment = crate::soc::cache_get_dcache_line_size() as usize; let alignment = unsafe { crate::soc::cache_get_dcache_line_size() } as usize;
if crate::soc::addr_in_range(des.buffer as usize, psram_range.clone()) { if crate::soc::addr_in_range(des.buffer as usize, psram_range.clone()) {
uses_psram = true; uses_psram = true;
// both the size and address of the buffer must be aligned // both the size and address of the buffer must be aligned
@ -1926,7 +1916,7 @@ where
if des.size() % alignment != 0 { if des.size() % alignment != 0 {
return Err(DmaError::InvalidAlignment(DmaAlignmentError::Size)); return Err(DmaError::InvalidAlignment(DmaAlignmentError::Size));
} }
crate::soc::cache_invalidate_addr(des.buffer as u32, des.size() as u32); unsafe {crate::soc::cache_invalidate_addr(des.buffer as u32, des.size() as u32); }
} }
} }
} }
@ -2182,7 +2172,7 @@ where
for des in chain.descriptors.iter() { for des in chain.descriptors.iter() {
// we are forcing the DMA alignment to the cache line size // we are forcing the DMA alignment to the cache line size
// required when we are using dcache // required when we are using dcache
let alignment = crate::soc::cache_get_dcache_line_size() as usize; let alignment = unsafe { crate::soc::cache_get_dcache_line_size()} as usize;
if crate::soc::addr_in_range(des.buffer as usize, psram_range.clone()) { if crate::soc::addr_in_range(des.buffer as usize, psram_range.clone()) {
uses_psram = true; uses_psram = true;
// both the size and address of the buffer must be aligned // both the size and address of the buffer must be aligned
@ -2192,7 +2182,7 @@ where
if des.size() % alignment != 0 { if des.size() % alignment != 0 {
return Err(DmaError::InvalidAlignment(DmaAlignmentError::Size)); return Err(DmaError::InvalidAlignment(DmaAlignmentError::Size));
} }
crate::soc::cache_writeback_addr(des.buffer as u32, des.size() as u32); unsafe { crate::soc::cache_writeback_addr(des.buffer as u32, des.size() as u32); }
} }
} }
} }
@ -2206,7 +2196,7 @@ where
burst_transfer: BurstConfig::default(), burst_transfer: BurstConfig::default(),
check_owner: Some(false), check_owner: Some(false),
// enable descriptor write back in circular mode // enable descriptor write back in circular mode
auto_write_back: !(*chain.last()).next.is_null(), auto_write_back: !(unsafe { *chain.last() }).next.is_null(),
}; };
self.do_prepare(preparation, peri)?; self.do_prepare(preparation, peri)?;

View File

@ -4,7 +4,7 @@ use crate::{
asynch::AtomicWaker, asynch::AtomicWaker,
dma::*, dma::*,
interrupt::{InterruptHandler, Priority}, interrupt::{InterruptHandler, Priority},
peripherals::{Interrupt, DMA_COPY}, peripherals::{DMA_COPY, Interrupt},
}; };
pub(super) type CopyRegisterBlock = crate::pac::copy_dma::RegisterBlock; pub(super) type CopyRegisterBlock = crate::pac::copy_dma::RegisterBlock;

View File

@ -4,7 +4,7 @@ use crate::{
asynch::AtomicWaker, asynch::AtomicWaker,
dma::*, dma::*,
interrupt::Priority, interrupt::Priority,
peripherals::{Interrupt, DMA_CRYPTO}, peripherals::{DMA_CRYPTO, Interrupt},
}; };
pub(super) type CryptoRegisterBlock = crate::pac::crypto_dma::RegisterBlock; pub(super) type CryptoRegisterBlock = crate::pac::crypto_dma::RegisterBlock;

View File

@ -53,12 +53,12 @@ macro_rules! impl_pdma_channel {
type Rx = [<$peri DmaRxChannel>]<'d>; type Rx = [<$peri DmaRxChannel>]<'d>;
type Tx = [<$peri DmaTxChannel>]<'d>; type Tx = [<$peri DmaTxChannel>]<'d>;
unsafe fn split_internal(self, _: $crate::private::Internal) -> (Self::Rx, Self::Tx) { unsafe fn split_internal(self, _: $crate::private::Internal) -> (Self::Rx, Self::Tx) { unsafe {
( (
[<$peri DmaRxChannel>](Self::steal().into()), [<$peri DmaRxChannel>](Self::steal().into()),
[<$peri DmaTxChannel>](Self::steal().into()), [<$peri DmaTxChannel>](Self::steal().into()),
) )
} }}
} }
impl DmaChannelExt for $instance<'_> { impl DmaChannelExt for $instance<'_> {

View File

@ -28,13 +28,13 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use crate::{ use crate::{
interrupt::InterruptHandler,
pac,
peripherals::{Interrupt, ECC},
reg_access::{AlignmentHelper, SocDependentEndianess},
system::{self, GenericPeripheralGuard},
Blocking, Blocking,
DriverMode, DriverMode,
interrupt::InterruptHandler,
pac,
peripherals::{ECC, Interrupt},
reg_access::{AlignmentHelper, SocDependentEndianess},
system::{self, GenericPeripheralGuard},
}; };
/// The ECC Accelerator driver instance /// The ECC Accelerator driver instance

View File

@ -55,9 +55,9 @@ use core::marker::PhantomData;
use crate::{ use crate::{
gpio::{ gpio::{
interconnect::{InputSignal, OutputSignal},
Level, Level,
Pull, Pull,
interconnect::{InputSignal, OutputSignal},
}, },
peripherals::GPIO_SD, peripherals::GPIO_SD,
private, private,

View File

@ -14,20 +14,20 @@ use crate::{
self, self,
AlternateFunction, AlternateFunction,
AnyPin, AnyPin,
FUNC_IN_SEL_OFFSET,
Flex, Flex,
GPIO_FUNCTION,
INPUT_SIGNAL_MAX,
InputPin, InputPin,
InputSignalType, InputSignalType,
Level, Level,
NoPin, NoPin,
OUTPUT_SIGNAL_MAX,
OutputPin, OutputPin,
OutputSignalType, OutputSignalType,
Pin, Pin,
PinGuard, PinGuard,
Pull, Pull,
FUNC_IN_SEL_OFFSET,
GPIO_FUNCTION,
INPUT_SIGNAL_MAX,
OUTPUT_SIGNAL_MAX,
}, },
peripherals::GPIO, peripherals::GPIO,
private::{self, Sealed}, private::{self, Sealed},

View File

@ -201,7 +201,9 @@ macro_rules! lp_gpio {
unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) { unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) {
let lp_io = $crate::peripherals::LP_IO::regs(); let lp_io = $crate::peripherals::LP_IO::regs();
lp_io.pin($gpionum).modify(|_, w| { lp_io.pin($gpionum).modify(|_, w| {
w.wakeup_enable().bit(wakeup).int_type().bits(level) unsafe {
w.wakeup_enable().bit(wakeup).int_type().bits(level)
}
}); });
} }

View File

@ -61,8 +61,8 @@ use strum::EnumCount;
use crate::peripherals::{handle_rtcio, handle_rtcio_with_resistors}; use crate::peripherals::{handle_rtcio, handle_rtcio_with_resistors};
pub use crate::soc::gpio::*; pub use crate::soc::gpio::*;
use crate::{ use crate::{
interrupt::{self, InterruptHandler, Priority, DEFAULT_INTERRUPT_HANDLER}, interrupt::{self, DEFAULT_INTERRUPT_HANDLER, InterruptHandler, Priority},
peripherals::{handle_gpio_input, handle_gpio_output, Interrupt, GPIO, IO_MUX}, peripherals::{GPIO, IO_MUX, Interrupt, handle_gpio_input, handle_gpio_output},
private::{self, Sealed}, private::{self, Sealed},
}; };
@ -1012,6 +1012,7 @@ macro_rules! gpio {
$( $(
$gpionum => $crate::if_rtcio_pin!($($type),* {{ $gpionum => $crate::if_rtcio_pin!($($type),* {{
#[allow(unused_mut)] #[allow(unused_mut)]
#[allow(unused_unsafe)]
let mut $inner = unsafe { $crate::peripherals::[<GPIO $gpionum>]::steal() }; let mut $inner = unsafe { $crate::peripherals::[<GPIO $gpionum>]::steal() };
$code $code
}} else {{ }} else {{
@ -2132,9 +2133,11 @@ impl RtcPin for AnyPin<'_> {
#[cfg(any(esp32c2, esp32c3, esp32c6))] #[cfg(any(esp32c2, esp32c3, esp32c6))]
unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) { unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) {
handle_rtcio!(self, target, { unsafe {
RtcPin::apply_wakeup(&target, wakeup, level) handle_rtcio!(self, target, {
}) RtcPin::apply_wakeup(&target, wakeup, level)
})
}
} }
} }

View File

@ -2,7 +2,7 @@
use crate::{ use crate::{
gpio::lp_io::LowPowerOutputOpenDrain, gpio::lp_io::LowPowerOutputOpenDrain,
peripherals::{LPWR, LP_AON, LP_I2C0, LP_IO, LP_PERI}, peripherals::{LP_AON, LP_I2C0, LP_IO, LP_PERI, LPWR},
time::Rate, time::Rate,
}; };

View File

@ -31,25 +31,25 @@ use embedded_hal::i2c::Operation as EhalOperation;
use enumset::{EnumSet, EnumSetType}; use enumset::{EnumSet, EnumSetType};
use crate::{ use crate::{
Async,
Blocking,
DriverMode,
asynch::AtomicWaker, asynch::AtomicWaker,
clock::Clocks, clock::Clocks,
gpio::{ gpio::{
interconnect::{OutputConnection, PeripheralOutput},
InputSignal, InputSignal,
OutputSignal, OutputSignal,
PinGuard, PinGuard,
Pull, Pull,
interconnect::{OutputConnection, PeripheralOutput},
}, },
i2c::{AnyI2c, AnyI2cInner}, i2c::{AnyI2c, AnyI2cInner},
interrupt::InterruptHandler, interrupt::InterruptHandler,
pac::i2c0::{RegisterBlock, COMD}, pac::i2c0::{COMD, RegisterBlock},
peripherals::Interrupt, peripherals::Interrupt,
private, private,
system::{PeripheralClockControl, PeripheralGuard}, system::{PeripheralClockControl, PeripheralGuard},
time::Rate, time::Rate,
Async,
Blocking,
DriverMode,
}; };
cfg_if::cfg_if! { cfg_if::cfg_if! {

View File

@ -73,8 +73,10 @@ use enumset::{EnumSet, EnumSetType};
use private::*; use private::*;
use crate::{ use crate::{
Async,
Blocking,
DriverMode,
dma::{ dma::{
dma_private::{DmaSupport, DmaSupportRx, DmaSupportTx},
Channel, Channel,
ChannelRx, ChannelRx,
ChannelTx, ChannelTx,
@ -90,15 +92,13 @@ use crate::{
PeripheralTxChannel, PeripheralTxChannel,
ReadBuffer, ReadBuffer,
WriteBuffer, WriteBuffer,
dma_private::{DmaSupport, DmaSupportRx, DmaSupportTx},
}, },
gpio::interconnect::PeripheralOutput, gpio::interconnect::PeripheralOutput,
i2s::AnyI2s, i2s::AnyI2s,
interrupt::{InterruptConfigurable, InterruptHandler}, interrupt::{InterruptConfigurable, InterruptHandler},
system::PeripheralGuard, system::PeripheralGuard,
time::Rate, time::Rate,
Async,
Blocking,
DriverMode,
}; };
#[derive(Debug, EnumSetType)] #[derive(Debug, EnumSetType)]
@ -678,16 +678,16 @@ mod private {
#[cfg(not(i2s1))] #[cfg(not(i2s1))]
use crate::pac::i2s0::RegisterBlock; use crate::pac::i2s0::RegisterBlock;
use crate::{ use crate::{
DriverMode,
dma::{ChannelRx, ChannelTx, DescriptorChain, DmaDescriptor, DmaEligible}, dma::{ChannelRx, ChannelTx, DescriptorChain, DmaDescriptor, DmaEligible},
gpio::{ gpio::{
interconnect::{PeripheralInput, PeripheralOutput},
InputSignal, InputSignal,
OutputSignal, OutputSignal,
interconnect::{PeripheralInput, PeripheralOutput},
}, },
i2s::AnyI2sInner, i2s::AnyI2sInner,
interrupt::InterruptHandler, interrupt::InterruptHandler,
peripherals::{Interrupt, I2S0}, peripherals::{I2S0, Interrupt},
DriverMode,
}; };
// on ESP32-S3 I2S1 doesn't support all features - use that to avoid using those features // on ESP32-S3 I2S1 doesn't support all features - use that to avoid using those features
// by accident // by accident
@ -1784,15 +1784,15 @@ mod private {
pub mod asynch { pub mod asynch {
use super::{Error, I2sRx, I2sTx, RegisterAccessPrivate}; use super::{Error, I2sRx, I2sTx, RegisterAccessPrivate};
use crate::{ use crate::{
Async,
dma::{ dma::{
asynch::{DmaRxDoneChFuture, DmaRxFuture, DmaTxDoneChFuture, DmaTxFuture},
DmaEligible, DmaEligible,
ReadBuffer, ReadBuffer,
RxCircularState, RxCircularState,
TxCircularState, TxCircularState,
WriteBuffer, WriteBuffer,
asynch::{DmaRxDoneChFuture, DmaRxFuture, DmaTxDoneChFuture, DmaTxFuture},
}, },
Async,
}; };
impl<'d> I2sTx<'d, Async> { impl<'d> I2sTx<'d, Async> {

View File

@ -103,8 +103,10 @@ use core::{
}; };
use crate::{ use crate::{
Async,
Blocking,
DriverMode,
dma::{ dma::{
asynch::DmaTxFuture,
Channel, Channel,
ChannelTx, ChannelTx,
DmaChannelFor, DmaChannelFor,
@ -112,19 +114,17 @@ use crate::{
DmaError, DmaError,
DmaTxBuffer, DmaTxBuffer,
PeripheralTxChannel, PeripheralTxChannel,
asynch::DmaTxFuture,
}, },
gpio::{ gpio::{
interconnect::{OutputConnection, PeripheralOutput},
OutputSignal, OutputSignal,
interconnect::{OutputConnection, PeripheralOutput},
}, },
i2s::{AnyI2s, AnyI2sInner}, i2s::{AnyI2s, AnyI2sInner},
pac::i2s0::RegisterBlock, pac::i2s0::RegisterBlock,
peripherals::{I2S0, I2S1}, peripherals::{I2S0, I2S1},
system::PeripheralGuard, system::PeripheralGuard,
time::Rate, time::Rate,
Async,
Blocking,
DriverMode,
}; };
#[doc(hidden)] #[doc(hidden)]

View File

@ -85,7 +85,7 @@ mod xtensa;
pub mod software; pub mod software;
#[no_mangle] #[unsafe(no_mangle)]
extern "C" fn EspDefaultHandler(_interrupt: crate::peripherals::Interrupt) { extern "C" fn EspDefaultHandler(_interrupt: crate::peripherals::Interrupt) {
panic!("Unhandled interrupt: {:?}", _interrupt); panic!("Unhandled interrupt: {:?}", _interrupt);
} }

View File

@ -12,8 +12,8 @@
//! interrupt15() => Priority::Priority15 //! interrupt15() => Priority::Priority15
//! ``` //! ```
pub(crate) use esp_riscv_rt::riscv::interrupt::free;
pub use esp_riscv_rt::TrapFrame; pub use esp_riscv_rt::TrapFrame;
pub(crate) use esp_riscv_rt::riscv::interrupt::free;
use riscv::register::{mcause, mtvec}; use riscv::register::{mcause, mtvec};
#[cfg(not(plic))] #[cfg(not(plic))]
@ -24,7 +24,7 @@ pub use self::vectored::*;
use super::InterruptStatus; use super::InterruptStatus;
use crate::{ use crate::{
pac, pac,
peripherals::{Interrupt, INTERRUPT_CORE0}, peripherals::{INTERRUPT_CORE0, Interrupt},
system::Cpu, system::Cpu,
}; };
@ -204,30 +204,32 @@ impl TryFrom<u8> for Priority {
} }
/// The interrupts reserved by the HAL /// The interrupts reserved by the HAL
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub static RESERVED_INTERRUPTS: &[usize] = PRIORITY_TO_INTERRUPT; pub static RESERVED_INTERRUPTS: &[usize] = PRIORITY_TO_INTERRUPT;
/// # Safety /// # Safety
/// ///
/// This function is called from an assembly trap handler. /// This function is called from an assembly trap handler.
#[doc(hidden)] #[doc(hidden)]
#[link_section = ".trap.rust"] #[unsafe(link_section = ".trap.rust")]
#[export_name = "_start_trap_rust_hal"] #[unsafe(export_name = "_start_trap_rust_hal")]
pub unsafe extern "C" fn start_trap_rust_hal(trap_frame: *mut TrapFrame) { pub unsafe extern "C" fn start_trap_rust_hal(trap_frame: *mut TrapFrame) {
assert!( assert!(
mcause::read().is_exception(), mcause::read().is_exception(),
"Arrived into _start_trap_rust_hal but mcause is not an exception!" "Arrived into _start_trap_rust_hal but mcause is not an exception!"
); );
extern "C" { unsafe extern "C" {
fn ExceptionHandler(tf: *mut TrapFrame); fn ExceptionHandler(tf: *mut TrapFrame);
} }
ExceptionHandler(trap_frame); unsafe {
ExceptionHandler(trap_frame);
}
} }
#[doc(hidden)] #[doc(hidden)]
#[no_mangle] #[unsafe(no_mangle)]
pub fn _setup_interrupts() { pub fn _setup_interrupts() {
extern "C" { unsafe extern "C" {
static _vector_table: *const u32; static _vector_table: *const u32;
} }
@ -338,9 +340,11 @@ pub unsafe fn map(_core: Cpu, interrupt: Interrupt, which: CpuInterrupt) {
Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU as *mut u32, Cpu::AppCpu => crate::soc::registers::INTERRUPT_MAP_BASE_APP_CPU as *mut u32,
}; };
intr_map_base unsafe {
.offset(interrupt_number) intr_map_base
.write_volatile(cpu_interrupt_number as u32 + EXTERNAL_INTERRUPT_OFFSET); .offset(interrupt_number)
.write_volatile(cpu_interrupt_number as u32 + EXTERNAL_INTERRUPT_OFFSET);
}
} }
/// Get cpu interrupt assigned to peripheral interrupt /// Get cpu interrupt assigned to peripheral interrupt
@ -349,11 +353,11 @@ unsafe fn assigned_cpu_interrupt(interrupt: Interrupt) -> Option<CpuInterrupt> {
let interrupt_number = interrupt as isize; let interrupt_number = interrupt as isize;
let intr_map_base = crate::soc::registers::INTERRUPT_MAP_BASE as *mut u32; let intr_map_base = crate::soc::registers::INTERRUPT_MAP_BASE as *mut u32;
let cpu_intr = intr_map_base.offset(interrupt_number).read_volatile(); let cpu_intr = unsafe { intr_map_base.offset(interrupt_number).read_volatile() };
if cpu_intr > 0 && cpu_intr != DISABLED_CPU_INTERRUPT { if cpu_intr > 0 && cpu_intr != DISABLED_CPU_INTERRUPT {
Some(core::mem::transmute::<u32, CpuInterrupt>( Some(unsafe {
cpu_intr - EXTERNAL_INTERRUPT_OFFSET, core::mem::transmute::<u32, CpuInterrupt>(cpu_intr - EXTERNAL_INTERRUPT_OFFSET)
)) })
} else { } else {
None None
} }
@ -372,17 +376,19 @@ mod vectored {
#[doc(hidden)] #[doc(hidden)]
pub(crate) unsafe fn init_vectoring() { pub(crate) unsafe fn init_vectoring() {
for (prio, num) in PRIORITY_TO_INTERRUPT.iter().enumerate() { for (prio, num) in PRIORITY_TO_INTERRUPT.iter().enumerate() {
set_kind( unsafe {
Cpu::current(), set_kind(
core::mem::transmute::<u32, CpuInterrupt>(*num as u32), Cpu::current(),
InterruptKind::Level, core::mem::transmute::<u32, CpuInterrupt>(*num as u32),
); InterruptKind::Level,
set_priority( );
Cpu::current(), set_priority(
core::mem::transmute::<u32, CpuInterrupt>(*num as u32), Cpu::current(),
core::mem::transmute::<u8, Priority>((prio as u8) + 1), core::mem::transmute::<u32, CpuInterrupt>(*num as u32),
); core::mem::transmute::<u8, Priority>((prio as u8) + 1),
enable_cpu_interrupt(core::mem::transmute::<u32, CpuInterrupt>(*num as u32)); );
enable_cpu_interrupt(core::mem::transmute::<u32, CpuInterrupt>(*num as u32));
}
} }
} }
@ -437,9 +443,11 @@ mod vectored {
/// ///
/// This will replace any previously bound interrupt handler /// This will replace any previously bound interrupt handler
pub unsafe fn bind_interrupt(interrupt: Interrupt, handler: unsafe extern "C" fn()) { pub unsafe fn bind_interrupt(interrupt: Interrupt, handler: unsafe extern "C" fn()) {
let ptr = &pac::__EXTERNAL_INTERRUPTS[interrupt as usize]._handler as *const _ unsafe {
as *mut unsafe extern "C" fn(); let ptr = &pac::__EXTERNAL_INTERRUPTS[interrupt as usize]._handler as *const _
ptr.write_volatile(handler); as *mut unsafe extern "C" fn();
ptr.write_volatile(handler);
}
} }
/// Returns the currently bound interrupt handler. /// Returns the currently bound interrupt handler.
@ -454,7 +462,7 @@ mod vectored {
} }
} }
#[no_mangle] #[unsafe(no_mangle)]
#[ram] #[ram]
unsafe fn handle_interrupts(cpu_intr: CpuInterrupt, context: &mut TrapFrame) { unsafe fn handle_interrupts(cpu_intr: CpuInterrupt, context: &mut TrapFrame) {
let core = Cpu::current(); let core = Cpu::current();
@ -471,27 +479,30 @@ mod vectored {
for interrupt_nr in configured_interrupts.iterator() { for interrupt_nr in configured_interrupts.iterator() {
// Don't use `Interrupt::try_from`. It's slower and placed in flash // Don't use `Interrupt::try_from`. It's slower and placed in flash
let interrupt: Interrupt = unsafe { core::mem::transmute(interrupt_nr as u16) }; let interrupt: Interrupt = unsafe { core::mem::transmute(interrupt_nr as u16) };
handle_interrupt(interrupt, context); unsafe {
handle_interrupt(interrupt, context);
}
} }
} }
#[inline(always)] #[inline(always)]
unsafe fn handle_interrupt(interrupt: Interrupt, save_frame: &mut TrapFrame) { unsafe fn handle_interrupt(interrupt: Interrupt, save_frame: &mut TrapFrame) {
extern "C" { unsafe extern "C" {
// defined in each hal // defined in each hal
fn EspDefaultHandler(interrupt: Interrupt); fn EspDefaultHandler(interrupt: Interrupt);
} }
let handler = pac::__EXTERNAL_INTERRUPTS[interrupt as usize]._handler; let handler = unsafe { pac::__EXTERNAL_INTERRUPTS[interrupt as usize]._handler };
if core::ptr::eq( if core::ptr::eq(
handler as *const _, handler as *const _,
EspDefaultHandler as *const unsafe extern "C" fn(), EspDefaultHandler as *const unsafe extern "C" fn(),
) { ) {
EspDefaultHandler(interrupt); unsafe { EspDefaultHandler(interrupt) };
} else { } else {
let handler: fn(&mut TrapFrame) = let handler: fn(&mut TrapFrame) = unsafe {
core::mem::transmute::<unsafe extern "C" fn(), fn(&mut TrapFrame)>(handler); core::mem::transmute::<unsafe extern "C" fn(), fn(&mut TrapFrame)>(handler)
};
handler(save_frame); handler(save_frame);
} }
} }
@ -571,18 +582,18 @@ mod classic {
use super::{CpuInterrupt, InterruptKind, Priority}; use super::{CpuInterrupt, InterruptKind, Priority};
use crate::{peripherals::INTERRUPT_CORE0, system::Cpu}; use crate::{peripherals::INTERRUPT_CORE0, system::Cpu};
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static DISABLED_CPU_INTERRUPT: u32 = 0; pub(super) static DISABLED_CPU_INTERRUPT: u32 = 0;
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static EXTERNAL_INTERRUPT_OFFSET: u32 = 0; pub(super) static EXTERNAL_INTERRUPT_OFFSET: u32 = 0;
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static PRIORITY_TO_INTERRUPT: &[usize] = pub(super) static PRIORITY_TO_INTERRUPT: &[usize] =
&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
// First element is not used, just there to avoid a -1 in the interrupt handler. // First element is not used, just there to avoid a -1 in the interrupt handler.
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static INTERRUPT_TO_PRIORITY: [u8; 16] = pub(super) static INTERRUPT_TO_PRIORITY: [u8; 16] =
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
@ -595,7 +606,7 @@ mod classic {
let cpu_interrupt_number = which as isize; let cpu_interrupt_number = which as isize;
let intr = INTERRUPT_CORE0::regs(); let intr = INTERRUPT_CORE0::regs();
intr.cpu_int_enable() intr.cpu_int_enable()
.modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits())); .modify(|r, w| unsafe { w.bits((1 << cpu_interrupt_number) | r.bits()) });
} }
/// Set the interrupt kind (i.e. level or edge) of an CPU interrupt /// Set the interrupt kind (i.e. level or edge) of an CPU interrupt
@ -629,7 +640,7 @@ mod classic {
pub unsafe fn set_priority(_core: Cpu, which: CpuInterrupt, priority: Priority) { pub unsafe fn set_priority(_core: Cpu, which: CpuInterrupt, priority: Priority) {
let intr = INTERRUPT_CORE0::regs(); let intr = INTERRUPT_CORE0::regs();
intr.cpu_int_pri(which as usize) intr.cpu_int_pri(which as usize)
.write(|w| w.map().bits(priority as u8)); .write(|w| unsafe { w.map().bits(priority as u8) });
} }
/// Clear a CPU interrupt /// Clear a CPU interrupt
@ -653,41 +664,43 @@ mod classic {
#[inline] #[inline]
pub(super) unsafe extern "C" fn priority(cpu_interrupt: CpuInterrupt) -> Priority { pub(super) unsafe extern "C" fn priority(cpu_interrupt: CpuInterrupt) -> Priority {
let intr = INTERRUPT_CORE0::regs(); let intr = INTERRUPT_CORE0::regs();
core::mem::transmute::<u8, Priority>( unsafe {
intr.cpu_int_pri(cpu_interrupt as usize).read().map().bits(), core::mem::transmute::<u8, Priority>(
) intr.cpu_int_pri(cpu_interrupt as usize).read().map().bits(),
)
}
} }
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".trap"] #[unsafe(link_section = ".trap")]
pub(super) unsafe extern "C" fn _handle_priority() -> u32 { pub(super) unsafe extern "C" fn _handle_priority() -> u32 {
use super::mcause; use super::mcause;
// Both C6 and H2 have 5 bits of code. The riscv crate masks 31 bits, which then // Both C6 and H2 have 5 bits of code. The riscv crate masks 31 bits, which then
// causes a bounds check to be present. // causes a bounds check to be present.
let interrupt_id: usize = mcause::read().bits() & 0x1f; let interrupt_id: usize = mcause::read().bits() & 0x1f;
let intr = INTERRUPT_CORE0::regs(); let intr = INTERRUPT_CORE0::regs();
let interrupt_priority = intr let interrupt_priority = unsafe {
.cpu_int_pri(0) intr.cpu_int_pri(0)
.as_ptr() .as_ptr()
.add(interrupt_id) .add(interrupt_id)
.read_volatile(); .read_volatile()
};
let prev_interrupt_priority = intr.cpu_int_thresh().read().bits(); let prev_interrupt_priority = intr.cpu_int_thresh().read().bits();
if interrupt_priority < 15 { if interrupt_priority < 15 {
// leave interrupts disabled if interrupt is of max priority. // leave interrupts disabled if interrupt is of max priority.
intr.cpu_int_thresh() intr.cpu_int_thresh()
.write(|w| w.bits(interrupt_priority + 1)); // set the prio threshold to 1 more than current interrupt prio .write(|w| unsafe { w.bits(interrupt_priority + 1) }); // set the prio threshold to 1 more than current interrupt prio
unsafe { unsafe { riscv::interrupt::enable() };
riscv::interrupt::enable();
}
} }
prev_interrupt_priority prev_interrupt_priority
} }
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".trap"] #[unsafe(link_section = ".trap")]
pub(super) unsafe extern "C" fn _restore_priority(stored_prio: u32) { pub(super) unsafe extern "C" fn _restore_priority(stored_prio: u32) {
riscv::interrupt::disable(); riscv::interrupt::disable();
let intr = INTERRUPT_CORE0::regs(); let intr = INTERRUPT_CORE0::regs();
intr.cpu_int_thresh().write(|w| w.bits(stored_prio)); intr.cpu_int_thresh()
.write(|w| unsafe { w.bits(stored_prio) });
} }
/// Get the current run level (the level below which interrupts are masked). /// Get the current run level (the level below which interrupts are masked).
@ -713,7 +726,7 @@ mod classic {
// interrupts at `level` so we set the threshold to `level + 1`. // interrupts at `level` so we set the threshold to `level + 1`.
INTERRUPT_CORE0::regs() INTERRUPT_CORE0::regs()
.cpu_int_thresh() .cpu_int_thresh()
.write(|w| w.bits(level as u32 + 1)); .write(|w| unsafe { w.bits(level as u32 + 1) });
prev_interrupt_priority prev_interrupt_priority
} }
@ -724,21 +737,21 @@ mod plic {
use super::{CpuInterrupt, InterruptKind, Priority}; use super::{CpuInterrupt, InterruptKind, Priority};
use crate::{peripherals::PLIC_MX, system::Cpu}; use crate::{peripherals::PLIC_MX, system::Cpu};
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static DISABLED_CPU_INTERRUPT: u32 = 31; pub(super) static DISABLED_CPU_INTERRUPT: u32 = 31;
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static EXTERNAL_INTERRUPT_OFFSET: u32 = 0; pub(super) static EXTERNAL_INTERRUPT_OFFSET: u32 = 0;
// don't use interrupts reserved for CLIC (0,3,4,7) // don't use interrupts reserved for CLIC (0,3,4,7)
// for some reason also CPU interrupt 8 doesn't work by default since it's // for some reason also CPU interrupt 8 doesn't work by default since it's
// disabled after reset - so don't use that, too // disabled after reset - so don't use that, too
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static PRIORITY_TO_INTERRUPT: &[usize] = pub(super) static PRIORITY_TO_INTERRUPT: &[usize] =
&[1, 2, 5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]; &[1, 2, 5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
// First element is not used, just there to avoid a -1 in the interrupt handler. // First element is not used, just there to avoid a -1 in the interrupt handler.
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub(super) static INTERRUPT_TO_PRIORITY: [u8; 20] = [ pub(super) static INTERRUPT_TO_PRIORITY: [u8; 20] = [
0, 1, 2, 0, 0, 3, 4, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 0, 0, 3, 4, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
]; ];
@ -820,10 +833,10 @@ mod plic {
.read() .read()
.cpu_mxint_pri() .cpu_mxint_pri()
.bits(); .bits();
core::mem::transmute::<u8, Priority>(prio) unsafe { core::mem::transmute::<u8, Priority>(prio) }
} }
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".trap"] #[unsafe(link_section = ".trap")]
pub(super) unsafe extern "C" fn _handle_priority() -> u32 { pub(super) unsafe extern "C" fn _handle_priority() -> u32 {
let interrupt_id: usize = super::mcause::read().code(); // MSB is whether its exception or interrupt. let interrupt_id: usize = super::mcause::read().code(); // MSB is whether its exception or interrupt.
let interrupt_priority = PLIC_MX::regs() let interrupt_priority = PLIC_MX::regs()
@ -841,20 +854,21 @@ mod plic {
// leave interrupts disabled if interrupt is of max priority. // leave interrupts disabled if interrupt is of max priority.
PLIC_MX::regs() PLIC_MX::regs()
.mxint_thresh() .mxint_thresh()
.write(|w| w.cpu_mxint_thresh().bits(interrupt_priority + 1)); .write(|w| unsafe { w.cpu_mxint_thresh().bits(interrupt_priority + 1) });
unsafe { unsafe {
riscv::interrupt::enable(); riscv::interrupt::enable();
} }
} }
prev_interrupt_priority as u32 prev_interrupt_priority as u32
} }
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".trap"] #[unsafe(link_section = ".trap")]
pub(super) unsafe extern "C" fn _restore_priority(stored_prio: u32) { pub(super) unsafe extern "C" fn _restore_priority(stored_prio: u32) {
riscv::interrupt::disable(); riscv::interrupt::disable();
PLIC_MX::regs() PLIC_MX::regs()
.mxint_thresh() .mxint_thresh()
.write(|w| w.cpu_mxint_thresh().bits(stored_prio as u8)); .write(|w| unsafe { w.cpu_mxint_thresh().bits(stored_prio as u8) });
} }
/// Get the current run level (the level below which interrupts are masked). /// Get the current run level (the level below which interrupts are masked).
@ -884,7 +898,7 @@ mod plic {
// interrupts at `level` so we set the threshold to `level + 1`. // interrupts at `level` so we set the threshold to `level + 1`.
PLIC_MX::regs() PLIC_MX::regs()
.mxint_thresh() .mxint_thresh()
.write(|w| w.cpu_mxint_thresh().bits(level as u8 + 1)); .write(|w| unsafe { w.cpu_mxint_thresh().bits(level as u8 + 1) });
prev_interrupt_priority prev_interrupt_priority
} }

View File

@ -119,7 +119,7 @@ impl CpuInterrupt {
} }
/// The interrupts reserved by the HAL /// The interrupts reserved by the HAL
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub static RESERVED_INTERRUPTS: &[usize] = &[ pub static RESERVED_INTERRUPTS: &[usize] = &[
CpuInterrupt::Interrupt1LevelPriority1 as _, CpuInterrupt::Interrupt1LevelPriority1 as _,
CpuInterrupt::Interrupt19LevelPriority2 as _, CpuInterrupt::Interrupt19LevelPriority2 as _,
@ -174,14 +174,16 @@ pub fn enable_direct(interrupt: Interrupt, cpu_interrupt: CpuInterrupt) -> Resul
pub unsafe fn map(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) { pub unsafe fn map(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) {
let interrupt_number = interrupt as isize; let interrupt_number = interrupt as isize;
let cpu_interrupt_number = which as isize; let cpu_interrupt_number = which as isize;
let intr_map_base = match core { unsafe {
Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map().as_ptr(), let intr_map_base = match core {
#[cfg(multi_core)] Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map().as_ptr(),
Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map().as_ptr(), #[cfg(multi_core)]
}; Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map().as_ptr(),
intr_map_base };
.offset(interrupt_number) intr_map_base
.write_volatile(cpu_interrupt_number as u32); .offset(interrupt_number)
.write_volatile(cpu_interrupt_number as u32);
}
} }
/// Get cpu interrupt assigned to peripheral interrupt /// Get cpu interrupt assigned to peripheral interrupt
@ -350,12 +352,14 @@ pub(crate) fn current_runlevel() -> Priority {
/// runlevel. /// runlevel.
pub(crate) unsafe fn change_current_runlevel(level: Priority) -> Priority { pub(crate) unsafe fn change_current_runlevel(level: Priority) -> Priority {
let token: u32; let token: u32;
match level { unsafe {
Priority::None => core::arch::asm!("rsil {0}, 0", out(reg) token), match level {
Priority::Priority1 => core::arch::asm!("rsil {0}, 1", out(reg) token), Priority::None => core::arch::asm!("rsil {0}, 0", out(reg) token),
Priority::Priority2 => core::arch::asm!("rsil {0}, 2", out(reg) token), Priority::Priority1 => core::arch::asm!("rsil {0}, 1", out(reg) token),
Priority::Priority3 => core::arch::asm!("rsil {0}, 3", out(reg) token), Priority::Priority2 => core::arch::asm!("rsil {0}, 2", out(reg) token),
}; Priority::Priority3 => core::arch::asm!("rsil {0}, 3", out(reg) token),
};
}
let prev_interrupt_priority = token as u8 & 0x0F; let prev_interrupt_priority = token as u8 & 0x0F;
@ -511,9 +515,13 @@ mod vectored {
/// ///
/// This will replace any previously bound interrupt handler /// This will replace any previously bound interrupt handler
pub unsafe fn bind_interrupt(interrupt: Interrupt, handler: unsafe extern "C" fn()) { pub unsafe fn bind_interrupt(interrupt: Interrupt, handler: unsafe extern "C" fn()) {
let ptr = &pac::__INTERRUPTS[interrupt as usize]._handler as *const _ let ptr = unsafe {
as *mut unsafe extern "C" fn(); &pac::__INTERRUPTS[interrupt as usize]._handler as *const _
ptr.write_volatile(handler); as *mut unsafe extern "C" fn()
};
unsafe {
ptr.write_volatile(handler);
}
} }
/// Returns the currently bound interrupt handler. /// Returns the currently bound interrupt handler.
@ -523,7 +531,6 @@ mod vectored {
if addr as usize == 0 { if addr as usize == 0 {
return None; return None;
} }
Some(addr) Some(addr)
} }
} }
@ -550,7 +557,7 @@ mod vectored {
} }
// TODO use CpuInterrupt::LevelX.mask() // TODO make it const // TODO use CpuInterrupt::LevelX.mask() // TODO make it const
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
static CPU_INTERRUPT_LEVELS: [u32; 8] = [ static CPU_INTERRUPT_LEVELS: [u32; 8] = [
0b_0000_0000_0000_0000_0000_0000_0000_0000, // Dummy level 0 0b_0000_0000_0000_0000_0000_0000_0000_0000, // Dummy level 0
0b_0000_0000_0000_0110_0011_0111_1111_1111, // Level_1 0b_0000_0000_0000_0110_0011_0111_1111_1111, // Level_1
@ -561,9 +568,9 @@ mod vectored {
0b_0000_0000_0000_0000_0000_0000_0000_0000, // Level 6 0b_0000_0000_0000_0000_0000_0000_0000_0000, // Level 6
0b_0000_0000_0000_0000_0100_0000_0000_0000, // Level 7 0b_0000_0000_0000_0000_0100_0000_0000_0000, // Level 7
]; ];
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
static CPU_INTERRUPT_INTERNAL: u32 = 0b_0010_0000_0000_0001_1000_1000_1100_0000; static CPU_INTERRUPT_INTERNAL: u32 = 0b_0010_0000_0000_0001_1000_1000_1100_0000;
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
static CPU_INTERRUPT_EDGE: u32 = 0b_0111_0000_0100_0000_0000_1100_1000_0000; static CPU_INTERRUPT_EDGE: u32 = 0b_0111_0000_0100_0000_0000_1100_1000_0000;
#[inline] #[inline]
@ -584,22 +591,28 @@ mod vectored {
}) })
} }
#[no_mangle] #[unsafe(no_mangle)]
#[ram] #[ram]
unsafe fn __level_1_interrupt(save_frame: &mut Context) { unsafe fn __level_1_interrupt(save_frame: &mut Context) {
handle_interrupts::<1>(save_frame); unsafe {
handle_interrupts::<1>(save_frame);
}
} }
#[no_mangle] #[unsafe(no_mangle)]
#[ram] #[ram]
unsafe fn __level_2_interrupt(save_frame: &mut Context) { unsafe fn __level_2_interrupt(save_frame: &mut Context) {
handle_interrupts::<2>(save_frame); unsafe {
handle_interrupts::<2>(save_frame);
}
} }
#[no_mangle] #[unsafe(no_mangle)]
#[ram] #[ram]
unsafe fn __level_3_interrupt(save_frame: &mut Context) { unsafe fn __level_3_interrupt(save_frame: &mut Context) {
handle_interrupts::<3>(save_frame); unsafe {
handle_interrupts::<3>(save_frame);
}
} }
#[inline(always)] #[inline(always)]
@ -622,11 +635,13 @@ mod vectored {
// If the interrupt is edge triggered, we need to clear the request on the CPU's // If the interrupt is edge triggered, we need to clear the request on the CPU's
// side. // side.
if ((1 << cpu_interrupt_nr) & CPU_INTERRUPT_EDGE) != 0 { if ((1 << cpu_interrupt_nr) & CPU_INTERRUPT_EDGE) != 0 {
interrupt::clear(1 << cpu_interrupt_nr); unsafe {
interrupt::clear(1 << cpu_interrupt_nr);
}
} }
if let Some(handler) = cpu_interrupt_nr_to_cpu_interrupt_handler(cpu_interrupt_nr) { if let Some(handler) = cpu_interrupt_nr_to_cpu_interrupt_handler(cpu_interrupt_nr) {
handler(save_frame); unsafe { handler(save_frame) };
} }
} else { } else {
let status = if !cfg!(esp32s3) && (cpu_interrupt_mask & CPU_INTERRUPT_EDGE) != 0 { let status = if !cfg!(esp32s3) && (cpu_interrupt_mask & CPU_INTERRUPT_EDGE) != 0 {
@ -635,7 +650,7 @@ mod vectored {
// If the interrupt is edge triggered, we need to clear the // If the interrupt is edge triggered, we need to clear the
// request on the CPU's side // request on the CPU's side
interrupt::clear(cpu_interrupt_mask & CPU_INTERRUPT_EDGE); unsafe { interrupt::clear(cpu_interrupt_mask & CPU_INTERRUPT_EDGE) };
// For edge interrupts we cannot rely on the peripherals' interrupt status // For edge interrupts we cannot rely on the peripherals' interrupt status
// registers, therefore call all registered handlers for current level. // registers, therefore call all registered handlers for current level.
@ -651,20 +666,21 @@ mod vectored {
// Don't use `Interrupt::try_from`. It's slower and placed in flash // Don't use `Interrupt::try_from`. It's slower and placed in flash
let interrupt: Interrupt = unsafe { core::mem::transmute(interrupt_nr as u16) }; let interrupt: Interrupt = unsafe { core::mem::transmute(interrupt_nr as u16) };
extern "C" { unsafe extern "C" {
// defined in each hal // defined in each hal
fn EspDefaultHandler(interrupt: Interrupt); fn EspDefaultHandler(interrupt: Interrupt);
} }
let handler = pac::__INTERRUPTS[interrupt as usize]._handler; let handler = unsafe { pac::__INTERRUPTS[interrupt as usize]._handler };
if core::ptr::eq( if core::ptr::eq(
handler as *const _, handler as *const _,
EspDefaultHandler as *const unsafe extern "C" fn(), EspDefaultHandler as *const unsafe extern "C" fn(),
) { ) {
EspDefaultHandler(interrupt); unsafe { EspDefaultHandler(interrupt) };
} else { } else {
let handler: fn(&mut Context) = let handler: fn(&mut Context) = unsafe {
core::mem::transmute::<unsafe extern "C" fn(), fn(&mut Context)>(handler); core::mem::transmute::<unsafe extern "C" fn(), fn(&mut Context)>(handler)
};
handler(save_frame); handler(save_frame);
} }
} }
@ -674,7 +690,7 @@ mod vectored {
#[cfg(esp32)] #[cfg(esp32)]
mod chip_specific { mod chip_specific {
use super::*; use super::*;
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub static INTERRUPT_EDGE: InterruptStatus = InterruptStatus::from( pub static INTERRUPT_EDGE: InterruptStatus = InterruptStatus::from(
0b0000_0000_0000_0000_0000_0000_0000_0000, 0b0000_0000_0000_0000_0000_0000_0000_0000,
0b1111_1100_0000_0000_0000_0000_0000_0000, 0b1111_1100_0000_0000_0000_0000_0000_0000,
@ -699,7 +715,7 @@ mod vectored {
#[cfg(esp32s2)] #[cfg(esp32s2)]
mod chip_specific { mod chip_specific {
use super::*; use super::*;
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub static INTERRUPT_EDGE: InterruptStatus = InterruptStatus::from( pub static INTERRUPT_EDGE: InterruptStatus = InterruptStatus::from(
0b0000_0000_0000_0000_0000_0000_0000_0000, 0b0000_0000_0000_0000_0000_0000_0000_0000,
0b1100_0000_0000_0000_0000_0000_0000_0000, 0b1100_0000_0000_0000_0000_0000_0000_0000,
@ -727,7 +743,7 @@ mod vectored {
#[cfg(esp32s3)] #[cfg(esp32s3)]
mod chip_specific { mod chip_specific {
use super::*; use super::*;
#[cfg_attr(place_switch_tables_in_ram, link_section = ".rwtext")] #[cfg_attr(place_switch_tables_in_ram, unsafe(link_section = ".rwtext"))]
pub static INTERRUPT_EDGE: InterruptStatus = InterruptStatus::empty(); pub static INTERRUPT_EDGE: InterruptStatus = InterruptStatus::empty();
#[inline] #[inline]
pub fn interrupt_is_edge(_interrupt: Interrupt) -> bool { pub fn interrupt_is_edge(_interrupt: Interrupt) -> bool {
@ -739,34 +755,34 @@ mod vectored {
mod raw { mod raw {
use super::*; use super::*;
extern "C" { unsafe extern "C" {
fn level4_interrupt(save_frame: &mut Context); fn level4_interrupt(save_frame: &mut Context);
fn level5_interrupt(save_frame: &mut Context); fn level5_interrupt(save_frame: &mut Context);
fn level6_interrupt(save_frame: &mut Context); fn level6_interrupt(save_frame: &mut Context);
fn level7_interrupt(save_frame: &mut Context); fn level7_interrupt(save_frame: &mut Context);
} }
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".rwtext"] #[unsafe(link_section = ".rwtext")]
unsafe fn __level_4_interrupt(save_frame: &mut Context) { unsafe fn __level_4_interrupt(save_frame: &mut Context) {
level4_interrupt(save_frame) unsafe { level4_interrupt(save_frame) }
} }
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".rwtext"] #[unsafe(link_section = ".rwtext")]
unsafe fn __level_5_interrupt(save_frame: &mut Context) { unsafe fn __level_5_interrupt(save_frame: &mut Context) {
level5_interrupt(save_frame) unsafe { level5_interrupt(save_frame) }
} }
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".rwtext"] #[unsafe(link_section = ".rwtext")]
unsafe fn __level_6_interrupt(save_frame: &mut Context) { unsafe fn __level_6_interrupt(save_frame: &mut Context) {
level6_interrupt(save_frame) unsafe { level6_interrupt(save_frame) }
} }
#[no_mangle] #[unsafe(no_mangle)]
#[link_section = ".rwtext"] #[unsafe(link_section = ".rwtext")]
unsafe fn __level_7_interrupt(save_frame: &mut Context) { unsafe fn __level_7_interrupt(save_frame: &mut Context) {
level7_interrupt(save_frame) unsafe { level7_interrupt(save_frame) }
} }
} }

View File

@ -59,20 +59,20 @@ use core::{
}; };
use crate::{ use crate::{
Blocking,
clock::Clocks, clock::Clocks,
dma::{ChannelRx, DmaError, DmaPeripheral, DmaRxBuffer, PeripheralRxChannel, RxChannelFor}, dma::{ChannelRx, DmaError, DmaPeripheral, DmaRxBuffer, PeripheralRxChannel, RxChannelFor},
gpio::{ gpio::{
interconnect::{PeripheralInput, PeripheralOutput},
InputSignal, InputSignal,
OutputSignal, OutputSignal,
Pull, Pull,
interconnect::{PeripheralInput, PeripheralOutput},
}, },
lcd_cam::{calculate_clkm, BitOrder, ByteOrder, ClockError}, lcd_cam::{BitOrder, ByteOrder, ClockError, calculate_clkm},
pac, pac,
peripherals::LCD_CAM, peripherals::LCD_CAM,
system::{self, GenericPeripheralGuard}, system::{self, GenericPeripheralGuard},
time::Rate, time::Rate,
Blocking,
}; };
/// Generation of GDMA SUC EOF /// Generation of GDMA SUC EOF

View File

@ -102,22 +102,22 @@ use core::{
}; };
use crate::{ use crate::{
Blocking,
DriverMode,
clock::Clocks, clock::Clocks,
dma::{ChannelTx, DmaError, DmaPeripheral, DmaTxBuffer, PeripheralTxChannel, TxChannelFor}, dma::{ChannelTx, DmaError, DmaPeripheral, DmaTxBuffer, PeripheralTxChannel, TxChannelFor},
gpio::{interconnect::PeripheralOutput, Level, OutputSignal}, gpio::{Level, OutputSignal, interconnect::PeripheralOutput},
lcd_cam::{ lcd_cam::{
calculate_clkm,
lcd::{ClockMode, DelayMode, Lcd, Phase, Polarity},
BitOrder, BitOrder,
ByteOrder, ByteOrder,
ClockError, ClockError,
calculate_clkm,
lcd::{ClockMode, DelayMode, Lcd, Phase, Polarity},
}, },
pac, pac,
peripherals::LCD_CAM, peripherals::LCD_CAM,
system::{self, GenericPeripheralGuard}, system::{self, GenericPeripheralGuard},
time::Rate, time::Rate,
Blocking,
DriverMode,
}; };
/// Errors that can occur when configuring the DPI peripheral. /// Errors that can occur when configuring the DPI peripheral.

View File

@ -53,33 +53,33 @@
use core::{ use core::{
fmt::Formatter, fmt::Formatter,
marker::PhantomData, marker::PhantomData,
mem::{size_of, ManuallyDrop}, mem::{ManuallyDrop, size_of},
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
}; };
use crate::{ use crate::{
Blocking,
DriverMode,
clock::Clocks, clock::Clocks,
dma::{ChannelTx, DmaError, DmaPeripheral, DmaTxBuffer, PeripheralTxChannel, TxChannelFor}, dma::{ChannelTx, DmaError, DmaPeripheral, DmaTxBuffer, PeripheralTxChannel, TxChannelFor},
gpio::{ gpio::{
interconnect::{OutputConnection, PeripheralOutput},
OutputSignal, OutputSignal,
interconnect::{OutputConnection, PeripheralOutput},
}, },
lcd_cam::{ lcd_cam::{
calculate_clkm,
lcd::{ClockMode, DelayMode, Phase, Polarity},
BitOrder, BitOrder,
ByteOrder, ByteOrder,
ClockError, ClockError,
Instance, Instance,
Lcd,
LCD_DONE_WAKER, LCD_DONE_WAKER,
Lcd,
calculate_clkm,
lcd::{ClockMode, DelayMode, Phase, Polarity},
}, },
pac, pac,
peripherals::LCD_CAM, peripherals::LCD_CAM,
system::{self, GenericPeripheralGuard}, system::{self, GenericPeripheralGuard},
time::Rate, time::Rate,
Blocking,
DriverMode,
}; };
/// A configuration error. /// A configuration error.

View File

@ -11,14 +11,14 @@ pub mod lcd;
use core::marker::PhantomData; use core::marker::PhantomData;
use crate::{ use crate::{
Async,
Blocking,
asynch::AtomicWaker, asynch::AtomicWaker,
handler, handler,
interrupt::InterruptHandler, interrupt::InterruptHandler,
lcd_cam::{cam::Cam, lcd::Lcd}, lcd_cam::{cam::Cam, lcd::Lcd},
peripherals::{Interrupt, LCD_CAM}, peripherals::{Interrupt, LCD_CAM},
system::{Cpu, GenericPeripheralGuard}, system::{Cpu, GenericPeripheralGuard},
Async,
Blocking,
}; };
/// Represents a combined LCD and Camera interface. /// Represents a combined LCD and Camera interface.
@ -291,11 +291,7 @@ fn calculate_closest_divider(
// https://en.wikipedia.org/wiki/Euclidean_algorithm // https://en.wikipedia.org/wiki/Euclidean_algorithm
const fn hcf(a: usize, b: usize) -> usize { const fn hcf(a: usize, b: usize) -> usize {
if b != 0 { if b != 0 { hcf(b, a % b) } else { a }
hcf(b, a % b)
} else {
a
}
} }
struct Fraction { struct Fraction {

View File

@ -12,8 +12,8 @@
use super::timer::{TimerIFace, TimerSpeed}; use super::timer::{TimerIFace, TimerSpeed};
use crate::{ use crate::{
gpio::{ gpio::{
interconnect::{OutputConnection, PeripheralOutput},
OutputSignal, OutputSignal,
interconnect::{OutputConnection, PeripheralOutput},
}, },
pac::ledc::RegisterBlock, pac::ledc::RegisterBlock,
peripherals::LEDC, peripherals::LEDC,

View File

@ -478,7 +478,9 @@ macro_rules! impl_persistable {
)+}; )+};
} }
impl_persistable!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, f32, f64); impl_persistable!(
u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, f32, f64
);
impl_persistable!(atomic AtomicU8, AtomicI8, AtomicU16, AtomicI16, AtomicU32, AtomicI32, AtomicUsize, AtomicIsize); impl_persistable!(atomic AtomicU8, AtomicI8, AtomicU16, AtomicI16, AtomicU32, AtomicI32, AtomicUsize, AtomicIsize);
unsafe impl<T: Persistable, const N: usize> Persistable for [T; N] {} unsafe impl<T: Persistable, const N: usize> Persistable for [T; N] {}
@ -500,14 +502,14 @@ pub mod __macro_implementation {
} }
#[cfg(riscv)] #[cfg(riscv)]
#[export_name = "hal_main"] #[unsafe(export_name = "hal_main")]
fn hal_main(a0: usize, a1: usize, a2: usize) -> ! { fn hal_main(a0: usize, a1: usize, a2: usize) -> ! {
extern "Rust" { unsafe extern "Rust" {
// This symbol will be provided by the user via `#[entry]` // This symbol will be provided by the user via `#[entry]`
fn main(a0: usize, a1: usize, a2: usize) -> !; fn main(a0: usize, a1: usize, a2: usize) -> !;
} }
extern "C" { unsafe extern "C" {
static mut __stack_chk_guard: u32; static mut __stack_chk_guard: u32;
} }
@ -524,7 +526,7 @@ fn hal_main(a0: usize, a1: usize, a2: usize) -> ! {
} }
} }
#[export_name = "__stack_chk_fail"] #[unsafe(export_name = "__stack_chk_fail")]
unsafe extern "C" fn stack_chk_fail() { unsafe extern "C" fn stack_chk_fail() {
panic!("Stack corruption detected"); panic!("Stack corruption detected");
} }

View File

@ -123,14 +123,14 @@ macro_rules! any_peripheral {
/// ///
/// You must ensure that you're only using one instance of this type at a time. /// You must ensure that you're only using one instance of this type at a time.
#[inline] #[inline]
pub unsafe fn clone_unchecked(&self) -> Self { pub unsafe fn clone_unchecked(&self) -> Self { unsafe {
match &self.0 { match &self.0 {
$( $(
$(#[cfg($variant_meta)])* $(#[cfg($variant_meta)])*
[< $name Inner >]::$variant(inner) => $name([<$name Inner>]::$variant(inner.clone_unchecked())), [< $name Inner >]::$variant(inner) => $name([<$name Inner>]::$variant(inner.clone_unchecked())),
)* )*
} }
} }}
/// Creates a new peripheral reference with a shorter lifetime. /// Creates a new peripheral reference with a shorter lifetime.
/// ///
@ -244,9 +244,9 @@ macro_rules! ignore {
#[doc(hidden)] #[doc(hidden)]
macro_rules! metadata { macro_rules! metadata {
($category:literal, $key:ident, $value:expr) => { ($category:literal, $key:ident, $value:expr) => {
#[link_section = concat!(".espressif.metadata")] #[unsafe(link_section = concat!(".espressif.metadata"))]
#[used] #[used]
#[export_name = concat!($category, ".", stringify!($key))] #[unsafe(export_name = concat!($category, ".", stringify!($key)))]
static $key: [u8; $value.len()] = const { static $key: [u8; $value.len()] = const {
let val_bytes = $value.as_bytes(); let val_bytes = $value.as_bytes();
let mut val_bytes_array = [0; $value.len()]; let mut val_bytes_array = [0; $value.len()];

View File

@ -14,7 +14,7 @@ use core::marker::PhantomData;
use super::PeripheralGuard; use super::PeripheralGuard;
use crate::{ use crate::{
gpio::interconnect::{OutputConnection, PeripheralOutput}, gpio::interconnect::{OutputConnection, PeripheralOutput},
mcpwm::{timer::Timer, PwmPeripheral}, mcpwm::{PwmPeripheral, timer::Timer},
pac, pac,
}; };
@ -320,7 +320,8 @@ impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP,
// SAFETY: // SAFETY:
// `bits` is a valid bit pattern // `bits` is a valid bit pattern
ch.gen((!IS_A) as usize).write(|w| unsafe { w.bits(bits) }); ch.r#gen((!IS_A) as usize)
.write(|w| unsafe { w.bits(bits) });
} }
/// Set how a new timestamp syncs with the timer /// Set how a new timestamp syncs with the timer

View File

@ -131,8 +131,6 @@ pub mod asynch {
}; };
pub use embassy_usb_synopsys_otg::Config; pub use embassy_usb_synopsys_otg::Config;
use embassy_usb_synopsys_otg::{ use embassy_usb_synopsys_otg::{
on_interrupt,
otg_v1::Otg,
Bus as OtgBus, Bus as OtgBus,
ControlPipe, ControlPipe,
Driver as OtgDriver, Driver as OtgDriver,
@ -142,6 +140,8 @@ pub mod asynch {
Out, Out,
PhyType, PhyType,
State, State,
on_interrupt,
otg_v1::Otg,
}; };
use procmacros::handler; use procmacros::handler;

View File

@ -132,6 +132,9 @@ use enumset::{EnumSet, EnumSetType};
use private::*; use private::*;
use crate::{ use crate::{
Async,
Blocking,
DriverMode,
dma::{ dma::{
Channel, Channel,
ChannelRx, ChannelRx,
@ -145,17 +148,14 @@ use crate::{
PeripheralTxChannel, PeripheralTxChannel,
}, },
gpio::{ gpio::{
interconnect::{InputConnection, OutputConnection, PeripheralInput, PeripheralOutput},
NoPin, NoPin,
interconnect::{InputConnection, OutputConnection, PeripheralInput, PeripheralOutput},
}, },
interrupt::InterruptHandler, interrupt::InterruptHandler,
parl_io::asynch::interrupt_handler, parl_io::asynch::interrupt_handler,
peripherals::{Interrupt, PARL_IO, PCR}, peripherals::{Interrupt, PARL_IO, PCR},
system::{self, GenericPeripheralGuard}, system::{self, GenericPeripheralGuard},
time::Rate, time::Rate,
Async,
Blocking,
DriverMode,
}; };
const MAX_DMA_SIZE: usize = 65535; const MAX_DMA_SIZE: usize = 65535;
@ -1546,10 +1546,10 @@ pub mod asynch {
use procmacros::handler; use procmacros::handler;
use super::{private::Instance, ParlIoRxTransfer, ParlIoTxTransfer}; use super::{ParlIoRxTransfer, ParlIoTxTransfer, private::Instance};
use crate::{ use crate::{
asynch::AtomicWaker, asynch::AtomicWaker,
dma::{asynch::DmaRxFuture, DmaRxBuffer, DmaTxBuffer}, dma::{DmaRxBuffer, DmaTxBuffer, asynch::DmaRxFuture},
}; };
static TX_WAKER: AtomicWaker = AtomicWaker::new(); static TX_WAKER: AtomicWaker = AtomicWaker::new();

View File

@ -11,7 +11,7 @@ use core::marker::PhantomData;
pub use crate::pac::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE as EdgeMode}; pub use crate::pac::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE as EdgeMode};
use crate::{ use crate::{
gpio::{interconnect::PeripheralInput, InputSignal}, gpio::{InputSignal, interconnect::PeripheralInput},
peripherals::PCNT, peripherals::PCNT,
system::GenericPeripheralGuard, system::GenericPeripheralGuard,
}; };

View File

@ -74,7 +74,7 @@ macro_rules! peripherals {
/// Returns all the peripherals *once* /// Returns all the peripherals *once*
#[inline] #[inline]
pub(crate) fn take() -> Self { pub(crate) fn take() -> Self {
#[no_mangle] #[unsafe(no_mangle)]
static mut _ESP_HAL_DEVICE_PERIPHERALS: bool = false; static mut _ESP_HAL_DEVICE_PERIPHERALS: bool = false;
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
@ -93,17 +93,19 @@ macro_rules! peripherals {
/// You must ensure that you're only using one instance of this type at a time. /// You must ensure that you're only using one instance of this type at a time.
#[inline] #[inline]
pub unsafe fn steal() -> Self { pub unsafe fn steal() -> Self {
Self { unsafe {
$( Self {
$name: $name::steal(), $(
)* $name: $name::steal(),
$( )*
$unstable_name: $unstable_name::steal(), $(
)* $unstable_name: $unstable_name::steal(),
)*
$( $(
[<GPIO $pin>]: [<GPIO $pin>]::steal(), [<GPIO $pin>]: [<GPIO $pin>]::steal(),
)* )*
}
} }
} }
} }
@ -182,9 +184,9 @@ macro_rules! create_peripheral {
/// You must ensure that you're only using one instance of this type at a time. /// You must ensure that you're only using one instance of this type at a time.
#[inline] #[inline]
#[allow(dead_code)] #[allow(dead_code)]
pub unsafe fn clone_unchecked(&self) -> Self { pub unsafe fn clone_unchecked(&self) -> Self { unsafe {
Self::steal() Self::steal()
} }}
/// Creates a new peripheral reference with a shorter lifetime. /// Creates a new peripheral reference with a shorter lifetime.
/// ///

View File

@ -229,18 +229,18 @@ use core::{
use enumset::{EnumSet, EnumSetType}; use enumset::{EnumSet, EnumSetType};
use crate::{ use crate::{
Async,
Blocking,
asynch::AtomicWaker, asynch::AtomicWaker,
gpio::{ gpio::{
interconnect::{PeripheralInput, PeripheralOutput},
Level, Level,
interconnect::{PeripheralInput, PeripheralOutput},
}, },
handler, handler,
peripherals::{Interrupt, RMT}, peripherals::{Interrupt, RMT},
soc::constants, soc::constants,
system::{self, GenericPeripheralGuard}, system::{self, GenericPeripheralGuard},
time::Rate, time::Rate,
Async,
Blocking,
}; };
/// Errors /// Errors

View File

@ -198,10 +198,10 @@ impl<'d> Trng<'d> {
/// ///
/// Returns a new `Trng` instance. /// Returns a new `Trng` instance.
pub fn new(rng: RNG<'_>, adc: ADC1<'d>) -> Self { pub fn new(rng: RNG<'_>, adc: ADC1<'d>) -> Self {
let gen = Rng::new(rng); let r#gen = Rng::new(rng);
crate::soc::trng::ensure_randomness(); crate::soc::trng::ensure_randomness();
Self { Self {
rng: gen, rng: r#gen,
_adc: adc, _adc: adc,
} }
} }

View File

@ -100,7 +100,7 @@
#[cfg(rom_crc_be)] #[cfg(rom_crc_be)]
#[inline(always)] #[inline(always)]
pub fn crc32_be(crc: u32, buf: &[u8]) -> u32 { pub fn crc32_be(crc: u32, buf: &[u8]) -> u32 {
extern "C" { unsafe extern "C" {
fn esp_rom_crc32_be(crc: u32, buf: *const u8, len: u32) -> u32; fn esp_rom_crc32_be(crc: u32, buf: *const u8, len: u32) -> u32;
} }
unsafe { esp_rom_crc32_be(crc, buf.as_ptr(), buf.len() as u32) } unsafe { esp_rom_crc32_be(crc, buf.as_ptr(), buf.len() as u32) }
@ -110,7 +110,7 @@ pub fn crc32_be(crc: u32, buf: &[u8]) -> u32 {
#[cfg(rom_crc_be)] #[cfg(rom_crc_be)]
#[inline(always)] #[inline(always)]
pub fn crc16_be(crc: u16, buf: &[u8]) -> u16 { pub fn crc16_be(crc: u16, buf: &[u8]) -> u16 {
extern "C" { unsafe extern "C" {
fn esp_rom_crc16_be(crc: u16, buf: *const u8, len: u32) -> u16; fn esp_rom_crc16_be(crc: u16, buf: *const u8, len: u32) -> u16;
} }
unsafe { esp_rom_crc16_be(crc, buf.as_ptr(), buf.len() as u32) } unsafe { esp_rom_crc16_be(crc, buf.as_ptr(), buf.len() as u32) }
@ -120,7 +120,7 @@ pub fn crc16_be(crc: u16, buf: &[u8]) -> u16 {
#[cfg(rom_crc_be)] #[cfg(rom_crc_be)]
#[inline(always)] #[inline(always)]
pub fn crc8_be(crc: u8, buf: &[u8]) -> u8 { pub fn crc8_be(crc: u8, buf: &[u8]) -> u8 {
extern "C" { unsafe extern "C" {
fn esp_rom_crc8_be(crc: u8, buf: *const u8, len: u32) -> u8; fn esp_rom_crc8_be(crc: u8, buf: *const u8, len: u32) -> u8;
} }
unsafe { esp_rom_crc8_be(crc, buf.as_ptr(), buf.len() as u32) } unsafe { esp_rom_crc8_be(crc, buf.as_ptr(), buf.len() as u32) }
@ -130,7 +130,7 @@ pub fn crc8_be(crc: u8, buf: &[u8]) -> u8 {
#[cfg(rom_crc_le)] #[cfg(rom_crc_le)]
#[inline(always)] #[inline(always)]
pub fn crc32_le(crc: u32, buf: &[u8]) -> u32 { pub fn crc32_le(crc: u32, buf: &[u8]) -> u32 {
extern "C" { unsafe extern "C" {
fn esp_rom_crc32_le(crc: u32, buf: *const u8, len: u32) -> u32; fn esp_rom_crc32_le(crc: u32, buf: *const u8, len: u32) -> u32;
} }
unsafe { esp_rom_crc32_le(crc, buf.as_ptr(), buf.len() as u32) } unsafe { esp_rom_crc32_le(crc, buf.as_ptr(), buf.len() as u32) }
@ -140,7 +140,7 @@ pub fn crc32_le(crc: u32, buf: &[u8]) -> u32 {
#[cfg(rom_crc_le)] #[cfg(rom_crc_le)]
#[inline(always)] #[inline(always)]
pub fn crc16_le(crc: u16, buf: &[u8]) -> u16 { pub fn crc16_le(crc: u16, buf: &[u8]) -> u16 {
extern "C" { unsafe extern "C" {
fn esp_rom_crc16_le(crc: u16, buf: *const u8, len: u32) -> u16; fn esp_rom_crc16_le(crc: u16, buf: *const u8, len: u32) -> u16;
} }
unsafe { esp_rom_crc16_le(crc, buf.as_ptr(), buf.len() as u32) } unsafe { esp_rom_crc16_le(crc, buf.as_ptr(), buf.len() as u32) }
@ -150,7 +150,7 @@ pub fn crc16_le(crc: u16, buf: &[u8]) -> u16 {
#[inline(always)] #[inline(always)]
#[cfg(rom_crc_le)] #[cfg(rom_crc_le)]
pub fn crc8_le(crc: u8, buf: &[u8]) -> u8 { pub fn crc8_le(crc: u8, buf: &[u8]) -> u8 {
extern "C" { unsafe extern "C" {
fn esp_rom_crc8_le(crc: u8, buf: *const u8, len: u32) -> u8; fn esp_rom_crc8_le(crc: u8, buf: *const u8, len: u32) -> u8;
} }
unsafe { esp_rom_crc8_le(crc, buf.as_ptr(), buf.len() as u32) } unsafe { esp_rom_crc8_le(crc, buf.as_ptr(), buf.len() as u32) }

View File

@ -78,7 +78,7 @@ struct InternalContext {
} }
#[cfg(rom_md5_bsd)] #[cfg(rom_md5_bsd)]
extern "C" { unsafe extern "C" {
fn esp_rom_md5_init(context: *mut InternalContext); fn esp_rom_md5_init(context: *mut InternalContext);
fn esp_rom_md5_update(context: *mut InternalContext, buf: *const c_void, len: u32); fn esp_rom_md5_update(context: *mut InternalContext, buf: *const c_void, len: u32);
fn esp_rom_md5_final(digest: *mut u8, context: *mut InternalContext); fn esp_rom_md5_final(digest: *mut u8, context: *mut InternalContext);
@ -94,7 +94,7 @@ struct InternalContext {
} }
#[cfg(rom_md5_mbedtls)] #[cfg(rom_md5_mbedtls)]
extern "C" { unsafe extern "C" {
fn esp_rom_mbedtls_md5_starts_ret(context: *mut InternalContext) -> c_int; fn esp_rom_mbedtls_md5_starts_ret(context: *mut InternalContext) -> c_int;
fn esp_rom_mbedtls_md5_update_ret( fn esp_rom_mbedtls_md5_update_ret(
context: *mut InternalContext, context: *mut InternalContext,

View File

@ -33,7 +33,7 @@ pub(crate) mod regi2c;
#[inline(always)] #[inline(always)]
pub(crate) fn ets_delay_us(us: u32) { pub(crate) fn ets_delay_us(us: u32) {
extern "C" { unsafe extern "C" {
fn ets_delay_us(us: u32); fn ets_delay_us(us: u32);
} }
@ -43,7 +43,7 @@ pub(crate) fn ets_delay_us(us: u32) {
#[allow(unused)] #[allow(unused)]
#[inline(always)] #[inline(always)]
pub(crate) fn ets_update_cpu_frequency_rom(ticks_per_us: u32) { pub(crate) fn ets_update_cpu_frequency_rom(ticks_per_us: u32) {
extern "C" { unsafe extern "C" {
fn ets_update_cpu_frequency(ticks_per_us: u32); fn ets_update_cpu_frequency(ticks_per_us: u32);
} }
@ -52,7 +52,7 @@ pub(crate) fn ets_update_cpu_frequency_rom(ticks_per_us: u32) {
#[inline(always)] #[inline(always)]
pub(crate) fn rtc_get_reset_reason(cpu_num: u32) -> u32 { pub(crate) fn rtc_get_reset_reason(cpu_num: u32) -> u32 {
extern "C" { unsafe extern "C" {
fn rtc_get_reset_reason(cpu_num: u32) -> u32; fn rtc_get_reset_reason(cpu_num: u32) -> u32;
} }
@ -61,7 +61,7 @@ pub(crate) fn rtc_get_reset_reason(cpu_num: u32) -> u32 {
#[inline(always)] #[inline(always)]
pub(crate) fn software_reset_cpu(cpu_num: u32) { pub(crate) fn software_reset_cpu(cpu_num: u32) {
extern "C" { unsafe extern "C" {
fn software_reset_cpu(cpu_num: u32); fn software_reset_cpu(cpu_num: u32);
} }
@ -70,7 +70,7 @@ pub(crate) fn software_reset_cpu(cpu_num: u32) {
#[inline(always)] #[inline(always)]
pub(crate) fn software_reset() -> ! { pub(crate) fn software_reset() -> ! {
extern "C" { unsafe extern "C" {
fn software_reset() -> !; fn software_reset() -> !;
} }
@ -80,7 +80,7 @@ pub(crate) fn software_reset() -> ! {
#[cfg(esp32s3)] #[cfg(esp32s3)]
#[inline(always)] #[inline(always)]
pub(crate) fn ets_set_appcpu_boot_addr(boot_addr: u32) { pub(crate) fn ets_set_appcpu_boot_addr(boot_addr: u32) {
extern "C" { unsafe extern "C" {
fn ets_set_appcpu_boot_addr(boot_addr: u32); fn ets_set_appcpu_boot_addr(boot_addr: u32);
} }

View File

@ -1,13 +1,13 @@
use core::convert::Infallible; use core::convert::Infallible;
use crate::rsa::{ use crate::rsa::{
implement_op,
Multi, Multi,
Rsa, Rsa,
RsaMode, RsaMode,
RsaModularExponentiation, RsaModularExponentiation,
RsaModularMultiplication, RsaModularMultiplication,
RsaMultiplication, RsaMultiplication,
implement_op,
}; };
impl<Dm: crate::DriverMode> Rsa<'_, Dm> { impl<Dm: crate::DriverMode> Rsa<'_, Dm> {
@ -65,7 +65,7 @@ pub mod operand_sizes {
//! Marker types for the operand sizes //! Marker types for the operand sizes
use paste::paste; use paste::paste;
use super::{implement_op, Multi, RsaMode}; use super::{Multi, RsaMode, implement_op};
implement_op!( implement_op!(
(512, multi), (512, multi),

View File

@ -1,13 +1,13 @@
use core::convert::Infallible; use core::convert::Infallible;
use crate::rsa::{ use crate::rsa::{
implement_op,
Multi, Multi,
Rsa, Rsa,
RsaMode, RsaMode,
RsaModularExponentiation, RsaModularExponentiation,
RsaModularMultiplication, RsaModularMultiplication,
RsaMultiplication, RsaMultiplication,
implement_op,
}; };
impl<Dm: crate::DriverMode> Rsa<'_, Dm> { impl<Dm: crate::DriverMode> Rsa<'_, Dm> {
@ -123,7 +123,7 @@ pub mod operand_sizes {
//! Marker types for the operand sizes //! Marker types for the operand sizes
use paste::paste; use paste::paste;
use super::{implement_op, Multi, RsaMode}; use super::{Multi, RsaMode, implement_op};
implement_op!( implement_op!(
(32, multi), (32, multi),

View File

@ -1,13 +1,13 @@
use core::convert::Infallible; use core::convert::Infallible;
use crate::rsa::{ use crate::rsa::{
implement_op,
Multi, Multi,
Rsa, Rsa,
RsaMode, RsaMode,
RsaModularExponentiation, RsaModularExponentiation,
RsaModularMultiplication, RsaModularMultiplication,
RsaMultiplication, RsaMultiplication,
implement_op,
}; };
impl<Dm: crate::DriverMode> Rsa<'_, Dm> { impl<Dm: crate::DriverMode> Rsa<'_, Dm> {
@ -115,7 +115,7 @@ pub mod operand_sizes {
//! Marker types for the operand sizes //! Marker types for the operand sizes
use paste::paste; use paste::paste;
use super::{implement_op, Multi, RsaMode}; use super::{Multi, RsaMode, implement_op};
implement_op!( implement_op!(
(32, multi), (32, multi),

View File

@ -24,12 +24,12 @@
use core::{marker::PhantomData, ptr::copy_nonoverlapping}; use core::{marker::PhantomData, ptr::copy_nonoverlapping};
use crate::{ use crate::{
Async,
Blocking,
interrupt::InterruptHandler, interrupt::InterruptHandler,
pac, pac,
peripherals::{Interrupt, RSA}, peripherals::{Interrupt, RSA},
system::{Cpu, GenericPeripheralGuard, Peripheral as PeripheralEnable}, system::{Cpu, GenericPeripheralGuard, Peripheral as PeripheralEnable},
Async,
Blocking,
}; };
#[cfg_attr(esp32s2, path = "esp32sX.rs")] #[cfg_attr(esp32s2, path = "esp32sX.rs")]
@ -386,6 +386,7 @@ pub(crate) mod asynch {
use procmacros::handler; use procmacros::handler;
use crate::{ use crate::{
Async,
asynch::AtomicWaker, asynch::AtomicWaker,
peripherals::RSA, peripherals::RSA,
rsa::{ rsa::{
@ -396,7 +397,6 @@ pub(crate) mod asynch {
RsaModularMultiplication, RsaModularMultiplication,
RsaMultiplication, RsaMultiplication,
}, },
Async,
}; };
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();

View File

@ -1272,7 +1272,7 @@ pub fn wakeup_cause() -> SleepSource {
// libphy.a can pull this in on some chips, we provide it here in the hal // libphy.a can pull this in on some chips, we provide it here in the hal
// so that either ieee or esp-wifi gets it for free without duplicating in both // so that either ieee or esp-wifi gets it for free without duplicating in both
#[no_mangle] #[unsafe(no_mangle)]
extern "C" fn rtc_clk_xtal_freq_get() -> i32 { extern "C" fn rtc_clk_xtal_freq_get() -> i32 {
let xtal = RtcClock::xtal_freq(); let xtal = RtcClock::xtal_freq();
xtal.mhz() as i32 xtal.mhz() as i32

View File

@ -6,6 +6,8 @@ use strum::FromRepr;
use crate::{ use crate::{
clock::{ clock::{
Clock,
XtalClock,
clocks_ll::{ clocks_ll::{
esp32c6_bbpll_get_freq_mhz, esp32c6_bbpll_get_freq_mhz,
esp32c6_cpu_get_hs_divider, esp32c6_cpu_get_hs_divider,
@ -15,8 +17,6 @@ use crate::{
esp32c6_rtc_update_to_8m, esp32c6_rtc_update_to_8m,
esp32c6_rtc_update_to_xtal_raw, esp32c6_rtc_update_to_xtal_raw,
}, },
Clock,
XtalClock,
}, },
peripherals::TIMG0, peripherals::TIMG0,
rtc_cntl::RtcClock, rtc_cntl::RtcClock,
@ -25,27 +25,27 @@ use crate::{
}; };
unsafe fn pmu<'a>() -> &'a esp32c6::pmu::RegisterBlock { unsafe fn pmu<'a>() -> &'a esp32c6::pmu::RegisterBlock {
&*esp32c6::PMU::ptr() unsafe { &*esp32c6::PMU::ptr() }
} }
unsafe fn modem_lpcon<'a>() -> &'a esp32c6::modem_lpcon::RegisterBlock { unsafe fn modem_lpcon<'a>() -> &'a esp32c6::modem_lpcon::RegisterBlock {
&*esp32c6::MODEM_LPCON::ptr() unsafe { &*esp32c6::MODEM_LPCON::ptr() }
} }
unsafe fn modem_syscon<'a>() -> &'a esp32c6::modem_syscon::RegisterBlock { unsafe fn modem_syscon<'a>() -> &'a esp32c6::modem_syscon::RegisterBlock {
&*esp32c6::MODEM_SYSCON::ptr() unsafe { &*esp32c6::MODEM_SYSCON::ptr() }
} }
unsafe fn lp_clkrst<'a>() -> &'a esp32c6::lp_clkrst::RegisterBlock { unsafe fn lp_clkrst<'a>() -> &'a esp32c6::lp_clkrst::RegisterBlock {
&*esp32c6::LP_CLKRST::ptr() unsafe { &*esp32c6::LP_CLKRST::ptr() }
} }
unsafe fn pcr<'a>() -> &'a esp32c6::pcr::RegisterBlock { unsafe fn pcr<'a>() -> &'a esp32c6::pcr::RegisterBlock {
&*esp32c6::PCR::ptr() unsafe { &*esp32c6::PCR::ptr() }
} }
unsafe fn lp_aon<'a>() -> &'a esp32c6::lp_aon::RegisterBlock { unsafe fn lp_aon<'a>() -> &'a esp32c6::lp_aon::RegisterBlock {
&*esp32c6::LP_AON::ptr() unsafe { &*esp32c6::LP_AON::ptr() }
} }
fn pmu_power_domain_force_default() { fn pmu_power_domain_force_default() {

View File

@ -1,8 +1,8 @@
use strum::FromRepr; use strum::FromRepr;
use crate::{ use crate::{
clock::{clocks_ll::regi2c_write_mask, Clock, XtalClock}, clock::{Clock, XtalClock, clocks_ll::regi2c_write_mask},
peripherals::{LPWR, LP_AON, PCR, PMU, TIMG0}, peripherals::{LP_AON, LPWR, PCR, PMU, TIMG0},
rtc_cntl::RtcClock, rtc_cntl::RtcClock,
time::Rate, time::Rate,
}; };

View File

@ -2,7 +2,7 @@ use super::{Ext0WakeupSource, Ext1WakeupSource, TimerWakeupSource, WakeSource, W
use crate::{ use crate::{
gpio::{RtcFunction, RtcPin}, gpio::{RtcFunction, RtcPin},
peripherals::{BB, DPORT, I2S0, LPWR, NRX, RTC_IO}, peripherals::{BB, DPORT, I2S0, LPWR, NRX, RTC_IO},
rtc_cntl::{sleep::WakeupLevel, Clock, Rtc, RtcClock}, rtc_cntl::{Clock, Rtc, RtcClock, sleep::WakeupLevel},
}; };
// Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP, // Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP,

View File

@ -2,7 +2,7 @@ use super::{TimerWakeupSource, WakeSource, WakeTriggers, WakeupLevel};
use crate::{ use crate::{
gpio::{RtcFunction, RtcPinWithResistors}, gpio::{RtcFunction, RtcPinWithResistors},
peripherals::{APB_CTRL, BB, EXTMEM, GPIO, IO_MUX, LPWR, SPI0, SPI1, SYSTEM}, peripherals::{APB_CTRL, BB, EXTMEM, GPIO, IO_MUX, LPWR, SPI0, SPI1, SYSTEM},
rtc_cntl::{sleep::RtcioWakeupSource, Clock, Rtc, RtcClock}, rtc_cntl::{Clock, Rtc, RtcClock, sleep::RtcioWakeupSource},
soc::regi2c, soc::regi2c,
}; };

View File

@ -2,7 +2,7 @@ use super::{TimerWakeupSource, WakeSource, WakeTriggers, WakeupLevel};
use crate::{ use crate::{
gpio::{RtcFunction, RtcPinWithResistors}, gpio::{RtcFunction, RtcPinWithResistors},
peripherals::{APB_CTRL, BB, EXTMEM, FE, FE2, GPIO, IO_MUX, LPWR, NRX, SPI0, SPI1, SYSTEM}, peripherals::{APB_CTRL, BB, EXTMEM, FE, FE2, GPIO, IO_MUX, LPWR, NRX, SPI0, SPI1, SYSTEM},
rtc_cntl::{sleep::RtcioWakeupSource, Clock, Rtc, RtcClock}, rtc_cntl::{Clock, Rtc, RtcClock, sleep::RtcioWakeupSource},
soc::regi2c, soc::regi2c,
}; };

View File

@ -5,8 +5,9 @@ use crate::{
efuse::Efuse, efuse::Efuse,
gpio::RtcFunction, gpio::RtcFunction,
rtc_cntl::{ rtc_cntl::{
Rtc,
RtcClock,
rtc::{ rtc::{
rtc_clk_cpu_freq_set_xtal,
HpAnalog, HpAnalog,
HpSysCntlReg, HpSysCntlReg,
HpSysPower, HpSysPower,
@ -14,6 +15,7 @@ use crate::{
LpSysPower, LpSysPower,
RtcCalSel, RtcCalSel,
SavedClockConfig, SavedClockConfig,
rtc_clk_cpu_freq_set_xtal,
}, },
sleep::{ sleep::{
Ext1WakeupSource, Ext1WakeupSource,
@ -23,8 +25,6 @@ use crate::{
WakeTriggers, WakeTriggers,
WakeupLevel, WakeupLevel,
}, },
Rtc,
RtcClock,
}, },
}; };
@ -783,11 +783,11 @@ impl Default for RtcSleepConfig {
} }
unsafe fn pmu<'a>() -> &'a esp32c6::pmu::RegisterBlock { unsafe fn pmu<'a>() -> &'a esp32c6::pmu::RegisterBlock {
&*esp32c6::PMU::ptr() unsafe { &*esp32c6::PMU::ptr() }
} }
unsafe fn lp_aon<'a>() -> &'a esp32c6::lp_aon::RegisterBlock { unsafe fn lp_aon<'a>() -> &'a esp32c6::lp_aon::RegisterBlock {
&*esp32c6::LP_AON::ptr() unsafe { &*esp32c6::LP_AON::ptr() }
} }
bitfield::bitfield! { bitfield::bitfield! {

View File

@ -9,7 +9,7 @@ use super::{
use crate::{ use crate::{
gpio::{RtcFunction, RtcPin}, gpio::{RtcFunction, RtcPin},
peripherals::{EXTMEM, LPWR, RTC_IO, SENS, SPI0, SPI1, SYSTEM}, peripherals::{EXTMEM, LPWR, RTC_IO, SENS, SPI0, SPI1, SYSTEM},
rtc_cntl::{sleep::RtcioWakeupSource, Clock, Rtc, RtcClock}, rtc_cntl::{Clock, Rtc, RtcClock, sleep::RtcioWakeupSource},
soc::regi2c, soc::regi2c,
}; };

View File

@ -9,7 +9,7 @@ use super::{
use crate::{ use crate::{
gpio::{RtcFunction, RtcPin}, gpio::{RtcFunction, RtcPin},
peripherals::{APB_CTRL, EXTMEM, LPWR, RTC_IO, SPI0, SPI1, SYSTEM}, peripherals::{APB_CTRL, EXTMEM, LPWR, RTC_IO, SPI0, SPI1, SYSTEM},
rtc_cntl::{sleep::RtcioWakeupSource, Clock, Rtc, RtcClock}, rtc_cntl::{Clock, Rtc, RtcClock, sleep::RtcioWakeupSource},
soc::regi2c, soc::regi2c,
}; };

View File

@ -159,18 +159,18 @@ unsafe fn internal_park_core(core: Cpu, park: bool) {
Cpu::ProCpu => { Cpu::ProCpu => {
LPWR::regs() LPWR::regs()
.sw_cpu_stall() .sw_cpu_stall()
.modify(|_, w| w.sw_stall_procpu_c1().bits(c1_value)); .modify(|_, w| unsafe { w.sw_stall_procpu_c1().bits(c1_value) });
LPWR::regs() LPWR::regs()
.options0() .options0()
.modify(|_, w| w.sw_stall_procpu_c0().bits(c0_value)); .modify(|_, w| unsafe { w.sw_stall_procpu_c0().bits(c0_value) });
} }
Cpu::AppCpu => { Cpu::AppCpu => {
LPWR::regs() LPWR::regs()
.sw_cpu_stall() .sw_cpu_stall()
.modify(|_, w| w.sw_stall_appcpu_c1().bits(c1_value)); .modify(|_, w| unsafe { w.sw_stall_appcpu_c1().bits(c1_value) });
LPWR::regs() LPWR::regs()
.options0() .options0()
.modify(|_, w| w.sw_stall_appcpu_c0().bits(c0_value)); .modify(|_, w| unsafe { w.sw_stall_appcpu_c0().bits(c0_value) });
} }
} }
} }
@ -192,7 +192,9 @@ impl<'d> CpuControl<'d> {
/// currently executing their code. /// currently executing their code.
#[instability::unstable] #[instability::unstable]
pub unsafe fn park_core(&mut self, core: Cpu) { pub unsafe fn park_core(&mut self, core: Cpu) {
internal_park_core(core, true); unsafe {
internal_park_core(core, true);
}
} }
/// Unpark the given core /// Unpark the given core
@ -273,31 +275,33 @@ impl<'d> CpuControl<'d> {
F: FnOnce(), F: FnOnce(),
{ {
// disables interrupts // disables interrupts
xtensa_lx::interrupt::set_mask(0); unsafe {
xtensa_lx::interrupt::set_mask(0);
}
// reset cycle compare registers // reset cycle compare registers
xtensa_lx::timer::set_ccompare0(0); xtensa_lx::timer::set_ccompare0(0);
xtensa_lx::timer::set_ccompare1(0); xtensa_lx::timer::set_ccompare1(0);
xtensa_lx::timer::set_ccompare2(0); xtensa_lx::timer::set_ccompare2(0);
extern "C" { unsafe extern "C" {
static mut _init_start: u32; static mut _init_start: u32;
} }
unsafe { // move vec table
// move vec table let base = core::ptr::addr_of!(_init_start);
let base = core::ptr::addr_of!(_init_start);
core::arch::asm!("wsr.vecbase {0}", in(reg) base, options(nostack));
}
// switch to new stack unsafe {
xtensa_lx::set_stack_pointer(unwrap!(APP_CORE_STACK_TOP)); core::arch::asm!("wsr.vecbase {0}", in(reg) base, options(nostack));
// switch to new stack
xtensa_lx::set_stack_pointer(unwrap!(APP_CORE_STACK_TOP));
}
// Trampoline to run from the new stack. // Trampoline to run from the new stack.
// start_core1_run should _NEVER_ be inlined // start_core1_run should _NEVER_ be inlined
// as we rely on the function call to use // as we rely on the function call to use
// the new stack. // the new stack.
Self::start_core1_run::<F>() unsafe { Self::start_core1_run::<F>() }
} }
/// Run the core1 closure. /// Run the core1 closure.
@ -307,14 +311,14 @@ impl<'d> CpuControl<'d> {
F: FnOnce(), F: FnOnce(),
{ {
#[allow(static_mut_refs)] // FIXME #[allow(static_mut_refs)] // FIXME
match START_CORE1_FUNCTION.take() { match unsafe { START_CORE1_FUNCTION.take() } {
Some(entry) => { Some(entry) => unsafe {
let entry = unsafe { ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>()) }; let entry = ManuallyDrop::take(&mut *entry.cast::<ManuallyDrop<F>>());
entry(); entry();
loop { loop {
unsafe { internal_park_core(Cpu::current(), true) }; internal_park_core(Cpu::current(), true);
} }
} },
None => panic!("No start function set"), None => panic!("No start function set"),
} }
} }

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