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:
CARGO_TERM_COLOR: always
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MSRV: "1.84.0"
MSRV: "1.85.0"
DEFMT_LOG: trace
# 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)
### Changed
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Fixed

View File

@ -1,8 +1,8 @@
[package]
name = "esp-alloc"
version = "0.7.0"
edition = "2021"
rust-version = "1.84.0"
edition = "2024"
rust-version = "1.85.0"
description = "A heap allocator for Espressif devices"
documentation = "https://docs.espressif.com/projects/rust/esp-alloc/latest/"
keywords = ["allocator", "embedded", "esp32", "espressif", "memory"]
@ -14,6 +14,10 @@ license = "MIT OR Apache-2.0"
default-target = "riscv32imc-unknown-none-elf"
features = ["nightly"]
[lib]
bench = false
test = false
[dependencies]
allocator-api2 = { version = "0.2.0", default-features = false }
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) {
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) {
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) {
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) {
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,
capabilities: EnumSet<MemoryCapability>,
) -> Self {
let mut heap = Heap::empty();
heap.init(heap_bottom, size);
unsafe {
let mut heap = Heap::empty();
heap.init(heap_bottom, size);
Self { heap, capabilities }
Self { heap, capabilities }
}
}
/// Return stats for the current memory region
@ -599,35 +601,37 @@ impl EspHeap {
unsafe impl GlobalAlloc for EspHeap {
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) {
if ptr.is_null() {
return;
}
unsafe {
if ptr.is_null() {
return;
}
critical_section::with(|cs| {
#[cfg(feature = "internal-heap-stats")]
let before = self.used();
let mut regions = self.heap.borrow_ref_mut(cs);
let mut iter = (*regions).iter_mut();
critical_section::with(|cs| {
#[cfg(feature = "internal-heap-stats")]
let before = self.used();
let mut regions = self.heap.borrow_ref_mut(cs);
let mut iter = (*regions).iter_mut();
while let Some(Some(region)) = iter.next() {
if region.heap.bottom() <= ptr && region.heap.top() >= ptr {
region.heap.deallocate(NonNull::new_unchecked(ptr), layout);
while let Some(Some(region)) = iter.next() {
if region.heap.bottom() <= ptr && region.heap.top() >= ptr {
region.heap.deallocate(NonNull::new_unchecked(ptr), layout);
}
}
}
#[cfg(feature = "internal-heap-stats")]
{
let mut internal_heap_stats = self.internal_heap_stats.borrow_ref_mut(cs);
drop(regions);
// We need to call `used()` because [linked_list_allocator::Heap] does internal
// size alignment so we cannot use the size provided by the
// layout.
internal_heap_stats.total_freed += before - self.used();
}
})
#[cfg(feature = "internal-heap-stats")]
{
let mut internal_heap_stats = self.internal_heap_stats.borrow_ref_mut(cs);
drop(regions);
// We need to call `used()` because [linked_list_allocator::Heap] does internal
// size alignment so we cannot use the size provided by the
// layout.
internal_heap_stats.total_freed += before - self.used();
}
})
}
}
}

View File

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

View File

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

View File

@ -1,5 +1,5 @@
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() {
// 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();
#[cfg(target_arch = "riscv32")]
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() {
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"))]
#[no_mangle]
#[link_section = ".rwtext"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".rwtext")]
unsafe fn __user_exception(cause: arch::ExceptionCause, context: arch::Context) {
pre_backtrace();
@ -117,7 +119,7 @@ unsafe fn __user_exception(cause: arch::ExceptionCause, context: arch::Context)
}
#[cfg(all(feature = "exception-handler", target_arch = "riscv32"))]
#[export_name = "ExceptionHandler"]
#[unsafe(export_name = "ExceptionHandler")]
fn exception_handler(context: &arch::TrapFrame) -> ! {
pre_backtrace();
@ -163,7 +165,9 @@ fn exception_handler(context: &arch::TrapFrame) -> ! {
let backtrace = Backtrace::from_sp(context.s0 as u32);
let frames = backtrace.frames();
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() {
println!("0x{:x}", frame.program_counter());
@ -233,7 +237,7 @@ fn halt() -> ! {
cfg_if::cfg_if! {
if #[cfg(feature = "custom-halt")] {
// call custom code
extern "Rust" {
unsafe extern "Rust" {
fn custom_halt() -> !;
}
unsafe { custom_halt() }
@ -285,7 +289,7 @@ fn halt() -> ! {
fn pre_backtrace() {
#[cfg(feature = "custom-pre-backtrace")]
{
extern "Rust" {
unsafe extern "Rust" {
fn custom_pre_backtrace();
}
unsafe { custom_pre_backtrace() }

View File

@ -102,7 +102,10 @@ pub enum ExceptionCause {
impl Display for ExceptionCause {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if *self == Self::Cp0Disabled {
write!(f, "Cp0Disabled (Access to the floating point coprocessor is not allowed. You may want to enable the `float-save-restore` feature of the `xtensa-lx-rt` crate.)")
write!(
f,
"Cp0Disabled (Access to the floating point coprocessor is not allowed. You may want to enable the `float-save-restore` feature of the `xtensa-lx-rt` crate.)"
)
} else {
write!(f, "{:?}", self)
}

View File

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

View File

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

View File

@ -1,7 +1,7 @@
use std::env;
use chrono::{TimeZone, Utc};
use esp_config::{generate_config, ConfigOption, Stability, Validator, Value};
use esp_config::{ConfigOption, Stability, Validator, Value, generate_config};
fn main() {
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
// doesn't like `link-sections` this way
#[cfg(not(target_os = "macos"))]
#[link_section = ".espressif.metadata"]
#[unsafe(link_section = ".espressif.metadata")]
#[used]
#[export_name = "bootloader.NAME"]
#[unsafe(export_name = "bootloader.NAME")]
static OTA_FEATURE: [u8; 7] = *b"ESP-IDF";
/// ESP-IDF compatible application descriptor
@ -305,8 +305,8 @@ macro_rules! esp_app_desc {
$min_efuse_blk_rev_full: expr,
$max_efuse_blk_rev_full: expr
) => {
#[export_name = "esp_app_desc"]
#[link_section = ".rodata_desc.appdesc"]
#[unsafe(export_name = "esp_app_desc")]
#[unsafe(link_section = ".rodata_desc.appdesc")]
pub static ESP_APP_DESC: $crate::EspAppDesc = $crate::EspAppDesc::new_internal(
$version,
$project_name,

View File

@ -6,7 +6,7 @@ impl Crc32 {
}
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;
}

View File

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

View File

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

View File

@ -6,7 +6,7 @@ use std::io::Write as _;
use proc_macro::TokenStream;
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};
/// Print a build error and terminate the process.
@ -113,7 +113,7 @@ pub fn assert_unique_used_features(input: TokenStream) -> TokenStream {
// ----------------------------------------------------------------------------
// 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 unique_cfgs = pairs
.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!(
r#"
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
- `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

View File

@ -1,13 +1,17 @@
[package]
name = "esp-config"
version = "0.3.1"
edition = "2021"
rust-version = "1.84.0"
edition = "2024"
rust-version = "1.85.0"
description = "Configure projects using esp-hal and related packages"
documentation = "https://docs.espressif.com/projects/rust/esp-config/latest/"
repository = "https://github.com/esp-rs/esp-hal"
license = "MIT OR Apache-2.0"
[lib]
bench = false
test = false
[dependencies]
document-features = "0.2.10"
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 super::{snake_case, value::Value, Error};
use super::{Error, snake_case, value::Value};
type CustomValidatorFn = Box<dyn Fn(&Value) -> Result<(), Error>>;

View File

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

View File

@ -9,12 +9,12 @@
mod generate;
#[cfg(feature = "build")]
pub use generate::{
generate_config,
validator::Validator,
value::Value,
ConfigOption,
Error,
Stability,
generate_config,
validator::Validator,
value::Value,
};
/// 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)
- Bump Rust edition to 2024, bump MSRV to 1.85. (#3391)
### Changed
### Fixed

View File

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

View File

@ -1,7 +1,7 @@
use std::{error::Error as StdError, str::FromStr};
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};
fn main() -> Result<(), Box<dyn StdError>> {

View File

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

View File

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

View File

@ -54,7 +54,7 @@ mod fmt;
#[cfg(not(feature = "esp32"))]
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;
#[cfg(feature = "executors")]

View File

@ -8,11 +8,11 @@ use core::cell::Cell;
use embassy_time_driver::Driver;
use esp_hal::{
Blocking,
interrupt::{InterruptHandler, Priority},
sync::Locked,
time::{Duration, Instant},
timer::OneShotTimer,
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
/// highest value possible.
pub(crate) unsafe fn allocate_alarm(&self, priority: Priority) -> Option<AlarmHandle> {
for (i, alarm) in self.alarms.iter().enumerate() {
let handle = alarm.inner.with(|alarm| {
let AlarmState::Created(interrupt_handler) = alarm.state else {
return None;
};
unsafe {
for (i, alarm) in self.alarms.iter().enumerate() {
let handle = alarm.inner.with(|alarm| {
let AlarmState::Created(interrupt_handler) = alarm.state else {
return None;
};
let timer = self.available_timers.with(|available_timers| {
if let Some(timers) = available_timers.take() {
// If the driver is initialized, we can allocate a timer.
// If this fails, we can't do anything about it.
let Some((timer, rest)) = timers.split_first_mut() else {
not_enough_timers();
};
*available_timers = Some(rest);
timer
} else {
panic!("schedule_wake called before esp_hal_embassy::init()")
}
let timer = self.available_timers.with(|available_timers| {
if let Some(timers) = available_timers.take() {
// If the driver is initialized, we can allocate a timer.
// If this fails, we can't do anything about it.
let Some((timer, rest)) = timers.split_first_mut() else {
not_enough_timers();
};
*available_timers = Some(rest);
timer
} else {
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(
timer,
InterruptHandler::new(interrupt_handler, priority),
);
Some(AlarmHandle::new(i))
});
if handle.is_some() {
return handle;
if handle.is_some() {
return handle;
}
}
}
None
None
}
}
/// 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
// extremely long strings. Also, if log is used, this avoids storing the string
// twice.
panic!("There are not enough timers to allocate a new alarm. Call esp_hal_embassy::init() with the correct number of timers, or consider 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 {

View File

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

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- 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

View File

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

View File

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

View File

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

View File

@ -2,9 +2,9 @@ use darling::ast::NestedMeta;
use main_mod::*;
use proc_macro::TokenStream;
use syn::{
Token,
parse::{Parse, ParseBuffer},
punctuated::Punctuated,
Token,
};
pub struct Args {
@ -30,9 +30,9 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
pub mod main_mod {
use std::{cell::RefCell, fmt::Display, thread};
use darling::{export::NestedMeta, FromMeta};
use darling::{FromMeta, export::NestedMeta};
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use quote::{ToTokens, quote};
use syn::{ReturnType, Type};
#[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_crate::{FoundCrate, crate_name};
use proc_macro2::Ident;
use proc_macro_crate::{crate_name, FoundCrate};
use syn::{
parse::Error as SynError,
spanned::Spanned,
AttrStyle,
Attribute,
ItemFn,
ReturnType,
Type,
parse::Error as SynError,
spanned::Spanned,
};
pub enum WhiteListCaller {
@ -40,18 +40,20 @@ pub fn handler(args: TokenStream, input: TokenStream) -> TokenStream {
};
let root = Ident::new(
if let Ok(FoundCrate::Name(ref name)) = crate_name("esp-hal") {
name
} else {
"crate"
match crate_name("esp-hal") {
Ok(FoundCrate::Name(ref name)) => name,
_ => "crate",
},
Span::call_site().into(),
);
let priority = if let Some(priority) = args.priority {
quote::quote!( #priority )
} else {
quote::quote! { #root::interrupt::Priority::min() }
let priority = match args.priority {
Some(priority) => {
quote::quote!( #priority )
}
_ => {
quote::quote! { #root::interrupt::Priority::min() }
}
};
// 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"))]
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::{Ident, Span};
use proc_macro_crate::{crate_name, FoundCrate};
use quote::format_ident;
use syn::{
parse::Error,
parse_macro_input,
spanned::Spanned,
FnArg,
GenericArgument,
ItemFn,
PatType,
PathArguments,
Type,
parse::Error,
parse_macro_input,
spanned::Spanned,
};
pub(crate) fn make_magic_symbol_name(args: &Vec<&PatType>) -> String {
@ -181,9 +181,9 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
quote!(
#[allow(non_snake_case)]
#[export_name = "main"]
#[unsafe(export_name = "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];
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 parse::Error;
use proc_macro::Span;
use proc_macro_crate::{crate_name, FoundCrate};
use syn::{parse, Ident};
use proc_macro_crate::{FoundCrate, crate_name};
use syn::{Ident, parse};
let hal_crate = if cfg!(any(feature = "is-lp-core", feature = "is-ulp-core")) {
crate_name("esp-lp-hal")
@ -349,7 +349,7 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream {
static LP_CODE: &[u8] = &[#(#binary),*];
extern "C" {
unsafe extern "C" {
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_macro2::Ident;
use proc_macro_error2::abort;
use syn::{parse, Item};
use proc_macro2::Ident;
use syn::{Item, parse};
#[derive(Debug, Default, darling::FromMeta)]
#[darling(default)]
@ -64,11 +64,11 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
let section = match (is_fn, section_name) {
(true, Ok(section_name)) => quote::quote! {
#[link_section = #section_name]
#[unsafe(link_section = #section_name)]
#[inline(never)] // make certain function is not inlined
},
(false, Ok(section_name)) => quote::quote! {
#[link_section = #section_name]
#[unsafe(link_section = #section_name)]
},
(_, Err(_)) => {
abort!(Span::call_site(), "Invalid combination of ram arguments");
@ -83,13 +83,12 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream {
None
};
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(
if let Ok(FoundCrate::Name(ref name)) = crate_name("esp-hal") {
name
} else {
"crate"
match crate_name("esp-hal") {
Ok(FoundCrate::Name(ref name)) => name,
_ => "crate",
},
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)
- Add DMA memcpy support to the S2 (#3352)
- 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

View File

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

View File

@ -9,7 +9,7 @@ use std::{
};
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};
fn main() -> Result<(), Box<dyn Error>> {
@ -139,8 +139,7 @@ fn main() -> Result<(), Box<dyn Error>> {
},
ConfigOption {
name: "flip-link",
description:
"Move the stack to start of RAM to get zero-cost stack overflow protection.",
description: "Move the stack to start of RAM to get zero-cost stack overflow protection.",
default_value: Value::Bool(false),
constraint: None,
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<'_> {
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<'_> {
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<'_> {
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<'_> {
pub(super) fn init(&mut self) {

View File

@ -108,10 +108,10 @@ impl Key {
/// Returns a slice representation of the AES key.
fn as_slice(&self) -> &[u8] {
match self {
Key::Key16(ref key) => key,
Key::Key16(key) => key,
#[cfg(any(esp32, esp32s2))]
Key::Key24(ref key) => key,
Key::Key32(ref key) => key,
Key::Key24(key) => key,
Key::Key32(key) => key,
}
}
}
@ -235,6 +235,7 @@ pub mod dma {
use core::mem::ManuallyDrop;
use crate::{
Blocking,
aes::{Key, Mode},
dma::{
Channel,
@ -245,7 +246,6 @@ pub mod dma {
PeripheralDmaChannel,
},
peripherals::AES,
Blocking,
};
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))]
use crate::efuse::Efuse;
use crate::{
analog::adc::asynch::AdcFuture,
interrupt::{InterruptConfigurable, InterruptHandler},
peripherals::{Interrupt, APB_SARADC},
soc::regi2c,
system::{GenericPeripheralGuard, Peripheral},
Async,
Blocking,
analog::adc::asynch::AdcFuture,
interrupt::{InterruptConfigurable, InterruptHandler},
peripherals::{APB_SARADC, Interrupt},
soc::regi2c,
system::{GenericPeripheralGuard, Peripheral},
};
mod calibration;
@ -573,7 +573,7 @@ pub(crate) mod asynch {
use portable_atomic::{AtomicU32, Ordering};
use procmacros::handler;
use crate::{asynch::AtomicWaker, peripherals::APB_SARADC, Async};
use crate::{Async, asynch::AtomicWaker, peripherals::APB_SARADC};
#[cfg(all(adc1, adc2))]
static ASYNC_ADC_COUNT: AtomicU32 = AtomicU32::new(0);

View File

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

View File

@ -221,11 +221,7 @@ fn regi2c_enable_block(block: u8) -> usize {
}
});
if i2c_sel {
0
} else {
1
}
if i2c_sel { 0 } else { 1 }
}
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 {
if a > b {
a
} else {
b
}
if a > b { a } else { b }
}
impl BurstConfig {

View File

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

View File

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

View File

@ -61,14 +61,14 @@ pub use self::m2m::*;
#[cfg(pdma)]
pub use self::pdma::*;
use crate::{
Async,
Blocking,
DriverMode,
interrupt::InterruptHandler,
peripherals::Interrupt,
soc::{is_slice_in_dram, is_valid_memory_address, is_valid_ram_address},
system,
system::Cpu,
Async,
Blocking,
DriverMode,
};
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_rules! dma_buffers_chunk_size {
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{
$crate::dma_buffers_impl!($rx_size, $tx_size, $chunk_size, is_circular = false)
}};
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ $crate::dma_buffers_impl!($rx_size, $tx_size, $chunk_size, is_circular = false) }};
($size:expr, $chunk_size:expr) => {
$crate::dma_buffers_chunk_size!($size, $size, $chunk_size)
@ -605,13 +603,9 @@ macro_rules! dma_buffers_chunk_size {
/// ```
#[macro_export]
macro_rules! dma_circular_buffers_chunk_size {
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{
$crate::dma_buffers_impl!($rx_size, $tx_size, $chunk_size, is_circular = true)
}};
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ $crate::dma_buffers_impl!($rx_size, $tx_size, $chunk_size, is_circular = true) }};
($size:expr, $chunk_size:expr) => {{
$crate::dma_circular_buffers_chunk_size!($size, $size, $chunk_size)
}};
($size:expr, $chunk_size:expr) => {{ $crate::dma_circular_buffers_chunk_size!($size, $size, $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_rules! dma_descriptors_chunk_size {
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{
$crate::dma_descriptors_impl!($rx_size, $tx_size, $chunk_size, is_circular = false)
}};
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ $crate::dma_descriptors_impl!($rx_size, $tx_size, $chunk_size, is_circular = false) }};
($size:expr, $chunk_size:expr) => {
$crate::dma_descriptors_chunk_size!($size, $size, $chunk_size)
@ -656,9 +648,7 @@ macro_rules! dma_descriptors_chunk_size {
/// ```
#[macro_export]
macro_rules! dma_circular_descriptors_chunk_size {
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{
$crate::dma_descriptors_impl!($rx_size, $tx_size, $chunk_size, is_circular = true)
}};
($rx_size:expr, $tx_size:expr, $chunk_size:expr) => {{ $crate::dma_descriptors_impl!($rx_size, $tx_size, $chunk_size, is_circular = true) }};
($size:expr, $chunk_size:expr) => {
$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.
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;
self.descriptors.iter_mut().take_while(move |d| {
if was_last {
@ -1916,7 +1906,7 @@ where
for des in chain.descriptors.iter() {
// we are forcing the DMA alignment to the cache line size
// 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()) {
uses_psram = true;
// both the size and address of the buffer must be aligned
@ -1926,7 +1916,7 @@ where
if des.size() % alignment != 0 {
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() {
// we are forcing the DMA alignment to the cache line size
// 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()) {
uses_psram = true;
// both the size and address of the buffer must be aligned
@ -2192,7 +2182,7 @@ where
if des.size() % alignment != 0 {
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(),
check_owner: Some(false),
// 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)?;

View File

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

View File

@ -4,7 +4,7 @@ use crate::{
asynch::AtomicWaker,
dma::*,
interrupt::Priority,
peripherals::{Interrupt, DMA_CRYPTO},
peripherals::{DMA_CRYPTO, Interrupt},
};
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 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 DmaTxChannel>](Self::steal().into()),
)
}
}}
}
impl DmaChannelExt for $instance<'_> {

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
use crate::{
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,
};

View File

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

View File

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

View File

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

View File

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

View File

@ -12,8 +12,8 @@
//! interrupt15() => Priority::Priority15
//! ```
pub(crate) use esp_riscv_rt::riscv::interrupt::free;
pub use esp_riscv_rt::TrapFrame;
pub(crate) use esp_riscv_rt::riscv::interrupt::free;
use riscv::register::{mcause, mtvec};
#[cfg(not(plic))]
@ -24,7 +24,7 @@ pub use self::vectored::*;
use super::InterruptStatus;
use crate::{
pac,
peripherals::{Interrupt, INTERRUPT_CORE0},
peripherals::{INTERRUPT_CORE0, Interrupt},
system::Cpu,
};
@ -204,30 +204,32 @@ impl TryFrom<u8> for Priority {
}
/// 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;
/// # Safety
///
/// This function is called from an assembly trap handler.
#[doc(hidden)]
#[link_section = ".trap.rust"]
#[export_name = "_start_trap_rust_hal"]
#[unsafe(link_section = ".trap.rust")]
#[unsafe(export_name = "_start_trap_rust_hal")]
pub unsafe extern "C" fn start_trap_rust_hal(trap_frame: *mut TrapFrame) {
assert!(
mcause::read().is_exception(),
"Arrived into _start_trap_rust_hal but mcause is not an exception!"
);
extern "C" {
unsafe extern "C" {
fn ExceptionHandler(tf: *mut TrapFrame);
}
ExceptionHandler(trap_frame);
unsafe {
ExceptionHandler(trap_frame);
}
}
#[doc(hidden)]
#[no_mangle]
#[unsafe(no_mangle)]
pub fn _setup_interrupts() {
extern "C" {
unsafe extern "C" {
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,
};
intr_map_base
.offset(interrupt_number)
.write_volatile(cpu_interrupt_number as u32 + EXTERNAL_INTERRUPT_OFFSET);
unsafe {
intr_map_base
.offset(interrupt_number)
.write_volatile(cpu_interrupt_number as u32 + EXTERNAL_INTERRUPT_OFFSET);
}
}
/// 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 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 {
Some(core::mem::transmute::<u32, CpuInterrupt>(
cpu_intr - EXTERNAL_INTERRUPT_OFFSET,
))
Some(unsafe {
core::mem::transmute::<u32, CpuInterrupt>(cpu_intr - EXTERNAL_INTERRUPT_OFFSET)
})
} else {
None
}
@ -372,17 +376,19 @@ mod vectored {
#[doc(hidden)]
pub(crate) unsafe fn init_vectoring() {
for (prio, num) in PRIORITY_TO_INTERRUPT.iter().enumerate() {
set_kind(
Cpu::current(),
core::mem::transmute::<u32, CpuInterrupt>(*num as u32),
InterruptKind::Level,
);
set_priority(
Cpu::current(),
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));
unsafe {
set_kind(
Cpu::current(),
core::mem::transmute::<u32, CpuInterrupt>(*num as u32),
InterruptKind::Level,
);
set_priority(
Cpu::current(),
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));
}
}
}
@ -437,9 +443,11 @@ mod vectored {
///
/// This will replace any previously bound interrupt handler
pub unsafe fn bind_interrupt(interrupt: Interrupt, handler: unsafe extern "C" fn()) {
let ptr = &pac::__EXTERNAL_INTERRUPTS[interrupt as usize]._handler as *const _
as *mut unsafe extern "C" fn();
ptr.write_volatile(handler);
unsafe {
let ptr = &pac::__EXTERNAL_INTERRUPTS[interrupt as usize]._handler as *const _
as *mut unsafe extern "C" fn();
ptr.write_volatile(handler);
}
}
/// Returns the currently bound interrupt handler.
@ -454,7 +462,7 @@ mod vectored {
}
}
#[no_mangle]
#[unsafe(no_mangle)]
#[ram]
unsafe fn handle_interrupts(cpu_intr: CpuInterrupt, context: &mut TrapFrame) {
let core = Cpu::current();
@ -471,27 +479,30 @@ mod vectored {
for interrupt_nr in configured_interrupts.iterator() {
// Don't use `Interrupt::try_from`. It's slower and placed in flash
let interrupt: Interrupt = unsafe { core::mem::transmute(interrupt_nr as u16) };
handle_interrupt(interrupt, context);
unsafe {
handle_interrupt(interrupt, context);
}
}
}
#[inline(always)]
unsafe fn handle_interrupt(interrupt: Interrupt, save_frame: &mut TrapFrame) {
extern "C" {
unsafe extern "C" {
// defined in each hal
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(
handler as *const _,
EspDefaultHandler as *const unsafe extern "C" fn(),
) {
EspDefaultHandler(interrupt);
unsafe { EspDefaultHandler(interrupt) };
} else {
let handler: fn(&mut TrapFrame) =
core::mem::transmute::<unsafe extern "C" fn(), fn(&mut TrapFrame)>(handler);
let handler: fn(&mut TrapFrame) = unsafe {
core::mem::transmute::<unsafe extern "C" fn(), fn(&mut TrapFrame)>(handler)
};
handler(save_frame);
}
}
@ -571,18 +582,18 @@ mod classic {
use super::{CpuInterrupt, InterruptKind, Priority};
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;
#[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;
#[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] =
&[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.
#[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] =
[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 intr = INTERRUPT_CORE0::regs();
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
@ -629,7 +640,7 @@ mod classic {
pub unsafe fn set_priority(_core: Cpu, which: CpuInterrupt, priority: Priority) {
let intr = INTERRUPT_CORE0::regs();
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
@ -653,41 +664,43 @@ mod classic {
#[inline]
pub(super) unsafe extern "C" fn priority(cpu_interrupt: CpuInterrupt) -> Priority {
let intr = INTERRUPT_CORE0::regs();
core::mem::transmute::<u8, Priority>(
intr.cpu_int_pri(cpu_interrupt as usize).read().map().bits(),
)
unsafe {
core::mem::transmute::<u8, Priority>(
intr.cpu_int_pri(cpu_interrupt as usize).read().map().bits(),
)
}
}
#[no_mangle]
#[link_section = ".trap"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".trap")]
pub(super) unsafe extern "C" fn _handle_priority() -> u32 {
use super::mcause;
// Both C6 and H2 have 5 bits of code. The riscv crate masks 31 bits, which then
// causes a bounds check to be present.
let interrupt_id: usize = mcause::read().bits() & 0x1f;
let intr = INTERRUPT_CORE0::regs();
let interrupt_priority = intr
.cpu_int_pri(0)
.as_ptr()
.add(interrupt_id)
.read_volatile();
let interrupt_priority = unsafe {
intr.cpu_int_pri(0)
.as_ptr()
.add(interrupt_id)
.read_volatile()
};
let prev_interrupt_priority = intr.cpu_int_thresh().read().bits();
if interrupt_priority < 15 {
// leave interrupts disabled if interrupt is of max priority.
intr.cpu_int_thresh()
.write(|w| w.bits(interrupt_priority + 1)); // set the prio threshold to 1 more than current interrupt prio
unsafe {
riscv::interrupt::enable();
}
.write(|w| unsafe { w.bits(interrupt_priority + 1) }); // set the prio threshold to 1 more than current interrupt prio
unsafe { riscv::interrupt::enable() };
}
prev_interrupt_priority
}
#[no_mangle]
#[link_section = ".trap"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".trap")]
pub(super) unsafe extern "C" fn _restore_priority(stored_prio: u32) {
riscv::interrupt::disable();
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).
@ -713,7 +726,7 @@ mod classic {
// interrupts at `level` so we set the threshold to `level + 1`.
INTERRUPT_CORE0::regs()
.cpu_int_thresh()
.write(|w| w.bits(level as u32 + 1));
.write(|w| unsafe { w.bits(level as u32 + 1) });
prev_interrupt_priority
}
@ -724,21 +737,21 @@ mod plic {
use super::{CpuInterrupt, InterruptKind, Priority};
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;
#[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;
// 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
// 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] =
&[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.
#[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] = [
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()
.cpu_mxint_pri()
.bits();
core::mem::transmute::<u8, Priority>(prio)
unsafe { core::mem::transmute::<u8, Priority>(prio) }
}
#[no_mangle]
#[link_section = ".trap"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".trap")]
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_priority = PLIC_MX::regs()
@ -841,20 +854,21 @@ mod plic {
// leave interrupts disabled if interrupt is of max priority.
PLIC_MX::regs()
.mxint_thresh()
.write(|w| w.cpu_mxint_thresh().bits(interrupt_priority + 1));
.write(|w| unsafe { w.cpu_mxint_thresh().bits(interrupt_priority + 1) });
unsafe {
riscv::interrupt::enable();
}
}
prev_interrupt_priority as u32
}
#[no_mangle]
#[link_section = ".trap"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".trap")]
pub(super) unsafe extern "C" fn _restore_priority(stored_prio: u32) {
riscv::interrupt::disable();
PLIC_MX::regs()
.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).
@ -884,7 +898,7 @@ mod plic {
// interrupts at `level` so we set the threshold to `level + 1`.
PLIC_MX::regs()
.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
}

View File

@ -119,7 +119,7 @@ impl CpuInterrupt {
}
/// 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] = &[
CpuInterrupt::Interrupt1LevelPriority1 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) {
let interrupt_number = interrupt as isize;
let cpu_interrupt_number = which as isize;
let intr_map_base = match core {
Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_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)
.write_volatile(cpu_interrupt_number as u32);
unsafe {
let intr_map_base = match core {
Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_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)
.write_volatile(cpu_interrupt_number as u32);
}
}
/// Get cpu interrupt assigned to peripheral interrupt
@ -350,12 +352,14 @@ pub(crate) fn current_runlevel() -> Priority {
/// runlevel.
pub(crate) unsafe fn change_current_runlevel(level: Priority) -> Priority {
let token: u32;
match level {
Priority::None => core::arch::asm!("rsil {0}, 0", out(reg) token),
Priority::Priority1 => core::arch::asm!("rsil {0}, 1", 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),
};
unsafe {
match level {
Priority::None => core::arch::asm!("rsil {0}, 0", out(reg) token),
Priority::Priority1 => core::arch::asm!("rsil {0}, 1", 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;
@ -511,9 +515,13 @@ mod vectored {
///
/// This will replace any previously bound interrupt handler
pub unsafe fn bind_interrupt(interrupt: Interrupt, handler: unsafe extern "C" fn()) {
let ptr = &pac::__INTERRUPTS[interrupt as usize]._handler as *const _
as *mut unsafe extern "C" fn();
ptr.write_volatile(handler);
let ptr = unsafe {
&pac::__INTERRUPTS[interrupt as usize]._handler as *const _
as *mut unsafe extern "C" fn()
};
unsafe {
ptr.write_volatile(handler);
}
}
/// Returns the currently bound interrupt handler.
@ -523,7 +531,6 @@ mod vectored {
if addr as usize == 0 {
return None;
}
Some(addr)
}
}
@ -550,7 +557,7 @@ mod vectored {
}
// 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] = [
0b_0000_0000_0000_0000_0000_0000_0000_0000, // Dummy level 0
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_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;
#[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;
#[inline]
@ -584,22 +591,28 @@ mod vectored {
})
}
#[no_mangle]
#[unsafe(no_mangle)]
#[ram]
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]
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]
unsafe fn __level_3_interrupt(save_frame: &mut Context) {
handle_interrupts::<3>(save_frame);
unsafe {
handle_interrupts::<3>(save_frame);
}
}
#[inline(always)]
@ -622,11 +635,13 @@ mod vectored {
// If the interrupt is edge triggered, we need to clear the request on the CPU's
// side.
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) {
handler(save_frame);
unsafe { handler(save_frame) };
}
} else {
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
// 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
// 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
let interrupt: Interrupt = unsafe { core::mem::transmute(interrupt_nr as u16) };
extern "C" {
unsafe extern "C" {
// defined in each hal
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(
handler as *const _,
EspDefaultHandler as *const unsafe extern "C" fn(),
) {
EspDefaultHandler(interrupt);
unsafe { EspDefaultHandler(interrupt) };
} else {
let handler: fn(&mut Context) =
core::mem::transmute::<unsafe extern "C" fn(), fn(&mut Context)>(handler);
let handler: fn(&mut Context) = unsafe {
core::mem::transmute::<unsafe extern "C" fn(), fn(&mut Context)>(handler)
};
handler(save_frame);
}
}
@ -674,7 +690,7 @@ mod vectored {
#[cfg(esp32)]
mod chip_specific {
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(
0b0000_0000_0000_0000_0000_0000_0000_0000,
0b1111_1100_0000_0000_0000_0000_0000_0000,
@ -699,7 +715,7 @@ mod vectored {
#[cfg(esp32s2)]
mod chip_specific {
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(
0b0000_0000_0000_0000_0000_0000_0000_0000,
0b1100_0000_0000_0000_0000_0000_0000_0000,
@ -727,7 +743,7 @@ mod vectored {
#[cfg(esp32s3)]
mod chip_specific {
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();
#[inline]
pub fn interrupt_is_edge(_interrupt: Interrupt) -> bool {
@ -739,34 +755,34 @@ mod vectored {
mod raw {
use super::*;
extern "C" {
unsafe extern "C" {
fn level4_interrupt(save_frame: &mut Context);
fn level5_interrupt(save_frame: &mut Context);
fn level6_interrupt(save_frame: &mut Context);
fn level7_interrupt(save_frame: &mut Context);
}
#[no_mangle]
#[link_section = ".rwtext"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".rwtext")]
unsafe fn __level_4_interrupt(save_frame: &mut Context) {
level4_interrupt(save_frame)
unsafe { level4_interrupt(save_frame) }
}
#[no_mangle]
#[link_section = ".rwtext"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".rwtext")]
unsafe fn __level_5_interrupt(save_frame: &mut Context) {
level5_interrupt(save_frame)
unsafe { level5_interrupt(save_frame) }
}
#[no_mangle]
#[link_section = ".rwtext"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".rwtext")]
unsafe fn __level_6_interrupt(save_frame: &mut Context) {
level6_interrupt(save_frame)
unsafe { level6_interrupt(save_frame) }
}
#[no_mangle]
#[link_section = ".rwtext"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".rwtext")]
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::{
Blocking,
clock::Clocks,
dma::{ChannelRx, DmaError, DmaPeripheral, DmaRxBuffer, PeripheralRxChannel, RxChannelFor},
gpio::{
interconnect::{PeripheralInput, PeripheralOutput},
InputSignal,
OutputSignal,
Pull,
interconnect::{PeripheralInput, PeripheralOutput},
},
lcd_cam::{calculate_clkm, BitOrder, ByteOrder, ClockError},
lcd_cam::{BitOrder, ByteOrder, ClockError, calculate_clkm},
pac,
peripherals::LCD_CAM,
system::{self, GenericPeripheralGuard},
time::Rate,
Blocking,
};
/// Generation of GDMA SUC EOF

View File

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

View File

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

View File

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

View File

@ -12,8 +12,8 @@
use super::timer::{TimerIFace, TimerSpeed};
use crate::{
gpio::{
interconnect::{OutputConnection, PeripheralOutput},
OutputSignal,
interconnect::{OutputConnection, PeripheralOutput},
},
pac::ledc::RegisterBlock,
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);
unsafe impl<T: Persistable, const N: usize> Persistable for [T; N] {}
@ -500,14 +502,14 @@ pub mod __macro_implementation {
}
#[cfg(riscv)]
#[export_name = "hal_main"]
#[unsafe(export_name = "hal_main")]
fn hal_main(a0: usize, a1: usize, a2: usize) -> ! {
extern "Rust" {
unsafe extern "Rust" {
// This symbol will be provided by the user via `#[entry]`
fn main(a0: usize, a1: usize, a2: usize) -> !;
}
extern "C" {
unsafe extern "C" {
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() {
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.
#[inline]
pub unsafe fn clone_unchecked(&self) -> Self {
pub unsafe fn clone_unchecked(&self) -> Self { unsafe {
match &self.0 {
$(
$(#[cfg($variant_meta)])*
[< $name Inner >]::$variant(inner) => $name([<$name Inner>]::$variant(inner.clone_unchecked())),
)*
}
}
}}
/// Creates a new peripheral reference with a shorter lifetime.
///
@ -244,9 +244,9 @@ macro_rules! ignore {
#[doc(hidden)]
macro_rules! metadata {
($category:literal, $key:ident, $value:expr) => {
#[link_section = concat!(".espressif.metadata")]
#[unsafe(link_section = concat!(".espressif.metadata"))]
#[used]
#[export_name = concat!($category, ".", stringify!($key))]
#[unsafe(export_name = concat!($category, ".", stringify!($key)))]
static $key: [u8; $value.len()] = const {
let val_bytes = $value.as_bytes();
let mut val_bytes_array = [0; $value.len()];

View File

@ -14,7 +14,7 @@ use core::marker::PhantomData;
use super::PeripheralGuard;
use crate::{
gpio::interconnect::{OutputConnection, PeripheralOutput},
mcpwm::{timer::Timer, PwmPeripheral},
mcpwm::{PwmPeripheral, timer::Timer},
pac,
};
@ -320,7 +320,8 @@ impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP,
// SAFETY:
// `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

View File

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

View File

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

View File

@ -74,7 +74,7 @@ macro_rules! peripherals {
/// Returns all the peripherals *once*
#[inline]
pub(crate) fn take() -> Self {
#[no_mangle]
#[unsafe(no_mangle)]
static mut _ESP_HAL_DEVICE_PERIPHERALS: bool = false;
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.
#[inline]
pub unsafe fn steal() -> Self {
Self {
$(
$name: $name::steal(),
)*
$(
$unstable_name: $unstable_name::steal(),
)*
unsafe {
Self {
$(
$name: $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.
#[inline]
#[allow(dead_code)]
pub unsafe fn clone_unchecked(&self) -> Self {
pub unsafe fn clone_unchecked(&self) -> Self { unsafe {
Self::steal()
}
}}
/// Creates a new peripheral reference with a shorter lifetime.
///

View File

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

View File

@ -198,10 +198,10 @@ impl<'d> Trng<'d> {
///
/// Returns a new `Trng` instance.
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();
Self {
rng: gen,
rng: r#gen,
_adc: adc,
}
}

View File

@ -100,7 +100,7 @@
#[cfg(rom_crc_be)]
#[inline(always)]
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;
}
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)]
#[inline(always)]
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;
}
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)]
#[inline(always)]
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;
}
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)]
#[inline(always)]
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;
}
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)]
#[inline(always)]
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;
}
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)]
#[cfg(rom_crc_le)]
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;
}
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)]
extern "C" {
unsafe extern "C" {
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_final(digest: *mut u8, context: *mut InternalContext);
@ -94,7 +94,7 @@ struct InternalContext {
}
#[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_update_ret(
context: *mut InternalContext,

View File

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

View File

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

View File

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

View File

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

View File

@ -24,12 +24,12 @@
use core::{marker::PhantomData, ptr::copy_nonoverlapping};
use crate::{
Async,
Blocking,
interrupt::InterruptHandler,
pac,
peripherals::{Interrupt, RSA},
system::{Cpu, GenericPeripheralGuard, Peripheral as PeripheralEnable},
Async,
Blocking,
};
#[cfg_attr(esp32s2, path = "esp32sX.rs")]
@ -386,6 +386,7 @@ pub(crate) mod asynch {
use procmacros::handler;
use crate::{
Async,
asynch::AtomicWaker,
peripherals::RSA,
rsa::{
@ -396,7 +397,6 @@ pub(crate) mod asynch {
RsaModularMultiplication,
RsaMultiplication,
},
Async,
};
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
// 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 {
let xtal = RtcClock::xtal_freq();
xtal.mhz() as i32

View File

@ -6,6 +6,8 @@ use strum::FromRepr;
use crate::{
clock::{
Clock,
XtalClock,
clocks_ll::{
esp32c6_bbpll_get_freq_mhz,
esp32c6_cpu_get_hs_divider,
@ -15,8 +17,6 @@ use crate::{
esp32c6_rtc_update_to_8m,
esp32c6_rtc_update_to_xtal_raw,
},
Clock,
XtalClock,
},
peripherals::TIMG0,
rtc_cntl::RtcClock,
@ -25,27 +25,27 @@ use crate::{
};
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 {
&*esp32c6::MODEM_LPCON::ptr()
unsafe { &*esp32c6::MODEM_LPCON::ptr() }
}
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 {
&*esp32c6::LP_CLKRST::ptr()
unsafe { &*esp32c6::LP_CLKRST::ptr() }
}
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 {
&*esp32c6::LP_AON::ptr()
unsafe { &*esp32c6::LP_AON::ptr() }
}
fn pmu_power_domain_force_default() {

View File

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

View File

@ -2,7 +2,7 @@ use super::{Ext0WakeupSource, Ext1WakeupSource, TimerWakeupSource, WakeSource, W
use crate::{
gpio::{RtcFunction, RtcPin},
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,

View File

@ -2,7 +2,7 @@ use super::{TimerWakeupSource, WakeSource, WakeTriggers, WakeupLevel};
use crate::{
gpio::{RtcFunction, RtcPinWithResistors},
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,
};

View File

@ -2,7 +2,7 @@ use super::{TimerWakeupSource, WakeSource, WakeTriggers, WakeupLevel};
use crate::{
gpio::{RtcFunction, RtcPinWithResistors},
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,
};

View File

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

View File

@ -9,7 +9,7 @@ use super::{
use crate::{
gpio::{RtcFunction, RtcPin},
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,
};

View File

@ -9,7 +9,7 @@ use super::{
use crate::{
gpio::{RtcFunction, RtcPin},
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,
};

View File

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

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