mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 12:20:56 +00:00
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:
parent
df6aa9c18f
commit
b33b877592
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 }
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 }
|
||||||
|
@ -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:
|
||||||
|
@ -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() }
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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") {
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 }
|
||||||
|
@ -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>>;
|
||||||
|
|
||||||
|
@ -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(_) => {
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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 }
|
||||||
|
@ -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>> {
|
||||||
|
@ -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};
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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")]
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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 {
|
||||||
|
@ -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] = &[
|
||||||
|
@ -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)]
|
||||||
|
@ -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?
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(),
|
||||||
);
|
);
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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>();
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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::{
|
||||||
|
@ -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)?;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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<'_> {
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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},
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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! {
|
||||||
|
@ -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> {
|
||||||
|
@ -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)]
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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()];
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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.
|
||||||
///
|
///
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) }
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
@ -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),
|
||||||
|
@ -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),
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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! {
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user