mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 06:42:32 +00:00
Merge branch 'embassy-rs:main' into barafael/minor_clippy_lints_rp
This commit is contained in:
commit
cf789be420
1
ci.sh
1
ci.sh
@ -124,6 +124,7 @@ cargo batch \
|
|||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h725re,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h725re,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7b3ai,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7b3ai,defmt,exti,time-driver-any,time \
|
||||||
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h7b3ai,defmt,exti,time-driver-tim1,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l431cb,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l431cb,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \
|
||||||
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l422cb,defmt,exti,time-driver-any,time \
|
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l422cb,defmt,exti,time-driver-any,time \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -183,29 +183,29 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S
|
|||||||
/// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
/// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
||||||
/// |-----------|------------|--------|--------|--------|--------|
|
/// |-----------|------------|--------|--------|--------|--------|
|
||||||
/// | Active | 0 | 1 | 2 | 3 | - |
|
/// | Active | 0 | 1 | 2 | 3 | - |
|
||||||
/// | DFU | 0 | 3 | 2 | 1 | X |
|
/// | DFU | 0 | 4 | 5 | 6 | X |
|
||||||
///
|
///
|
||||||
/// The algorithm starts by copying 'backwards', and after the first step, the layout is
|
/// The algorithm starts by copying 'backwards', and after the first step, the layout is
|
||||||
/// as follows:
|
/// as follows:
|
||||||
///
|
///
|
||||||
/// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
/// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
||||||
/// |-----------|------------|--------|--------|--------|--------|
|
/// |-----------|------------|--------|--------|--------|--------|
|
||||||
/// | Active | 1 | 1 | 2 | 1 | - |
|
/// | Active | 1 | 1 | 2 | 6 | - |
|
||||||
/// | DFU | 1 | 3 | 2 | 1 | 3 |
|
/// | DFU | 1 | 4 | 5 | 6 | 3 |
|
||||||
///
|
///
|
||||||
/// The next iteration performs the same steps
|
/// The next iteration performs the same steps
|
||||||
///
|
///
|
||||||
/// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
/// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
||||||
/// |-----------|------------|--------|--------|--------|--------|
|
/// |-----------|------------|--------|--------|--------|--------|
|
||||||
/// | Active | 2 | 1 | 2 | 1 | - |
|
/// | Active | 2 | 1 | 5 | 6 | - |
|
||||||
/// | DFU | 2 | 3 | 2 | 2 | 3 |
|
/// | DFU | 2 | 4 | 5 | 2 | 3 |
|
||||||
///
|
///
|
||||||
/// And again until we're done
|
/// And again until we're done
|
||||||
///
|
///
|
||||||
/// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
/// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
||||||
/// |-----------|------------|--------|--------|--------|--------|
|
/// |-----------|------------|--------|--------|--------|--------|
|
||||||
/// | Active | 3 | 3 | 2 | 1 | - |
|
/// | Active | 3 | 4 | 5 | 6 | - |
|
||||||
/// | DFU | 3 | 3 | 1 | 2 | 3 |
|
/// | DFU | 3 | 4 | 1 | 2 | 3 |
|
||||||
///
|
///
|
||||||
/// ## REVERTING
|
/// ## REVERTING
|
||||||
///
|
///
|
||||||
@ -220,19 +220,19 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S
|
|||||||
///
|
///
|
||||||
/// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
/// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
||||||
/// |-----------|--------------|--------|--------|--------|--------|
|
/// |-----------|--------------|--------|--------|--------|--------|
|
||||||
/// | Active | 3 | 1 | 2 | 1 | - |
|
/// | Active | 3 | 1 | 5 | 6 | - |
|
||||||
/// | DFU | 3 | 3 | 1 | 2 | 3 |
|
/// | DFU | 3 | 4 | 1 | 2 | 3 |
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
/// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
||||||
/// |-----------|--------------|--------|--------|--------|--------|
|
/// |-----------|--------------|--------|--------|--------|--------|
|
||||||
/// | Active | 3 | 1 | 2 | 1 | - |
|
/// | Active | 3 | 1 | 2 | 6 | - |
|
||||||
/// | DFU | 3 | 3 | 2 | 2 | 3 |
|
/// | DFU | 3 | 4 | 5 | 2 | 3 |
|
||||||
///
|
///
|
||||||
/// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
/// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|
||||||
/// |-----------|--------------|--------|--------|--------|--------|
|
/// |-----------|--------------|--------|--------|--------|--------|
|
||||||
/// | Active | 3 | 1 | 2 | 3 | - |
|
/// | Active | 3 | 1 | 2 | 3 | - |
|
||||||
/// | DFU | 3 | 3 | 2 | 1 | 3 |
|
/// | DFU | 3 | 4 | 5 | 6 | 3 |
|
||||||
///
|
///
|
||||||
pub fn prepare_boot(&mut self, aligned_buf: &mut [u8]) -> Result<State, BootError> {
|
pub fn prepare_boot(&mut self, aligned_buf: &mut [u8]) -> Result<State, BootError> {
|
||||||
// Ensure we have enough progress pages to store copy progress
|
// Ensure we have enough progress pages to store copy progress
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -106,6 +106,11 @@ impl<'a, M: RawMutex, BUS: SetConfig> I2cDeviceWithConfig<'a, M, BUS> {
|
|||||||
pub fn new(bus: &'a Mutex<M, BUS>, config: BUS::Config) -> Self {
|
pub fn new(bus: &'a Mutex<M, BUS>, config: BUS::Config) -> Self {
|
||||||
Self { bus, config }
|
Self { bus, config }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the device's config at runtime
|
||||||
|
pub fn set_config(&mut self, config: BUS::Config) {
|
||||||
|
self.config = config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, BUS> i2c::ErrorType for I2cDeviceWithConfig<'a, M, BUS>
|
impl<'a, M, BUS> i2c::ErrorType for I2cDeviceWithConfig<'a, M, BUS>
|
||||||
|
@ -122,6 +122,11 @@ impl<'a, M: RawMutex, BUS: SetConfig, CS> SpiDeviceWithConfig<'a, M, BUS, CS> {
|
|||||||
pub fn new(bus: &'a Mutex<M, BUS>, cs: CS, config: BUS::Config) -> Self {
|
pub fn new(bus: &'a Mutex<M, BUS>, cs: CS, config: BUS::Config) -> Self {
|
||||||
Self { bus, cs, config }
|
Self { bus, cs, config }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the device's config at runtime
|
||||||
|
pub fn set_config(&mut self, config: BUS::Config) {
|
||||||
|
self.config = config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, BUS, CS> spi::ErrorType for SpiDeviceWithConfig<'a, M, BUS, CS>
|
impl<'a, M, BUS, CS> spi::ErrorType for SpiDeviceWithConfig<'a, M, BUS, CS>
|
||||||
|
@ -67,9 +67,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> {
|
fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> {
|
||||||
let _ = address;
|
self.bus.lock(|bus| {
|
||||||
let _ = operations;
|
bus.borrow_mut()
|
||||||
todo!()
|
.transaction(address, operations)
|
||||||
|
.map_err(I2cDeviceError::I2c)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +132,11 @@ impl<'a, M: RawMutex, BUS: SetConfig> I2cDeviceWithConfig<'a, M, BUS> {
|
|||||||
pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, config: BUS::Config) -> Self {
|
pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, config: BUS::Config) -> Self {
|
||||||
Self { bus, config }
|
Self { bus, config }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the device's config at runtime
|
||||||
|
pub fn set_config(&mut self, config: BUS::Config) {
|
||||||
|
self.config = config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, BUS> ErrorType for I2cDeviceWithConfig<'a, M, BUS>
|
impl<'a, M, BUS> ErrorType for I2cDeviceWithConfig<'a, M, BUS>
|
||||||
@ -171,8 +178,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> {
|
fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> {
|
||||||
let _ = address;
|
self.bus.lock(|bus| {
|
||||||
let _ = operations;
|
let mut bus = bus.borrow_mut();
|
||||||
todo!()
|
bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?;
|
||||||
|
bus.transaction(address, operations).map_err(I2cDeviceError::I2c)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,11 @@ impl<'a, M: RawMutex, BUS: SetConfig, CS> SpiDeviceWithConfig<'a, M, BUS, CS> {
|
|||||||
pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, cs: CS, config: BUS::Config) -> Self {
|
pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, cs: CS, config: BUS::Config) -> Self {
|
||||||
Self { bus, cs, config }
|
Self { bus, cs, config }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the device's config at runtime
|
||||||
|
pub fn set_config(&mut self, config: BUS::Config) {
|
||||||
|
self.config = config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M, BUS, CS> spi::ErrorType for SpiDeviceWithConfig<'a, M, BUS, CS>
|
impl<'a, M, BUS, CS> spi::ErrorType for SpiDeviceWithConfig<'a, M, BUS, CS>
|
||||||
|
@ -93,10 +93,21 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre
|
|||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
let mut task_outer: ItemFn = parse_quote! {
|
let mut task_outer: ItemFn = parse_quote! {
|
||||||
#visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
|
#visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
|
||||||
type Fut = impl ::core::future::Future + 'static;
|
trait _EmbassyInternalTaskTrait {
|
||||||
|
type Fut: ::core::future::Future + 'static;
|
||||||
|
fn construct(#fargs) -> Self::Fut;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl _EmbassyInternalTaskTrait for () {
|
||||||
|
type Fut = impl core::future::Future + 'static;
|
||||||
|
fn construct(#fargs) -> Self::Fut {
|
||||||
|
#task_inner_ident(#(#full_args,)*)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const POOL_SIZE: usize = #pool_size;
|
const POOL_SIZE: usize = #pool_size;
|
||||||
static POOL: ::embassy_executor::raw::TaskPool<Fut, POOL_SIZE> = ::embassy_executor::raw::TaskPool::new();
|
static POOL: ::embassy_executor::raw::TaskPool<<() as _EmbassyInternalTaskTrait>::Fut, POOL_SIZE> = ::embassy_executor::raw::TaskPool::new();
|
||||||
unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) }
|
unsafe { POOL._spawn_async_fn(move || <() as _EmbassyInternalTaskTrait>::construct(#(#full_args,)*)) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
|
@ -7,7 +7,6 @@ use std::thread;
|
|||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{quote, ToTokens};
|
use quote::{quote, ToTokens};
|
||||||
use syn;
|
|
||||||
|
|
||||||
/// A type to collect errors together and format them.
|
/// A type to collect errors together and format them.
|
||||||
///
|
///
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -30,7 +30,7 @@ use core::ptr::NonNull;
|
|||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
#[cfg(feature = "integrated-timers")]
|
#[cfg(feature = "integrated-timers")]
|
||||||
use embassy_time_driver::{self, AlarmHandle};
|
use embassy_time_driver::AlarmHandle;
|
||||||
#[cfg(feature = "rtos-trace")]
|
#[cfg(feature = "rtos-trace")]
|
||||||
use rtos_trace::trace;
|
use rtos_trace::trace;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
|
#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
|
||||||
|
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
use std::future::poll_fn;
|
use std::future::poll_fn;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -30,14 +30,12 @@ macro_rules! interrupt_mod {
|
|||||||
pub mod typelevel {
|
pub mod typelevel {
|
||||||
use super::InterruptExt;
|
use super::InterruptExt;
|
||||||
|
|
||||||
mod sealed {
|
trait SealedInterrupt {}
|
||||||
pub trait Interrupt {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Type-level interrupt.
|
/// Type-level interrupt.
|
||||||
///
|
///
|
||||||
/// This trait is implemented for all typelevel interrupt types in this module.
|
/// This trait is implemented for all typelevel interrupt types in this module.
|
||||||
pub trait Interrupt: sealed::Interrupt {
|
pub trait Interrupt: SealedInterrupt {
|
||||||
|
|
||||||
/// Interrupt enum variant.
|
/// Interrupt enum variant.
|
||||||
///
|
///
|
||||||
@ -105,7 +103,7 @@ macro_rules! interrupt_mod {
|
|||||||
#[doc=stringify!($irqs)]
|
#[doc=stringify!($irqs)]
|
||||||
#[doc=" typelevel interrupt."]
|
#[doc=" typelevel interrupt."]
|
||||||
pub enum $irqs {}
|
pub enum $irqs {}
|
||||||
impl sealed::Interrupt for $irqs{}
|
impl SealedInterrupt for $irqs{}
|
||||||
impl Interrupt for $irqs {
|
impl Interrupt for $irqs {
|
||||||
const IRQ: super::Interrupt = super::Interrupt::$irqs;
|
const IRQ: super::Interrupt = super::Interrupt::$irqs;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -83,14 +83,17 @@ macro_rules! todo {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "defmt"))]
|
||||||
macro_rules! unreachable {
|
macro_rules! unreachable {
|
||||||
($($x:tt)*) => {
|
($($x:tt)*) => {
|
||||||
{
|
::core::unreachable!($($x)*)
|
||||||
#[cfg(not(feature = "defmt"))]
|
};
|
||||||
::core::unreachable!($($x)*);
|
}
|
||||||
#[cfg(feature = "defmt")]
|
|
||||||
::defmt::unreachable!($($x)*);
|
#[cfg(feature = "defmt")]
|
||||||
}
|
macro_rules! unreachable {
|
||||||
|
($($x:tt)*) => {
|
||||||
|
::defmt::unreachable!($($x)*)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +116,7 @@ macro_rules! trace {
|
|||||||
#[cfg(feature = "defmt")]
|
#[cfg(feature = "defmt")]
|
||||||
::defmt::trace!($s $(, $x)*);
|
::defmt::trace!($s $(, $x)*);
|
||||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
let _ignored = ($( & $x ),*);
|
let _ = ($( & $x ),*);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -126,7 +129,7 @@ macro_rules! debug {
|
|||||||
#[cfg(feature = "defmt")]
|
#[cfg(feature = "defmt")]
|
||||||
::defmt::debug!($s $(, $x)*);
|
::defmt::debug!($s $(, $x)*);
|
||||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
let _ignored = ($( & $x ),*);
|
let _ = ($( & $x ),*);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -139,7 +142,7 @@ macro_rules! info {
|
|||||||
#[cfg(feature = "defmt")]
|
#[cfg(feature = "defmt")]
|
||||||
::defmt::info!($s $(, $x)*);
|
::defmt::info!($s $(, $x)*);
|
||||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
let _ignored = ($( & $x ),*);
|
let _ = ($( & $x ),*);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -152,7 +155,7 @@ macro_rules! warn {
|
|||||||
#[cfg(feature = "defmt")]
|
#[cfg(feature = "defmt")]
|
||||||
::defmt::warn!($s $(, $x)*);
|
::defmt::warn!($s $(, $x)*);
|
||||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
let _ignored = ($( & $x ),*);
|
let _ = ($( & $x ),*);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -165,7 +168,7 @@ macro_rules! error {
|
|||||||
#[cfg(feature = "defmt")]
|
#[cfg(feature = "defmt")]
|
||||||
::defmt::error!($s $(, $x)*);
|
::defmt::error!($s $(, $x)*);
|
||||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||||
let _ignored = ($( & $x ),*);
|
let _ = ($( & $x ),*);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -226,7 +229,7 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -17,7 +17,6 @@ mod phy;
|
|||||||
mod traits;
|
mod traits;
|
||||||
|
|
||||||
use core::cmp;
|
use core::cmp;
|
||||||
use core::convert::TryInto;
|
|
||||||
|
|
||||||
use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
|
use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
|
||||||
use embassy_time::Duration;
|
use embassy_time::Duration;
|
||||||
@ -645,8 +644,8 @@ where
|
|||||||
Self: 'a;
|
Self: 'a;
|
||||||
|
|
||||||
fn receive(&mut self, cx: &mut core::task::Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
|
fn receive(&mut self, cx: &mut core::task::Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
|
||||||
let rx_buf = unsafe { &mut RX_BUF };
|
let rx_buf = unsafe { &mut *core::ptr::addr_of_mut!(RX_BUF) };
|
||||||
let tx_buf = unsafe { &mut TX_BUF };
|
let tx_buf = unsafe { &mut *core::ptr::addr_of_mut!(TX_BUF) };
|
||||||
if let Some(n) = self.receive(rx_buf) {
|
if let Some(n) = self.receive(rx_buf) {
|
||||||
Some((RxToken { buf: &mut rx_buf[..n] }, TxToken { buf: tx_buf, eth: self }))
|
Some((RxToken { buf: &mut rx_buf[..n] }, TxToken { buf: tx_buf, eth: self }))
|
||||||
} else {
|
} else {
|
||||||
@ -656,7 +655,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transmit(&mut self, _cx: &mut core::task::Context) -> Option<Self::TxToken<'_>> {
|
fn transmit(&mut self, _cx: &mut core::task::Context) -> Option<Self::TxToken<'_>> {
|
||||||
let tx_buf = unsafe { &mut TX_BUF };
|
let tx_buf = unsafe { &mut *core::ptr::addr_of_mut!(TX_BUF) };
|
||||||
Some(TxToken { buf: tx_buf, eth: self })
|
Some(TxToken { buf: tx_buf, eth: self })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -6,7 +6,7 @@ use std::os::unix::io::{AsRawFd, RawFd};
|
|||||||
use std::task::Context;
|
use std::task::Context;
|
||||||
|
|
||||||
use async_io::Async;
|
use async_io::Async;
|
||||||
use embassy_net_driver::{self, Capabilities, Driver, HardwareAddress, LinkState};
|
use embassy_net_driver::{Capabilities, Driver, HardwareAddress, LinkState};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
||||||
/// Get the MTU of the given interface.
|
/// Get the MTU of the given interface.
|
||||||
|
@ -2,12 +2,10 @@
|
|||||||
mod w5500;
|
mod w5500;
|
||||||
pub use w5500::W5500;
|
pub use w5500::W5500;
|
||||||
mod w5100s;
|
mod w5100s;
|
||||||
|
use embedded_hal_async::spi::SpiDevice;
|
||||||
pub use w5100s::W5100S;
|
pub use w5100s::W5100S;
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) trait SealedChip {
|
||||||
use embedded_hal_async::spi::SpiDevice;
|
|
||||||
|
|
||||||
pub trait Chip {
|
|
||||||
type Address;
|
type Address;
|
||||||
|
|
||||||
const COMMON_MODE: Self::Address;
|
const COMMON_MODE: Self::Address;
|
||||||
@ -33,18 +31,11 @@ pub(crate) mod sealed {
|
|||||||
fn rx_addr(addr: u16) -> Self::Address;
|
fn rx_addr(addr: u16) -> Self::Address;
|
||||||
fn tx_addr(addr: u16) -> Self::Address;
|
fn tx_addr(addr: u16) -> Self::Address;
|
||||||
|
|
||||||
async fn bus_read<SPI: SpiDevice>(
|
async fn bus_read<SPI: SpiDevice>(spi: &mut SPI, address: Self::Address, data: &mut [u8])
|
||||||
spi: &mut SPI,
|
-> Result<(), SPI::Error>;
|
||||||
address: Self::Address,
|
async fn bus_write<SPI: SpiDevice>(spi: &mut SPI, address: Self::Address, data: &[u8]) -> Result<(), SPI::Error>;
|
||||||
data: &mut [u8],
|
|
||||||
) -> Result<(), SPI::Error>;
|
|
||||||
async fn bus_write<SPI: SpiDevice>(
|
|
||||||
spi: &mut SPI,
|
|
||||||
address: Self::Address,
|
|
||||||
data: &[u8],
|
|
||||||
) -> Result<(), SPI::Error>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for Wiznet chips.
|
/// Trait for Wiznet chips.
|
||||||
pub trait Chip: sealed::Chip {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait Chip: SealedChip {}
|
||||||
|
@ -8,7 +8,7 @@ const RX_BASE: u16 = 0x6000;
|
|||||||
pub enum W5100S {}
|
pub enum W5100S {}
|
||||||
|
|
||||||
impl super::Chip for W5100S {}
|
impl super::Chip for W5100S {}
|
||||||
impl super::sealed::Chip for W5100S {
|
impl super::SealedChip for W5100S {
|
||||||
type Address = u16;
|
type Address = u16;
|
||||||
|
|
||||||
const COMMON_MODE: Self::Address = 0x00;
|
const COMMON_MODE: Self::Address = 0x00;
|
||||||
|
@ -12,7 +12,7 @@ pub enum RegisterBlock {
|
|||||||
pub enum W5500 {}
|
pub enum W5500 {}
|
||||||
|
|
||||||
impl super::Chip for W5500 {}
|
impl super::Chip for W5500 {}
|
||||||
impl super::sealed::Chip for W5500 {
|
impl super::SealedChip for W5500 {
|
||||||
type Address = (RegisterBlock, u16);
|
type Address = (RegisterBlock, u16);
|
||||||
|
|
||||||
const COMMON_MODE: Self::Address = (RegisterBlock::Common, 0x00);
|
const COMMON_MODE: Self::Address = (RegisterBlock::Common, 0x00);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -473,10 +473,12 @@ impl sealed::Pin for AnyPin {
|
|||||||
|
|
||||||
// ====================
|
// ====================
|
||||||
|
|
||||||
|
#[cfg(not(feature = "_nrf51"))]
|
||||||
pub(crate) trait PselBits {
|
pub(crate) trait PselBits {
|
||||||
fn psel_bits(&self) -> u32;
|
fn psel_bits(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "_nrf51"))]
|
||||||
impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> {
|
impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn psel_bits(&self) -> u32 {
|
fn psel_bits(&self) -> u32 {
|
||||||
|
@ -167,8 +167,10 @@ unsafe fn handle_gpiote_interrupt() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "_nrf51"))]
|
||||||
struct BitIter(u32);
|
struct BitIter(u32);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "_nrf51"))]
|
||||||
impl Iterator for BitIter {
|
impl Iterator for BitIter {
|
||||||
type Item = u32;
|
type Item = u32;
|
||||||
|
|
||||||
|
@ -225,10 +225,31 @@ pub mod config {
|
|||||||
/// Config for the first stage DCDC (VDDH -> VDD), if disabled LDO will be used.
|
/// Config for the first stage DCDC (VDDH -> VDD), if disabled LDO will be used.
|
||||||
#[cfg(feature = "nrf52840")]
|
#[cfg(feature = "nrf52840")]
|
||||||
pub reg0: bool,
|
pub reg0: bool,
|
||||||
|
/// Configure the voltage of the first stage DCDC. It is stored in non-volatile memory (UICR.REGOUT0 register); pass None to not touch it.
|
||||||
|
#[cfg(feature = "nrf52840")]
|
||||||
|
pub reg0_voltage: Option<Reg0Voltage>,
|
||||||
/// Config for the second stage DCDC (VDD -> DEC4), if disabled LDO will be used.
|
/// Config for the second stage DCDC (VDD -> DEC4), if disabled LDO will be used.
|
||||||
pub reg1: bool,
|
pub reg1: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Output voltage setting for REG0 regulator stage.
|
||||||
|
#[cfg(feature = "nrf52840")]
|
||||||
|
pub enum Reg0Voltage {
|
||||||
|
/// 1.8 V
|
||||||
|
_1V8 = 0,
|
||||||
|
/// 2.1 V
|
||||||
|
_2V1 = 1,
|
||||||
|
/// 2.4 V
|
||||||
|
_2V4 = 2,
|
||||||
|
/// 2.7 V
|
||||||
|
_2V7 = 3,
|
||||||
|
/// 3.0 V
|
||||||
|
_3V0 = 4,
|
||||||
|
/// 3.3 V
|
||||||
|
_3v3 = 5,
|
||||||
|
//ERASED = 7, means 1.8V
|
||||||
|
}
|
||||||
|
|
||||||
/// Settings for enabling the built in DCDC converters.
|
/// Settings for enabling the built in DCDC converters.
|
||||||
#[cfg(feature = "_nrf5340-app")]
|
#[cfg(feature = "_nrf5340-app")]
|
||||||
pub struct DcdcConfig {
|
pub struct DcdcConfig {
|
||||||
@ -279,6 +300,8 @@ pub mod config {
|
|||||||
dcdc: DcdcConfig {
|
dcdc: DcdcConfig {
|
||||||
#[cfg(feature = "nrf52840")]
|
#[cfg(feature = "nrf52840")]
|
||||||
reg0: false,
|
reg0: false,
|
||||||
|
#[cfg(feature = "nrf52840")]
|
||||||
|
reg0_voltage: None,
|
||||||
reg1: false,
|
reg1: false,
|
||||||
},
|
},
|
||||||
#[cfg(feature = "_nrf5340-app")]
|
#[cfg(feature = "_nrf5340-app")]
|
||||||
@ -337,6 +360,7 @@ mod consts {
|
|||||||
pub const UICR_PSELRESET2: *mut u32 = 0x10001204 as *mut u32;
|
pub const UICR_PSELRESET2: *mut u32 = 0x10001204 as *mut u32;
|
||||||
pub const UICR_NFCPINS: *mut u32 = 0x1000120C as *mut u32;
|
pub const UICR_NFCPINS: *mut u32 = 0x1000120C as *mut u32;
|
||||||
pub const UICR_APPROTECT: *mut u32 = 0x10001208 as *mut u32;
|
pub const UICR_APPROTECT: *mut u32 = 0x10001208 as *mut u32;
|
||||||
|
pub const UICR_REGOUT0: *mut u32 = 0x10001304 as *mut u32;
|
||||||
pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
|
pub const APPROTECT_ENABLED: u32 = 0x0000_0000;
|
||||||
pub const APPROTECT_DISABLED: u32 = 0x0000_005a;
|
pub const APPROTECT_DISABLED: u32 = 0x0000_005a;
|
||||||
}
|
}
|
||||||
@ -493,6 +517,21 @@ pub fn init(config: config::Config) -> Peripherals {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nrf52840")]
|
||||||
|
unsafe {
|
||||||
|
if let Some(value) = config.dcdc.reg0_voltage {
|
||||||
|
let value = value as u32;
|
||||||
|
let res = uicr_write_masked(consts::UICR_REGOUT0, value, 0b00000000_00000000_00000000_00000111);
|
||||||
|
needs_reset |= res == WriteResult::Written;
|
||||||
|
if res == WriteResult::Failed {
|
||||||
|
warn!(
|
||||||
|
"Failed to set regulator voltage, as UICR is already programmed to some other setting, and can't be changed without erasing it.\n\
|
||||||
|
To fix this, erase UICR manually, for example using `probe-rs erase` or `nrfjprog --eraseuicr`."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if needs_reset {
|
if needs_reset {
|
||||||
cortex_m::peripheral::SCB::sys_reset();
|
cortex_m::peripheral::SCB::sys_reset();
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,6 @@ pub(crate) mod sealed {
|
|||||||
fn regs() -> &'static pac::timer0::RegisterBlock;
|
fn regs() -> &'static pac::timer0::RegisterBlock;
|
||||||
}
|
}
|
||||||
pub trait ExtendedInstance {}
|
pub trait ExtendedInstance {}
|
||||||
|
|
||||||
pub trait TimerType {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Basic Timer instance.
|
/// Basic Timer instance.
|
||||||
|
@ -96,7 +96,7 @@ pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
|
|||||||
) -> Transfer<'a, C> {
|
) -> Transfer<'a, C> {
|
||||||
copy_inner(
|
copy_inner(
|
||||||
ch,
|
ch,
|
||||||
&mut DUMMY as *const u32,
|
core::ptr::addr_of_mut!(DUMMY) as *const u32,
|
||||||
to as *mut u32,
|
to as *mut u32,
|
||||||
len,
|
len,
|
||||||
W::size(),
|
W::size(),
|
||||||
|
@ -420,8 +420,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
mod ram_helpers {
|
mod ram_helpers {
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::rom_data;
|
use crate::rom_data;
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ pub(crate) trait Float:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if `self` is infinity
|
/// Returns true if `self` is infinity
|
||||||
|
#[allow(unused)]
|
||||||
fn is_infinity(self) -> bool {
|
fn is_infinity(self) -> bool {
|
||||||
(self.repr() & (Self::EXPONENT_MASK | Self::SIGNIFICAND_MASK)) == Self::EXPONENT_MASK
|
(self.repr() & (Self::EXPONENT_MASK | Self::SIGNIFICAND_MASK)) == Self::EXPONENT_MASK
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -976,8 +976,6 @@ impl_pin!(PIN_QSPI_SD3, Bank::Qspi, 5);
|
|||||||
// ====================
|
// ====================
|
||||||
|
|
||||||
mod eh02 {
|
mod eh02 {
|
||||||
use core::convert::Infallible;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl<'d> embedded_hal_02::digital::v2::InputPin for Input<'d> {
|
impl<'d> embedded_hal_02::digital::v2::InputPin for Input<'d> {
|
||||||
|
@ -274,7 +274,7 @@ pub fn install_core0_stack_guard() -> Result<(), ()> {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
static mut _stack_end: usize;
|
static mut _stack_end: usize;
|
||||||
}
|
}
|
||||||
unsafe { install_stack_guard(&mut _stack_end as *mut usize) }
|
unsafe { install_stack_guard(core::ptr::addr_of_mut!(_stack_end)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -354,6 +354,7 @@ pub fn init(config: config::Config) -> Peripherals {
|
|||||||
|
|
||||||
/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes.
|
/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes.
|
||||||
trait RegExt<T: Copy> {
|
trait RegExt<T: Copy> {
|
||||||
|
#[allow(unused)]
|
||||||
fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
|
fn write_xor<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
|
||||||
fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
|
fn write_set<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
|
||||||
fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
|
fn write_clear<R>(&self, f: impl FnOnce(&mut T) -> R) -> R;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use core::iter::Iterator;
|
|
||||||
|
|
||||||
use pio::{Program, SideSet, Wrap};
|
use pio::{Program, SideSet, Wrap};
|
||||||
|
|
||||||
pub struct CodeIterator<'a, I>
|
pub struct CodeIterator<'a, I>
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
//! Buffered UART driver.
|
//! Buffered UART driver.
|
||||||
use core::future::{poll_fn, Future};
|
use core::future::Future;
|
||||||
use core::slice;
|
use core::slice;
|
||||||
use core::task::Poll;
|
|
||||||
|
|
||||||
use atomic_polyfill::{AtomicU8, Ordering};
|
use atomic_polyfill::AtomicU8;
|
||||||
use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
|
use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
|
||||||
use embassy_time::Timer;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::clocks::clk_peri_freq;
|
|
||||||
use crate::interrupt::typelevel::{Binding, Interrupt};
|
|
||||||
use crate::{interrupt, RegExt};
|
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
tx_waker: AtomicWaker,
|
tx_waker: AtomicWaker,
|
||||||
|
@ -465,7 +465,6 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
|
|||||||
|
|
||||||
trait Dir {
|
trait Dir {
|
||||||
fn dir() -> Direction;
|
fn dir() -> Direction;
|
||||||
fn waker(i: usize) -> &'static AtomicWaker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type for In direction.
|
/// Type for In direction.
|
||||||
@ -474,11 +473,6 @@ impl Dir for In {
|
|||||||
fn dir() -> Direction {
|
fn dir() -> Direction {
|
||||||
Direction::In
|
Direction::In
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn waker(i: usize) -> &'static AtomicWaker {
|
|
||||||
&EP_IN_WAKERS[i]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type for Out direction.
|
/// Type for Out direction.
|
||||||
@ -487,11 +481,6 @@ impl Dir for Out {
|
|||||||
fn dir() -> Direction {
|
fn dir() -> Direction {
|
||||||
Direction::Out
|
Direction::Out
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn waker(i: usize) -> &'static AtomicWaker {
|
|
||||||
&EP_OUT_WAKERS[i]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Endpoint for RP USB driver.
|
/// Endpoint for RP USB driver.
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use core::convert::TryFrom;
|
|
||||||
|
|
||||||
use crate::evt::CsEvt;
|
use crate::evt::CsEvt;
|
||||||
use crate::PacketHeader;
|
use crate::PacketHeader;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -70,7 +70,7 @@ rand_core = "0.6.3"
|
|||||||
sdio-host = "0.5.0"
|
sdio-host = "0.5.0"
|
||||||
critical-section = "1.1"
|
critical-section = "1.1"
|
||||||
#stm32-metapac = { version = "15" }
|
#stm32-metapac = { version = "15" }
|
||||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c8b32ecae7d70cea2705095c4fc6bd5f59d238d5" }
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f84633553331c2d154ee72de779a40cbb10fd1bd" }
|
||||||
vcell = "0.1.3"
|
vcell = "0.1.3"
|
||||||
nb = "1.0.0"
|
nb = "1.0.0"
|
||||||
stm32-fmc = "0.3.0"
|
stm32-fmc = "0.3.0"
|
||||||
@ -94,7 +94,7 @@ critical-section = { version = "1.1", features = ["std"] }
|
|||||||
proc-macro2 = "1.0.36"
|
proc-macro2 = "1.0.36"
|
||||||
quote = "1.0.15"
|
quote = "1.0.15"
|
||||||
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
|
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
|
||||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c8b32ecae7d70cea2705095c4fc6bd5f59d238d5", default-features = false, features = ["metadata"]}
|
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-f84633553331c2d154ee72de779a40cbb10fd1bd", default-features = false, features = ["metadata"]}
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -584,7 +584,7 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
g.extend(quote! {
|
g.extend(quote! {
|
||||||
impl crate::rcc::sealed::RccPeripheral for peripherals::#pname {
|
impl crate::rcc::SealedRccPeripheral for peripherals::#pname {
|
||||||
fn frequency() -> crate::time::Hertz {
|
fn frequency() -> crate::time::Hertz {
|
||||||
#clock_frequency
|
#clock_frequency
|
||||||
}
|
}
|
||||||
@ -826,20 +826,20 @@ fn main() {
|
|||||||
(("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)),
|
(("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)),
|
||||||
(("usb", "DP"), quote!(crate::usb::DpPin)),
|
(("usb", "DP"), quote!(crate::usb::DpPin)),
|
||||||
(("usb", "DM"), quote!(crate::usb::DmPin)),
|
(("usb", "DM"), quote!(crate::usb::DmPin)),
|
||||||
(("otg", "DP"), quote!(crate::usb_otg::DpPin)),
|
(("otg", "DP"), quote!(crate::usb::DpPin)),
|
||||||
(("otg", "DM"), quote!(crate::usb_otg::DmPin)),
|
(("otg", "DM"), quote!(crate::usb::DmPin)),
|
||||||
(("otg", "ULPI_CK"), quote!(crate::usb_otg::UlpiClkPin)),
|
(("otg", "ULPI_CK"), quote!(crate::usb::UlpiClkPin)),
|
||||||
(("otg", "ULPI_DIR"), quote!(crate::usb_otg::UlpiDirPin)),
|
(("otg", "ULPI_DIR"), quote!(crate::usb::UlpiDirPin)),
|
||||||
(("otg", "ULPI_NXT"), quote!(crate::usb_otg::UlpiNxtPin)),
|
(("otg", "ULPI_NXT"), quote!(crate::usb::UlpiNxtPin)),
|
||||||
(("otg", "ULPI_STP"), quote!(crate::usb_otg::UlpiStpPin)),
|
(("otg", "ULPI_STP"), quote!(crate::usb::UlpiStpPin)),
|
||||||
(("otg", "ULPI_D0"), quote!(crate::usb_otg::UlpiD0Pin)),
|
(("otg", "ULPI_D0"), quote!(crate::usb::UlpiD0Pin)),
|
||||||
(("otg", "ULPI_D1"), quote!(crate::usb_otg::UlpiD1Pin)),
|
(("otg", "ULPI_D1"), quote!(crate::usb::UlpiD1Pin)),
|
||||||
(("otg", "ULPI_D2"), quote!(crate::usb_otg::UlpiD2Pin)),
|
(("otg", "ULPI_D2"), quote!(crate::usb::UlpiD2Pin)),
|
||||||
(("otg", "ULPI_D3"), quote!(crate::usb_otg::UlpiD3Pin)),
|
(("otg", "ULPI_D3"), quote!(crate::usb::UlpiD3Pin)),
|
||||||
(("otg", "ULPI_D4"), quote!(crate::usb_otg::UlpiD4Pin)),
|
(("otg", "ULPI_D4"), quote!(crate::usb::UlpiD4Pin)),
|
||||||
(("otg", "ULPI_D5"), quote!(crate::usb_otg::UlpiD5Pin)),
|
(("otg", "ULPI_D5"), quote!(crate::usb::UlpiD5Pin)),
|
||||||
(("otg", "ULPI_D6"), quote!(crate::usb_otg::UlpiD6Pin)),
|
(("otg", "ULPI_D6"), quote!(crate::usb::UlpiD6Pin)),
|
||||||
(("otg", "ULPI_D7"), quote!(crate::usb_otg::UlpiD7Pin)),
|
(("otg", "ULPI_D7"), quote!(crate::usb::UlpiD7Pin)),
|
||||||
(("can", "TX"), quote!(crate::can::TxPin)),
|
(("can", "TX"), quote!(crate::can::TxPin)),
|
||||||
(("can", "RX"), quote!(crate::can::RxPin)),
|
(("can", "RX"), quote!(crate::can::RxPin)),
|
||||||
(("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)),
|
(("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)),
|
||||||
@ -1486,7 +1486,7 @@ fn main() {
|
|||||||
#[crate::interrupt]
|
#[crate::interrupt]
|
||||||
unsafe fn #irq () {
|
unsafe fn #irq () {
|
||||||
#(
|
#(
|
||||||
<crate::peripherals::#channels as crate::dma::sealed::ChannelInterrupt>::on_irq();
|
<crate::peripherals::#channels as crate::dma::ChannelInterrupt>::on_irq();
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
|
|||||||
|
|
||||||
pub struct Vref;
|
pub struct Vref;
|
||||||
impl<T: Instance> AdcPin<T> for Vref {}
|
impl<T: Instance> AdcPin<T> for Vref {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Vref {
|
impl<T: Instance> super::SealedAdcPin<T> for Vref {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
17
|
17
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Vref {
|
|||||||
|
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl<T: Instance> AdcPin<T> for Temperature {}
|
impl<T: Instance> AdcPin<T> for Temperature {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
|
impl<T: Instance> super::SealedAdcPin<T> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
|
|||||||
|
|
||||||
pub struct Vref;
|
pub struct Vref;
|
||||||
impl<T: Instance> AdcPin<T> for Vref {}
|
impl<T: Instance> AdcPin<T> for Vref {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Vref {
|
impl<T: Instance> super::SealedAdcPin<T> for Vref {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
18
|
18
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ impl Vref {
|
|||||||
|
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl<T: Instance> AdcPin<T> for Temperature {}
|
impl<T: Instance> AdcPin<T> for Temperature {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
|
impl<T: Instance> super::SealedAdcPin<T> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn freq() -> Hertz {
|
fn freq() -> Hertz {
|
||||||
<T as crate::rcc::sealed::RccPeripheral>::frequency()
|
<T as crate::rcc::SealedRccPeripheral>::frequency()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
|
pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
|
||||||
|
@ -65,7 +65,7 @@ fn update_vref<T: Instance>(op: i8) {
|
|||||||
|
|
||||||
pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
|
pub struct Vref<T: Instance>(core::marker::PhantomData<T>);
|
||||||
impl<T: Instance> AdcPin<T> for Vref<T> {}
|
impl<T: Instance> AdcPin<T> for Vref<T> {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Vref<T> {
|
impl<T: Instance> super::SealedAdcPin<T> for Vref<T> {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
17
|
17
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ impl<T: Instance> Drop for Vref<T> {
|
|||||||
|
|
||||||
pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
|
pub struct Temperature<T: Instance>(core::marker::PhantomData<T>);
|
||||||
impl<T: Instance> AdcPin<T> for Temperature<T> {}
|
impl<T: Instance> AdcPin<T> for Temperature<T> {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Temperature<T> {
|
impl<T: Instance> super::SealedAdcPin<T> for Temperature<T> {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ mod _version;
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[cfg(not(adc_f3_v2))]
|
#[cfg(not(adc_f3_v2))]
|
||||||
pub use _version::*;
|
pub use _version::*;
|
||||||
|
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
||||||
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
#[cfg(not(any(adc_f1, adc_f3_v2)))]
|
#[cfg(not(any(adc_f1, adc_f3_v2)))]
|
||||||
pub use crate::pac::adc::vals::Res as Resolution;
|
pub use crate::pac::adc::vals::Res as Resolution;
|
||||||
@ -31,63 +33,65 @@ pub struct Adc<'d, T: Instance> {
|
|||||||
sample_time: SampleTime,
|
sample_time: SampleTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
||||||
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
pub struct State {
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
|
||||||
|
|
||||||
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
|
||||||
pub struct State {
|
|
||||||
pub waker: AtomicWaker,
|
pub waker: AtomicWaker,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
||||||
impl State {
|
impl State {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
waker: AtomicWaker::new(),
|
waker: AtomicWaker::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InterruptableInstance {
|
trait SealedInstance {
|
||||||
type Interrupt: crate::interrupt::typelevel::Interrupt;
|
#[allow(unused)]
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Instance: InterruptableInstance {
|
|
||||||
fn regs() -> crate::pac::adc::Adc;
|
fn regs() -> crate::pac::adc::Adc;
|
||||||
#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
|
#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
|
||||||
fn common_regs() -> crate::pac::adccommon::AdcCommon;
|
fn common_regs() -> crate::pac::adccommon::AdcCommon;
|
||||||
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
||||||
fn state() -> &'static State;
|
fn state() -> &'static State;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AdcPin<T: Instance> {
|
pub(crate) trait SealedAdcPin<T: Instance> {
|
||||||
#[cfg(any(adc_v1, adc_l0, adc_v2))]
|
#[cfg(any(adc_v1, adc_l0, adc_v2))]
|
||||||
fn set_as_analog(&mut self) {}
|
fn set_as_analog(&mut self) {}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
fn channel(&self) -> u8;
|
fn channel(&self) -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InternalChannel<T> {
|
trait SealedInternalChannel<T> {
|
||||||
|
#[allow(unused)]
|
||||||
fn channel(&self) -> u8;
|
fn channel(&self) -> u8;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ADC instance.
|
/// ADC instance.
|
||||||
#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))]
|
#[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))]
|
||||||
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + crate::Peripheral<P = Self> {
|
||||||
|
type Interrupt: crate::interrupt::typelevel::Interrupt;
|
||||||
|
}
|
||||||
/// ADC instance.
|
/// ADC instance.
|
||||||
#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))]
|
#[cfg(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5))]
|
||||||
pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {
|
||||||
|
type Interrupt: crate::interrupt::typelevel::Interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
/// ADC pin.
|
/// ADC pin.
|
||||||
pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait AdcPin<T: Instance>: SealedAdcPin<T> {}
|
||||||
/// ADC internal channel.
|
/// ADC internal channel.
|
||||||
pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait InternalChannel<T>: SealedInternalChannel<T> {}
|
||||||
|
|
||||||
foreach_adc!(
|
foreach_adc!(
|
||||||
($inst:ident, $common_inst:ident, $clock:ident) => {
|
($inst:ident, $common_inst:ident, $clock:ident) => {
|
||||||
impl crate::adc::sealed::Instance for peripherals::$inst {
|
impl crate::adc::SealedInstance for peripherals::$inst {
|
||||||
fn regs() -> crate::pac::adc::Adc {
|
fn regs() -> crate::pac::adc::Adc {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
@ -98,32 +102,26 @@ foreach_adc!(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
|
||||||
fn state() -> &'static sealed::State {
|
fn state() -> &'static State {
|
||||||
static STATE: sealed::State = sealed::State::new();
|
static STATE: State = State::new();
|
||||||
&STATE
|
&STATE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach_interrupt!(
|
impl crate::adc::Instance for peripherals::$inst {
|
||||||
($inst,adc,ADC,GLOBAL,$irq:ident) => {
|
type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL;
|
||||||
impl sealed::InterruptableInstance for peripherals::$inst {
|
|
||||||
type Interrupt = crate::interrupt::typelevel::$irq;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
);
|
|
||||||
|
|
||||||
impl crate::adc::Instance for peripherals::$inst {}
|
|
||||||
};
|
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! impl_adc_pin {
|
macro_rules! impl_adc_pin {
|
||||||
($inst:ident, $pin:ident, $ch:expr) => {
|
($inst:ident, $pin:ident, $ch:expr) => {
|
||||||
impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
|
impl crate::adc::AdcPin<peripherals::$inst> for crate::peripherals::$pin {}
|
||||||
|
|
||||||
impl crate::adc::sealed::AdcPin<peripherals::$inst> for crate::peripherals::$pin {
|
impl crate::adc::SealedAdcPin<peripherals::$inst> for crate::peripherals::$pin {
|
||||||
#[cfg(any(adc_v1, adc_l0, adc_v2))]
|
#[cfg(any(adc_v1, adc_l0, adc_v2))]
|
||||||
fn set_as_analog(&mut self) {
|
fn set_as_analog(&mut self) {
|
||||||
<Self as crate::gpio::sealed::Pin>::set_as_analog(self);
|
<Self as crate::gpio::SealedPin>::set_as_analog(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
|
@ -39,7 +39,7 @@ pub struct Vbat;
|
|||||||
impl AdcPin<ADC> for Vbat {}
|
impl AdcPin<ADC> for Vbat {}
|
||||||
|
|
||||||
#[cfg(not(adc_l0))]
|
#[cfg(not(adc_l0))]
|
||||||
impl super::sealed::AdcPin<ADC> for Vbat {
|
impl super::SealedAdcPin<ADC> for Vbat {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
18
|
18
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ impl super::sealed::AdcPin<ADC> for Vbat {
|
|||||||
|
|
||||||
pub struct Vref;
|
pub struct Vref;
|
||||||
impl AdcPin<ADC> for Vref {}
|
impl AdcPin<ADC> for Vref {}
|
||||||
impl super::sealed::AdcPin<ADC> for Vref {
|
impl super::SealedAdcPin<ADC> for Vref {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
17
|
17
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ impl super::sealed::AdcPin<ADC> for Vref {
|
|||||||
|
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl AdcPin<ADC> for Temperature {}
|
impl AdcPin<ADC> for Temperature {}
|
||||||
impl super::sealed::AdcPin<ADC> for Temperature {
|
impl super::SealedAdcPin<ADC> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ pub const ADC_POWERUP_TIME_US: u32 = 3;
|
|||||||
|
|
||||||
pub struct VrefInt;
|
pub struct VrefInt;
|
||||||
impl AdcPin<ADC1> for VrefInt {}
|
impl AdcPin<ADC1> for VrefInt {}
|
||||||
impl super::sealed::AdcPin<ADC1> for VrefInt {
|
impl super::SealedAdcPin<ADC1> for VrefInt {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
17
|
17
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ impl VrefInt {
|
|||||||
|
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl AdcPin<ADC1> for Temperature {}
|
impl AdcPin<ADC1> for Temperature {}
|
||||||
impl super::sealed::AdcPin<ADC1> for Temperature {
|
impl super::SealedAdcPin<ADC1> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(stm32f2, stm32f40, stm32f41))] {
|
if #[cfg(any(stm32f2, stm32f40, stm32f41))] {
|
||||||
@ -52,7 +52,7 @@ impl Temperature {
|
|||||||
|
|
||||||
pub struct Vbat;
|
pub struct Vbat;
|
||||||
impl AdcPin<ADC1> for Vbat {}
|
impl AdcPin<ADC1> for Vbat {}
|
||||||
impl super::sealed::AdcPin<ADC1> for Vbat {
|
impl super::SealedAdcPin<ADC1> for Vbat {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
18
|
18
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ pub const VREF_CALIB_MV: u32 = 3000;
|
|||||||
|
|
||||||
pub struct VrefInt;
|
pub struct VrefInt;
|
||||||
impl<T: Instance> AdcPin<T> for VrefInt {}
|
impl<T: Instance> AdcPin<T> for VrefInt {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
|
impl<T: Instance> super::SealedAdcPin<T> for VrefInt {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(adc_g0)] {
|
if #[cfg(adc_g0)] {
|
||||||
@ -29,7 +29,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for VrefInt {
|
|||||||
|
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl<T: Instance> AdcPin<T> for Temperature {}
|
impl<T: Instance> AdcPin<T> for Temperature {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
|
impl<T: Instance> super::SealedAdcPin<T> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(adc_g0)] {
|
if #[cfg(adc_g0)] {
|
||||||
@ -46,7 +46,7 @@ impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
|
|||||||
|
|
||||||
pub struct Vbat;
|
pub struct Vbat;
|
||||||
impl<T: Instance> AdcPin<T> for Vbat {}
|
impl<T: Instance> AdcPin<T> for Vbat {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Vbat {
|
impl<T: Instance> super::SealedAdcPin<T> for Vbat {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(adc_g0)] {
|
if #[cfg(adc_g0)] {
|
||||||
@ -65,7 +65,7 @@ cfg_if! {
|
|||||||
if #[cfg(adc_h5)] {
|
if #[cfg(adc_h5)] {
|
||||||
pub struct VddCore;
|
pub struct VddCore;
|
||||||
impl<T: Instance> AdcPin<T> for VddCore {}
|
impl<T: Instance> AdcPin<T> for VddCore {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for VddCore {
|
impl<T: Instance> super::SealedAdcPin<T> for VddCore {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
6
|
6
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ const VBAT_CHANNEL: u8 = 17;
|
|||||||
/// Internal voltage reference channel.
|
/// Internal voltage reference channel.
|
||||||
pub struct VrefInt;
|
pub struct VrefInt;
|
||||||
impl<T: Instance> InternalChannel<T> for VrefInt {}
|
impl<T: Instance> InternalChannel<T> for VrefInt {}
|
||||||
impl<T: Instance> super::sealed::InternalChannel<T> for VrefInt {
|
impl<T: Instance> super::SealedInternalChannel<T> for VrefInt {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
VREF_CHANNEL
|
VREF_CHANNEL
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ impl<T: Instance> super::sealed::InternalChannel<T> for VrefInt {
|
|||||||
/// Internal temperature channel.
|
/// Internal temperature channel.
|
||||||
pub struct Temperature;
|
pub struct Temperature;
|
||||||
impl<T: Instance> InternalChannel<T> for Temperature {}
|
impl<T: Instance> InternalChannel<T> for Temperature {}
|
||||||
impl<T: Instance> super::sealed::InternalChannel<T> for Temperature {
|
impl<T: Instance> super::SealedInternalChannel<T> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
TEMP_CHANNEL
|
TEMP_CHANNEL
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ impl<T: Instance> super::sealed::InternalChannel<T> for Temperature {
|
|||||||
/// Internal battery voltage channel.
|
/// Internal battery voltage channel.
|
||||||
pub struct Vbat;
|
pub struct Vbat;
|
||||||
impl<T: Instance> InternalChannel<T> for Vbat {}
|
impl<T: Instance> InternalChannel<T> for Vbat {}
|
||||||
impl<T: Instance> super::sealed::InternalChannel<T> for Vbat {
|
impl<T: Instance> super::SealedInternalChannel<T> for Vbat {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
VBAT_CHANNEL
|
VBAT_CHANNEL
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
pub fn read<P>(&mut self, pin: &mut P) -> u16
|
pub fn read<P>(&mut self, pin: &mut P) -> u16
|
||||||
where
|
where
|
||||||
P: AdcPin<T>,
|
P: AdcPin<T>,
|
||||||
P: crate::gpio::sealed::Pin,
|
P: crate::gpio::Pin,
|
||||||
{
|
{
|
||||||
pin.set_as_analog();
|
pin.set_as_analog();
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ pub mod filter;
|
|||||||
|
|
||||||
#[allow(clippy::all)] // generated code
|
#[allow(clippy::all)] // generated code
|
||||||
use core::cmp::{Ord, Ordering};
|
use core::cmp::{Ord, Ordering};
|
||||||
use core::convert::{Infallible, Into, TryInto};
|
use core::convert::Infallible;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::AsMut;
|
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
@ -8,9 +7,12 @@ pub mod bx;
|
|||||||
|
|
||||||
pub use bx::{filter, Data, ExtendedId, Fifo, Frame, Header, Id, StandardId};
|
pub use bx::{filter, Data, ExtendedId, Fifo, Frame, Header, Id, StandardId};
|
||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embassy_sync::channel::Channel;
|
||||||
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
|
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::AFType;
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::pac::can::vals::{Ide, Lec};
|
use crate::pac::can::vals::{Ide, Lec};
|
||||||
use crate::rcc::RccPeripheral;
|
use crate::rcc::RccPeripheral;
|
||||||
@ -486,20 +488,13 @@ impl<'d, T: Instance> DerefMut for Can<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
struct State {
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
|
||||||
use embassy_sync::channel::Channel;
|
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
|
||||||
|
|
||||||
use super::Envelope;
|
|
||||||
|
|
||||||
pub struct State {
|
|
||||||
pub tx_waker: AtomicWaker,
|
pub tx_waker: AtomicWaker,
|
||||||
pub err_waker: AtomicWaker,
|
pub err_waker: AtomicWaker,
|
||||||
pub rx_queue: Channel<CriticalSectionRawMutex, Envelope, 32>,
|
pub rx_queue: Channel<CriticalSectionRawMutex, Envelope, 32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
tx_waker: AtomicWaker::new(),
|
tx_waker: AtomicWaker::new(),
|
||||||
@ -507,16 +502,16 @@ pub(crate) mod sealed {
|
|||||||
rx_queue: Channel::new(),
|
rx_queue: Channel::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Instance {
|
trait SealedInstance {
|
||||||
fn regs() -> crate::pac::can::Can;
|
fn regs() -> crate::pac::can::Can;
|
||||||
fn state() -> &'static State;
|
fn state() -> &'static State;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CAN instance trait.
|
/// CAN instance trait.
|
||||||
pub trait Instance: sealed::Instance + RccPeripheral + 'static {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + RccPeripheral + 'static {
|
||||||
/// TX interrupt for this instance.
|
/// TX interrupt for this instance.
|
||||||
type TXInterrupt: crate::interrupt::typelevel::Interrupt;
|
type TXInterrupt: crate::interrupt::typelevel::Interrupt;
|
||||||
/// RX0 interrupt for this instance.
|
/// RX0 interrupt for this instance.
|
||||||
@ -534,14 +529,14 @@ unsafe impl<'d, T: Instance> crate::can::bx::Instance for BxcanInstance<'d, T> {
|
|||||||
|
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(can, $inst:ident) => {
|
(can, $inst:ident) => {
|
||||||
impl sealed::Instance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
|
|
||||||
fn regs() -> crate::pac::can::Can {
|
fn regs() -> crate::pac::can::Can {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state() -> &'static sealed::State {
|
fn state() -> &'static State {
|
||||||
static STATE: sealed::State = sealed::State::new();
|
static STATE: State = State::new();
|
||||||
&STATE
|
&STATE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,26 +140,6 @@ pub(crate) struct _TxBufferElement;
|
|||||||
impl generic::Readable for TxBufferElementHeader {}
|
impl generic::Readable for TxBufferElementHeader {}
|
||||||
impl generic::Writable for TxBufferElementHeader {}
|
impl generic::Writable for TxBufferElementHeader {}
|
||||||
|
|
||||||
/// FdCan Message RAM instance.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// It is only safe to implement this trait, when:
|
|
||||||
///
|
|
||||||
/// * The implementing type has ownership of the Message RAM, preventing any
|
|
||||||
/// other accesses to the register block.
|
|
||||||
/// * `MSG_RAM` is a pointer to the Message RAM block and can be safely accessed
|
|
||||||
/// for as long as ownership or a borrow of the implementing type is present.
|
|
||||||
pub unsafe trait Instance {
|
|
||||||
const MSG_RAM: *mut RegisterBlock;
|
|
||||||
fn msg_ram(&self) -> &RegisterBlock {
|
|
||||||
unsafe { &*Self::MSG_RAM }
|
|
||||||
}
|
|
||||||
fn msg_ram_mut(&mut self) -> &mut RegisterBlock {
|
|
||||||
unsafe { &mut *Self::MSG_RAM }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the RegisterBlock is the same size as on pg 1957 of RM0440.
|
// Ensure the RegisterBlock is the same size as on pg 1957 of RM0440.
|
||||||
static_assertions::assert_eq_size!(Filters, [u32; 28 + 16]);
|
static_assertions::assert_eq_size!(Filters, [u32; 28 + 16]);
|
||||||
static_assertions::assert_eq_size!(Receive, [u32; 54]);
|
static_assertions::assert_eq_size!(Receive, [u32; 54]);
|
||||||
|
@ -325,17 +325,6 @@ impl Registers {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disables the CAN interface and returns back the raw peripheral it was created from.
|
|
||||||
#[inline]
|
|
||||||
pub fn free(mut self) {
|
|
||||||
//self.disable_interrupts(Interrupts::all());
|
|
||||||
|
|
||||||
//TODO check this!
|
|
||||||
self.enter_init_mode();
|
|
||||||
self.set_power_down_mode(true);
|
|
||||||
//self.control.instance
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies the settings of a new FdCanConfig See [`FdCanConfig`]
|
/// Applies the settings of a new FdCanConfig See [`FdCanConfig`]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn apply_config(&mut self, config: FdCanConfig) {
|
pub fn apply_config(&mut self, config: FdCanConfig) {
|
||||||
@ -419,55 +408,6 @@ impl Registers {
|
|||||||
self.leave_init_mode(config);
|
self.leave_init_mode(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves out of ConfigMode and into InternalLoopbackMode
|
|
||||||
#[inline]
|
|
||||||
pub fn into_internal_loopback(mut self, config: FdCanConfig) {
|
|
||||||
self.set_loopback_mode(LoopbackMode::Internal);
|
|
||||||
self.leave_init_mode(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves out of ConfigMode and into ExternalLoopbackMode
|
|
||||||
#[inline]
|
|
||||||
pub fn into_external_loopback(mut self, config: FdCanConfig) {
|
|
||||||
self.set_loopback_mode(LoopbackMode::External);
|
|
||||||
self.leave_init_mode(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves out of ConfigMode and into RestrictedOperationMode
|
|
||||||
#[inline]
|
|
||||||
pub fn into_restricted(mut self, config: FdCanConfig) {
|
|
||||||
self.set_restricted_operations(true);
|
|
||||||
self.leave_init_mode(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves out of ConfigMode and into NormalOperationMode
|
|
||||||
#[inline]
|
|
||||||
pub fn into_normal(mut self, config: FdCanConfig) {
|
|
||||||
self.set_normal_operations(true);
|
|
||||||
self.leave_init_mode(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves out of ConfigMode and into BusMonitoringMode
|
|
||||||
#[inline]
|
|
||||||
pub fn into_bus_monitoring(mut self, config: FdCanConfig) {
|
|
||||||
self.set_bus_monitoring_mode(true);
|
|
||||||
self.leave_init_mode(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves out of ConfigMode and into Testmode
|
|
||||||
#[inline]
|
|
||||||
pub fn into_test_mode(mut self, config: FdCanConfig) {
|
|
||||||
self.set_test_mode(true);
|
|
||||||
self.leave_init_mode(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves out of ConfigMode and into PoweredDownmode
|
|
||||||
#[inline]
|
|
||||||
pub fn into_powered_down(mut self, config: FdCanConfig) {
|
|
||||||
self.set_power_down_mode(true);
|
|
||||||
self.leave_init_mode(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the bit timings.
|
/// Configures the bit timings.
|
||||||
///
|
///
|
||||||
/// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter
|
/// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter
|
||||||
@ -565,6 +505,7 @@ impl Registers {
|
|||||||
|
|
||||||
/// Configures and resets the timestamp counter
|
/// Configures and resets the timestamp counter
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[allow(unused)]
|
||||||
pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) {
|
pub fn set_timestamp_counter_source(&mut self, select: TimestampSource) {
|
||||||
#[cfg(stm32h7)]
|
#[cfg(stm32h7)]
|
||||||
let (tcp, tss) = match select {
|
let (tcp, tss) = match select {
|
||||||
|
@ -5,10 +5,11 @@ use core::task::Poll;
|
|||||||
|
|
||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender};
|
||||||
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use crate::can::fd::peripheral::Registers;
|
use crate::can::fd::peripheral::Registers;
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::AFType;
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::rcc::RccPeripheral;
|
use crate::rcc::RccPeripheral;
|
||||||
use crate::{interrupt, peripherals, Peripheral};
|
use crate::{interrupt, peripherals, Peripheral};
|
||||||
@ -53,8 +54,8 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &T::state().tx_mode {
|
match &T::state().tx_mode {
|
||||||
sealed::TxMode::NonBuffered(waker) => waker.wake(),
|
TxMode::NonBuffered(waker) => waker.wake(),
|
||||||
sealed::TxMode::ClassicBuffered(buf) => {
|
TxMode::ClassicBuffered(buf) => {
|
||||||
if !T::registers().tx_queue_is_full() {
|
if !T::registers().tx_queue_is_full() {
|
||||||
match buf.tx_receiver.try_receive() {
|
match buf.tx_receiver.try_receive() {
|
||||||
Ok(frame) => {
|
Ok(frame) => {
|
||||||
@ -64,7 +65,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sealed::TxMode::FdBuffered(buf) => {
|
TxMode::FdBuffered(buf) => {
|
||||||
if !T::registers().tx_queue_is_full() {
|
if !T::registers().tx_queue_is_full() {
|
||||||
match buf.tx_receiver.try_receive() {
|
match buf.tx_receiver.try_receive() {
|
||||||
Ok(frame) => {
|
Ok(frame) => {
|
||||||
@ -467,14 +468,14 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
|||||||
fn setup(self) -> Self {
|
fn setup(self) -> Self {
|
||||||
// We don't want interrupts being processed while we change modes.
|
// We don't want interrupts being processed while we change modes.
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
let rx_inner = sealed::ClassicBufferedRxInner {
|
let rx_inner = ClassicBufferedRxInner {
|
||||||
rx_sender: self.rx_buf.sender().into(),
|
rx_sender: self.rx_buf.sender().into(),
|
||||||
};
|
};
|
||||||
let tx_inner = sealed::ClassicBufferedTxInner {
|
let tx_inner = ClassicBufferedTxInner {
|
||||||
tx_receiver: self.tx_buf.receiver().into(),
|
tx_receiver: self.tx_buf.receiver().into(),
|
||||||
};
|
};
|
||||||
T::mut_state().rx_mode = sealed::RxMode::ClassicBuffered(rx_inner);
|
T::mut_state().rx_mode = RxMode::ClassicBuffered(rx_inner);
|
||||||
T::mut_state().tx_mode = sealed::TxMode::ClassicBuffered(tx_inner);
|
T::mut_state().tx_mode = TxMode::ClassicBuffered(tx_inner);
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -509,8 +510,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr
|
|||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
T::mut_state().rx_mode = sealed::RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
|
T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
|
||||||
T::mut_state().tx_mode = sealed::TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
|
T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -585,14 +586,14 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
|||||||
fn setup(self) -> Self {
|
fn setup(self) -> Self {
|
||||||
// We don't want interrupts being processed while we change modes.
|
// We don't want interrupts being processed while we change modes.
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
let rx_inner = sealed::FdBufferedRxInner {
|
let rx_inner = FdBufferedRxInner {
|
||||||
rx_sender: self.rx_buf.sender().into(),
|
rx_sender: self.rx_buf.sender().into(),
|
||||||
};
|
};
|
||||||
let tx_inner = sealed::FdBufferedTxInner {
|
let tx_inner = FdBufferedTxInner {
|
||||||
tx_receiver: self.tx_buf.receiver().into(),
|
tx_receiver: self.tx_buf.receiver().into(),
|
||||||
};
|
};
|
||||||
T::mut_state().rx_mode = sealed::RxMode::FdBuffered(rx_inner);
|
T::mut_state().rx_mode = RxMode::FdBuffered(rx_inner);
|
||||||
T::mut_state().tx_mode = sealed::TxMode::FdBuffered(tx_inner);
|
T::mut_state().tx_mode = TxMode::FdBuffered(tx_inner);
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -627,8 +628,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr
|
|||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
T::mut_state().rx_mode = sealed::RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
|
T::mut_state().rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
|
||||||
T::mut_state().tx_mode = sealed::TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
|
T::mut_state().tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -677,39 +678,28 @@ impl<'c, 'd, T: Instance> FdcanRx<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
struct ClassicBufferedRxInner {
|
||||||
use core::future::poll_fn;
|
rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>,
|
||||||
use core::task::Poll;
|
}
|
||||||
|
struct ClassicBufferedTxInner {
|
||||||
|
tx_receiver: DynamicReceiver<'static, ClassicFrame>,
|
||||||
|
}
|
||||||
|
|
||||||
use embassy_sync::channel::{DynamicReceiver, DynamicSender};
|
struct FdBufferedRxInner {
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>,
|
||||||
|
}
|
||||||
|
struct FdBufferedTxInner {
|
||||||
|
tx_receiver: DynamicReceiver<'static, FdFrame>,
|
||||||
|
}
|
||||||
|
|
||||||
use super::CanHeader;
|
enum RxMode {
|
||||||
use crate::can::_version::{BusError, Timestamp};
|
|
||||||
use crate::can::frame::{ClassicFrame, FdFrame};
|
|
||||||
|
|
||||||
pub struct ClassicBufferedRxInner {
|
|
||||||
pub rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>,
|
|
||||||
}
|
|
||||||
pub struct ClassicBufferedTxInner {
|
|
||||||
pub tx_receiver: DynamicReceiver<'static, ClassicFrame>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct FdBufferedRxInner {
|
|
||||||
pub rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>,
|
|
||||||
}
|
|
||||||
pub struct FdBufferedTxInner {
|
|
||||||
pub tx_receiver: DynamicReceiver<'static, FdFrame>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum RxMode {
|
|
||||||
NonBuffered(AtomicWaker),
|
NonBuffered(AtomicWaker),
|
||||||
ClassicBuffered(ClassicBufferedRxInner),
|
ClassicBuffered(ClassicBufferedRxInner),
|
||||||
FdBuffered(FdBufferedRxInner),
|
FdBuffered(FdBufferedRxInner),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RxMode {
|
impl RxMode {
|
||||||
pub fn register(&self, arg: &core::task::Waker) {
|
fn register(&self, arg: &core::task::Waker) {
|
||||||
match self {
|
match self {
|
||||||
RxMode::NonBuffered(waker) => waker.register(arg),
|
RxMode::NonBuffered(waker) => waker.register(arg),
|
||||||
_ => {
|
_ => {
|
||||||
@ -718,7 +708,7 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_interrupt<T: Instance>(&self, fifonr: usize) {
|
fn on_interrupt<T: Instance>(&self, fifonr: usize) {
|
||||||
T::regs().ir().write(|w| w.set_rfn(fifonr, true));
|
T::regs().ir().write(|w| w.set_rfn(fifonr, true));
|
||||||
match self {
|
match self {
|
||||||
RxMode::NonBuffered(waker) => {
|
RxMode::NonBuffered(waker) => {
|
||||||
@ -764,23 +754,23 @@ pub(crate) mod sealed {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
||||||
self.read_async::<T, _>().await
|
self.read_async::<T, _>().await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> {
|
async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> {
|
||||||
self.read_async::<T, _>().await
|
self.read_async::<T, _>().await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum TxMode {
|
enum TxMode {
|
||||||
NonBuffered(AtomicWaker),
|
NonBuffered(AtomicWaker),
|
||||||
ClassicBuffered(ClassicBufferedTxInner),
|
ClassicBuffered(ClassicBufferedTxInner),
|
||||||
FdBuffered(FdBufferedTxInner),
|
FdBuffered(FdBufferedTxInner),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TxMode {
|
impl TxMode {
|
||||||
pub fn register(&self, arg: &core::task::Waker) {
|
fn register(&self, arg: &core::task::Waker) {
|
||||||
match self {
|
match self {
|
||||||
TxMode::NonBuffered(waker) => {
|
TxMode::NonBuffered(waker) => {
|
||||||
waker.register(arg);
|
waker.register(arg);
|
||||||
@ -814,7 +804,7 @@ pub(crate) mod sealed {
|
|||||||
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
|
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
|
||||||
/// can be replaced, this call asynchronously waits for a frame to be successfully
|
/// can be replaced, this call asynchronously waits for a frame to be successfully
|
||||||
/// transmitted, then tries again.
|
/// transmitted, then tries again.
|
||||||
pub async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> {
|
async fn write<T: Instance>(&self, frame: &ClassicFrame) -> Option<ClassicFrame> {
|
||||||
self.write_generic::<T, _>(frame).await
|
self.write_generic::<T, _>(frame).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,21 +812,21 @@ pub(crate) mod sealed {
|
|||||||
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
|
/// frame is dropped from the mailbox, it is returned. If no lower-priority frames
|
||||||
/// can be replaced, this call asynchronously waits for a frame to be successfully
|
/// can be replaced, this call asynchronously waits for a frame to be successfully
|
||||||
/// transmitted, then tries again.
|
/// transmitted, then tries again.
|
||||||
pub async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> {
|
async fn write_fd<T: Instance>(&self, frame: &FdFrame) -> Option<FdFrame> {
|
||||||
self.write_generic::<T, _>(frame).await
|
self.write_generic::<T, _>(frame).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct State {
|
struct State {
|
||||||
pub rx_mode: RxMode,
|
pub rx_mode: RxMode,
|
||||||
pub tx_mode: TxMode,
|
pub tx_mode: TxMode,
|
||||||
pub ns_per_timer_tick: u64,
|
pub ns_per_timer_tick: u64,
|
||||||
|
|
||||||
pub err_waker: AtomicWaker,
|
pub err_waker: AtomicWaker,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub const fn new() -> Self {
|
const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
|
rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
|
||||||
tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
|
tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
|
||||||
@ -844,25 +834,24 @@ pub(crate) mod sealed {
|
|||||||
err_waker: AtomicWaker::new(),
|
err_waker: AtomicWaker::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Instance {
|
trait SealedInstance {
|
||||||
const MSG_RAM_OFFSET: usize;
|
const MSG_RAM_OFFSET: usize;
|
||||||
|
|
||||||
fn regs() -> &'static crate::pac::can::Fdcan;
|
fn regs() -> &'static crate::pac::can::Fdcan;
|
||||||
fn registers() -> crate::can::fd::peripheral::Registers;
|
fn registers() -> crate::can::fd::peripheral::Registers;
|
||||||
fn ram() -> &'static crate::pac::fdcanram::Fdcanram;
|
|
||||||
fn state() -> &'static State;
|
fn state() -> &'static State;
|
||||||
unsafe fn mut_state() -> &'static mut State;
|
unsafe fn mut_state() -> &'static mut State;
|
||||||
fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
|
fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instance trait
|
/// Instance trait
|
||||||
pub trait Instance: sealed::Instance + RccPeripheral + 'static {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + RccPeripheral + 'static {
|
||||||
/// Interrupt 0
|
/// Interrupt 0
|
||||||
type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
|
type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
|
||||||
/// Interrupt 0
|
/// Interrupt 1
|
||||||
type IT1Interrupt: crate::interrupt::typelevel::Interrupt;
|
type IT1Interrupt: crate::interrupt::typelevel::Interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,7 +860,7 @@ pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>);
|
|||||||
|
|
||||||
macro_rules! impl_fdcan {
|
macro_rules! impl_fdcan {
|
||||||
($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => {
|
($inst:ident, $msg_ram_inst:ident, $msg_ram_offset:literal) => {
|
||||||
impl sealed::Instance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
const MSG_RAM_OFFSET: usize = $msg_ram_offset;
|
const MSG_RAM_OFFSET: usize = $msg_ram_offset;
|
||||||
|
|
||||||
fn regs() -> &'static crate::pac::can::Fdcan {
|
fn regs() -> &'static crate::pac::can::Fdcan {
|
||||||
@ -880,14 +869,11 @@ macro_rules! impl_fdcan {
|
|||||||
fn registers() -> Registers {
|
fn registers() -> Registers {
|
||||||
Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET}
|
Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET}
|
||||||
}
|
}
|
||||||
fn ram() -> &'static crate::pac::fdcanram::Fdcanram {
|
unsafe fn mut_state() -> &'static mut State {
|
||||||
&crate::pac::$msg_ram_inst
|
static mut STATE: State = State::new();
|
||||||
|
&mut *core::ptr::addr_of_mut!(STATE)
|
||||||
}
|
}
|
||||||
unsafe fn mut_state() -> & 'static mut sealed::State {
|
fn state() -> &'static State {
|
||||||
static mut STATE: sealed::State = sealed::State::new();
|
|
||||||
& mut STATE
|
|
||||||
}
|
|
||||||
fn state() -> &'static sealed::State {
|
|
||||||
unsafe { peripherals::$inst::mut_state() }
|
unsafe { peripherals::$inst::mut_state() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
|
|||||||
|
|
||||||
use crate::pac::CRC as PAC_CRC;
|
use crate::pac::CRC as PAC_CRC;
|
||||||
use crate::peripherals::CRC;
|
use crate::peripherals::CRC;
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::SealedRccPeripheral;
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
|
|
||||||
/// CRC driver.
|
/// CRC driver.
|
||||||
|
@ -3,7 +3,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
|
|||||||
use crate::pac::crc::vals;
|
use crate::pac::crc::vals;
|
||||||
use crate::pac::CRC as PAC_CRC;
|
use crate::pac::CRC as PAC_CRC;
|
||||||
use crate::peripherals::CRC;
|
use crate::peripherals::CRC;
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::SealedRccPeripheral;
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
|
|
||||||
/// CRC driver.
|
/// CRC driver.
|
||||||
|
@ -1885,16 +1885,13 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedInstance {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub trait Instance {
|
|
||||||
fn regs() -> pac::cryp::Cryp;
|
fn regs() -> pac::cryp::Cryp;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CRYP instance trait.
|
/// CRYP instance trait.
|
||||||
pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
|
||||||
/// Interrupt for this CRYP instance.
|
/// Interrupt for this CRYP instance.
|
||||||
type Interrupt: interrupt::typelevel::Interrupt;
|
type Interrupt: interrupt::typelevel::Interrupt;
|
||||||
}
|
}
|
||||||
@ -1905,7 +1902,7 @@ foreach_interrupt!(
|
|||||||
type Interrupt = crate::interrupt::typelevel::$irq;
|
type Interrupt = crate::interrupt::typelevel::$irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sealed::Instance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
fn regs() -> crate::pac::cryp::Cryp {
|
fn regs() -> crate::pac::cryp::Cryp {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
_peri: impl Peripheral<P = T> + 'd,
|
_peri: impl Peripheral<P = T> + 'd,
|
||||||
dma: impl Peripheral<P = DMA> + 'd,
|
dma: impl Peripheral<P = DMA> + 'd,
|
||||||
pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::sealed::Pin> + 'd,
|
pin: impl Peripheral<P = impl DacPin<T, N> + crate::gpio::Pin> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(dma, pin);
|
into_ref!(dma, pin);
|
||||||
pin.set_as_analog();
|
pin.set_as_analog();
|
||||||
@ -392,8 +392,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
|
|||||||
_peri: impl Peripheral<P = T> + 'd,
|
_peri: impl Peripheral<P = T> + 'd,
|
||||||
dma_ch1: impl Peripheral<P = DMACh1> + 'd,
|
dma_ch1: impl Peripheral<P = DMACh1> + 'd,
|
||||||
dma_ch2: impl Peripheral<P = DMACh2> + 'd,
|
dma_ch2: impl Peripheral<P = DMACh2> + 'd,
|
||||||
pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::sealed::Pin> + 'd,
|
pin_ch1: impl Peripheral<P = impl DacPin<T, 1> + crate::gpio::Pin> + 'd,
|
||||||
pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::sealed::Pin> + 'd,
|
pin_ch2: impl Peripheral<P = impl DacPin<T, 2> + crate::gpio::Pin> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2);
|
into_ref!(dma_ch1, dma_ch2, pin_ch1, pin_ch2);
|
||||||
pin_ch1.set_as_analog();
|
pin_ch1.set_as_analog();
|
||||||
@ -488,14 +488,13 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedInstance {
|
||||||
pub trait Instance {
|
|
||||||
fn regs() -> &'static crate::pac::dac::Dac;
|
fn regs() -> &'static crate::pac::dac::Dac;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DAC instance.
|
/// DAC instance.
|
||||||
pub trait Instance: sealed::Instance + RccPeripheral + 'static {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + RccPeripheral + 'static {}
|
||||||
dma_trait!(DacDma1, Instance);
|
dma_trait!(DacDma1, Instance);
|
||||||
dma_trait!(DacDma2, Instance);
|
dma_trait!(DacDma2, Instance);
|
||||||
|
|
||||||
@ -504,7 +503,7 @@ pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {}
|
|||||||
|
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(dac, $inst:ident) => {
|
(dac, $inst:ident) => {
|
||||||
impl crate::dac::sealed::Instance for peripherals::$inst {
|
impl crate::dac::SealedInstance for peripherals::$inst {
|
||||||
fn regs() -> &'static crate::pac::dac::Dac {
|
fn regs() -> &'static crate::pac::dac::Dac {
|
||||||
&crate::pac::$inst
|
&crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
|
|||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use crate::dma::Transfer;
|
use crate::dma::Transfer;
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::{AFType, Speed};
|
||||||
use crate::gpio::Speed;
|
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::{interrupt, Peripheral};
|
use crate::{interrupt, Peripheral};
|
||||||
|
|
||||||
@ -431,14 +430,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod sealed {
|
trait SealedInstance: crate::rcc::RccPeripheral {
|
||||||
pub trait Instance: crate::rcc::RccPeripheral {
|
|
||||||
fn regs(&self) -> crate::pac::dcmi::Dcmi;
|
fn regs(&self) -> crate::pac::dcmi::Dcmi;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DCMI instance.
|
/// DCMI instance.
|
||||||
pub trait Instance: sealed::Instance + 'static {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + 'static {
|
||||||
/// Interrupt for this instance.
|
/// Interrupt for this instance.
|
||||||
type Interrupt: interrupt::typelevel::Interrupt;
|
type Interrupt: interrupt::typelevel::Interrupt;
|
||||||
}
|
}
|
||||||
@ -465,7 +463,7 @@ pin_trait!(PixClkPin, Instance);
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
macro_rules! impl_peripheral {
|
macro_rules! impl_peripheral {
|
||||||
($inst:ident, $irq:ident) => {
|
($inst:ident, $irq:ident) => {
|
||||||
impl sealed::Instance for crate::peripherals::$inst {
|
impl SealedInstance for crate::peripherals::$inst {
|
||||||
fn regs(&self) -> crate::pac::dcmi::Dcmi {
|
fn regs(&self) -> crate::pac::dcmi::Dcmi {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,7 @@ pub(crate) fn configure_dmamux(info: &DmamuxInfo, request: u8) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod dmamux_sealed {
|
pub(crate) trait SealedMuxChannel {}
|
||||||
pub trait MuxChannel {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// DMAMUX1 instance.
|
/// DMAMUX1 instance.
|
||||||
pub struct DMAMUX1;
|
pub struct DMAMUX1;
|
||||||
@ -30,14 +28,15 @@ pub struct DMAMUX1;
|
|||||||
pub struct DMAMUX2;
|
pub struct DMAMUX2;
|
||||||
|
|
||||||
/// DMAMUX channel trait.
|
/// DMAMUX channel trait.
|
||||||
pub trait MuxChannel: dmamux_sealed::MuxChannel {
|
#[allow(private_bounds)]
|
||||||
|
pub trait MuxChannel: SealedMuxChannel {
|
||||||
/// DMAMUX instance this channel is on.
|
/// DMAMUX instance this channel is on.
|
||||||
type Mux;
|
type Mux;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! dmamux_channel_impl {
|
macro_rules! dmamux_channel_impl {
|
||||||
($channel_peri:ident, $dmamux:ident) => {
|
($channel_peri:ident, $dmamux:ident) => {
|
||||||
impl crate::dma::dmamux_sealed::MuxChannel for crate::peripherals::$channel_peri {}
|
impl crate::dma::SealedMuxChannel for crate::peripherals::$channel_peri {}
|
||||||
impl crate::dma::MuxChannel for crate::peripherals::$channel_peri {
|
impl crate::dma::MuxChannel for crate::peripherals::$channel_peri {
|
||||||
type Mux = crate::dma::$dmamux;
|
type Mux = crate::dma::$dmamux;
|
||||||
}
|
}
|
||||||
|
@ -39,17 +39,18 @@ pub type Request = u8;
|
|||||||
#[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))]
|
#[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))]
|
||||||
pub type Request = ();
|
pub type Request = ();
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) trait SealedChannel {
|
||||||
pub trait Channel {
|
|
||||||
fn id(&self) -> u8;
|
fn id(&self) -> u8;
|
||||||
}
|
}
|
||||||
pub trait ChannelInterrupt {
|
|
||||||
|
pub(crate) trait ChannelInterrupt {
|
||||||
|
#[cfg_attr(not(feature = "rt"), allow(unused))]
|
||||||
unsafe fn on_irq();
|
unsafe fn on_irq();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DMA channel.
|
/// DMA channel.
|
||||||
pub trait Channel: sealed::Channel + Peripheral<P = Self> + Into<AnyChannel> + 'static {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Channel: SealedChannel + Peripheral<P = Self> + Into<AnyChannel> + 'static {
|
||||||
/// Type-erase (degrade) this pin into an `AnyChannel`.
|
/// Type-erase (degrade) this pin into an `AnyChannel`.
|
||||||
///
|
///
|
||||||
/// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which
|
/// This converts DMA channel singletons (`DMA1_CH3`, `DMA2_CH1`, ...), which
|
||||||
@ -63,12 +64,12 @@ pub trait Channel: sealed::Channel + Peripheral<P = Self> + Into<AnyChannel> + '
|
|||||||
|
|
||||||
macro_rules! dma_channel_impl {
|
macro_rules! dma_channel_impl {
|
||||||
($channel_peri:ident, $index:expr) => {
|
($channel_peri:ident, $index:expr) => {
|
||||||
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
impl crate::dma::SealedChannel for crate::peripherals::$channel_peri {
|
||||||
fn id(&self) -> u8 {
|
fn id(&self) -> u8 {
|
||||||
$index
|
$index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl crate::dma::sealed::ChannelInterrupt for crate::peripherals::$channel_peri {
|
impl crate::dma::ChannelInterrupt for crate::peripherals::$channel_peri {
|
||||||
unsafe fn on_irq() {
|
unsafe fn on_irq() {
|
||||||
crate::dma::AnyChannel { id: $index }.on_irq();
|
crate::dma::AnyChannel { id: $index }.on_irq();
|
||||||
}
|
}
|
||||||
@ -96,7 +97,7 @@ impl AnyChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sealed::Channel for AnyChannel {
|
impl SealedChannel for AnyChannel {
|
||||||
fn id(&self) -> u8 {
|
fn id(&self) -> u8 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,13 @@ impl WordSize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod sealed {
|
trait SealedWord {}
|
||||||
pub trait Word {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// DMA word trait.
|
/// DMA word trait.
|
||||||
///
|
///
|
||||||
/// This is implemented for u8, u16, u32, etc.
|
/// This is implemented for u8, u16, u32, etc.
|
||||||
pub trait Word: sealed::Word + Default + Copy + 'static {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Word: SealedWord + Default + Copy + 'static {
|
||||||
/// Word size
|
/// Word size
|
||||||
fn size() -> WordSize;
|
fn size() -> WordSize;
|
||||||
/// Amount of bits of this word size.
|
/// Amount of bits of this word size.
|
||||||
@ -36,7 +35,7 @@ pub trait Word: sealed::Word + Default + Copy + 'static {
|
|||||||
|
|
||||||
macro_rules! impl_word {
|
macro_rules! impl_word {
|
||||||
(_, $T:ident, $bits:literal, $size:ident) => {
|
(_, $T:ident, $bits:literal, $size:ident) => {
|
||||||
impl sealed::Word for $T {}
|
impl SealedWord for $T {}
|
||||||
impl Word for $T {
|
impl Word for $T {
|
||||||
fn bits() -> usize {
|
fn bits() -> usize {
|
||||||
$bits
|
$bits
|
||||||
|
@ -177,16 +177,15 @@ pub unsafe trait PHY {
|
|||||||
fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool;
|
fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedInstance {
|
||||||
pub trait Instance {
|
|
||||||
fn regs() -> crate::pac::eth::Eth;
|
fn regs() -> crate::pac::eth::Eth;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ethernet instance.
|
/// Ethernet instance.
|
||||||
pub trait Instance: sealed::Instance + RccPeripheral + Send + 'static {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + RccPeripheral + Send + 'static {}
|
||||||
|
|
||||||
impl sealed::Instance for crate::peripherals::ETH {
|
impl SealedInstance for crate::peripherals::ETH {
|
||||||
fn regs() -> crate::pac::eth::Eth {
|
fn regs() -> crate::pac::eth::Eth {
|
||||||
crate::pac::ETH
|
crate::pac::ETH
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,14 @@ use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress
|
|||||||
pub(crate) use self::rx_desc::{RDes, RDesRing};
|
pub(crate) use self::rx_desc::{RDes, RDesRing};
|
||||||
pub(crate) use self::tx_desc::{TDes, TDesRing};
|
pub(crate) use self::tx_desc::{TDes, TDesRing};
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::gpio::sealed::{AFType, Pin as __GpioPin};
|
use crate::gpio::{AFType, AnyPin, SealedPin};
|
||||||
use crate::gpio::AnyPin;
|
|
||||||
use crate::interrupt::InterruptExt;
|
use crate::interrupt::InterruptExt;
|
||||||
#[cfg(eth_v1a)]
|
#[cfg(eth_v1a)]
|
||||||
use crate::pac::AFIO;
|
use crate::pac::AFIO;
|
||||||
#[cfg(any(eth_v1b, eth_v1c))]
|
#[cfg(any(eth_v1b, eth_v1c))]
|
||||||
use crate::pac::SYSCFG;
|
use crate::pac::SYSCFG;
|
||||||
use crate::pac::{ETH, RCC};
|
use crate::pac::{ETH, RCC};
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::SealedRccPeripheral;
|
||||||
use crate::{interrupt, Peripheral};
|
use crate::{interrupt, Peripheral};
|
||||||
|
|
||||||
/// Interrupt handler.
|
/// Interrupt handler.
|
||||||
@ -149,8 +148,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
#[cfg(any(eth_v1b, eth_v1c))]
|
#[cfg(any(eth_v1b, eth_v1c))]
|
||||||
config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
|
config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
|
||||||
|
|
||||||
let dma = ETH.ethernet_dma();
|
let dma = T::regs().ethernet_dma();
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
|
|
||||||
// Reset and wait
|
// Reset and wait
|
||||||
dma.dmabmr().modify(|w| w.set_sr(true));
|
dma.dmabmr().modify(|w| w.set_sr(true));
|
||||||
@ -192,7 +191,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
|
|
||||||
// TODO MTU size setting not found for v1 ethernet, check if correct
|
// TODO MTU size setting not found for v1 ethernet, check if correct
|
||||||
|
|
||||||
let hclk = <T as RccPeripheral>::frequency();
|
let hclk = <T as SealedRccPeripheral>::frequency();
|
||||||
let hclk_mhz = hclk.0 / 1_000_000;
|
let hclk_mhz = hclk.0 / 1_000_000;
|
||||||
|
|
||||||
// Set the MDC clock frequency in the range 1MHz - 2.5MHz
|
// Set the MDC clock frequency in the range 1MHz - 2.5MHz
|
||||||
@ -235,8 +234,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
|
|
||||||
fence(Ordering::SeqCst);
|
fence(Ordering::SeqCst);
|
||||||
|
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
let dma = ETH.ethernet_dma();
|
let dma = T::regs().ethernet_dma();
|
||||||
|
|
||||||
mac.maccr().modify(|w| {
|
mac.maccr().modify(|w| {
|
||||||
w.set_re(true);
|
w.set_re(true);
|
||||||
@ -275,7 +274,7 @@ pub struct EthernetStationManagement<T: Instance> {
|
|||||||
|
|
||||||
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
||||||
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 {
|
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 {
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
|
|
||||||
mac.macmiiar().modify(|w| {
|
mac.macmiiar().modify(|w| {
|
||||||
w.set_pa(phy_addr);
|
w.set_pa(phy_addr);
|
||||||
@ -289,7 +288,7 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) {
|
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) {
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
|
|
||||||
mac.macmiidr().write(|w| w.set_md(val));
|
mac.macmiidr().write(|w| w.set_md(val));
|
||||||
mac.macmiiar().modify(|w| {
|
mac.macmiiar().modify(|w| {
|
||||||
@ -305,8 +304,8 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
|||||||
|
|
||||||
impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
|
impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let dma = ETH.ethernet_dma();
|
let dma = T::regs().ethernet_dma();
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
|
|
||||||
// Disable the TX DMA and wait for any previous transmissions to be completed
|
// Disable the TX DMA and wait for any previous transmissions to be completed
|
||||||
dma.dmaomr().modify(|w| w.set_st(St::STOPPED));
|
dma.dmaomr().modify(|w| w.set_st(St::STOPPED));
|
||||||
|
@ -7,11 +7,10 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
|
|||||||
|
|
||||||
pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
|
pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::gpio::sealed::{AFType, Pin as _};
|
use crate::gpio::{AFType, AnyPin, SealedPin as _, Speed};
|
||||||
use crate::gpio::{AnyPin, Speed};
|
|
||||||
use crate::interrupt::InterruptExt;
|
use crate::interrupt::InterruptExt;
|
||||||
use crate::pac::ETH;
|
use crate::pac::ETH;
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::SealedRccPeripheral;
|
||||||
use crate::{interrupt, Peripheral};
|
use crate::{interrupt, Peripheral};
|
||||||
|
|
||||||
/// Interrupt handler.
|
/// Interrupt handler.
|
||||||
@ -207,9 +206,9 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
phy: P,
|
phy: P,
|
||||||
mac_addr: [u8; 6],
|
mac_addr: [u8; 6],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let dma = ETH.ethernet_dma();
|
let dma = T::regs().ethernet_dma();
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
let mtl = ETH.ethernet_mtl();
|
let mtl = T::regs().ethernet_mtl();
|
||||||
|
|
||||||
// Reset and wait
|
// Reset and wait
|
||||||
dma.dmamr().modify(|w| w.set_swr(true));
|
dma.dmamr().modify(|w| w.set_swr(true));
|
||||||
@ -265,7 +264,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
w.set_rbsz(RX_BUFFER_SIZE as u16);
|
w.set_rbsz(RX_BUFFER_SIZE as u16);
|
||||||
});
|
});
|
||||||
|
|
||||||
let hclk = <T as RccPeripheral>::frequency();
|
let hclk = <T as SealedRccPeripheral>::frequency();
|
||||||
let hclk_mhz = hclk.0 / 1_000_000;
|
let hclk_mhz = hclk.0 / 1_000_000;
|
||||||
|
|
||||||
// Set the MDC clock frequency in the range 1MHz - 2.5MHz
|
// Set the MDC clock frequency in the range 1MHz - 2.5MHz
|
||||||
@ -296,9 +295,9 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
|||||||
|
|
||||||
fence(Ordering::SeqCst);
|
fence(Ordering::SeqCst);
|
||||||
|
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
let mtl = ETH.ethernet_mtl();
|
let mtl = T::regs().ethernet_mtl();
|
||||||
let dma = ETH.ethernet_dma();
|
let dma = T::regs().ethernet_dma();
|
||||||
|
|
||||||
mac.maccr().modify(|w| {
|
mac.maccr().modify(|w| {
|
||||||
w.set_re(true);
|
w.set_re(true);
|
||||||
@ -334,7 +333,7 @@ pub struct EthernetStationManagement<T: Instance> {
|
|||||||
|
|
||||||
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
||||||
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 {
|
fn smi_read(&mut self, phy_addr: u8, reg: u8) -> u16 {
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
|
|
||||||
mac.macmdioar().modify(|w| {
|
mac.macmdioar().modify(|w| {
|
||||||
w.set_pa(phy_addr);
|
w.set_pa(phy_addr);
|
||||||
@ -348,7 +347,7 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) {
|
fn smi_write(&mut self, phy_addr: u8, reg: u8, val: u16) {
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
|
|
||||||
mac.macmdiodr().write(|w| w.set_md(val));
|
mac.macmdiodr().write(|w| w.set_md(val));
|
||||||
mac.macmdioar().modify(|w| {
|
mac.macmdioar().modify(|w| {
|
||||||
@ -364,9 +363,9 @@ unsafe impl<T: Instance> StationManagement for EthernetStationManagement<T> {
|
|||||||
|
|
||||||
impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
|
impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let dma = ETH.ethernet_dma();
|
let dma = T::regs().ethernet_dma();
|
||||||
let mac = ETH.ethernet_mac();
|
let mac = T::regs().ethernet_mac();
|
||||||
let mtl = ETH.ethernet_mtl();
|
let mtl = T::regs().ethernet_mtl();
|
||||||
|
|
||||||
// Disable the TX DMA and wait for any previous transmissions to be completed
|
// Disable the TX DMA and wait for any previous transmissions to be completed
|
||||||
dma.dmactx_cr().modify(|w| w.set_st(false));
|
dma.dmactx_cr().modify(|w| w.set_st(false));
|
||||||
|
@ -330,12 +330,11 @@ macro_rules! impl_irq {
|
|||||||
|
|
||||||
foreach_exti_irq!(impl_irq);
|
foreach_exti_irq!(impl_irq);
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedChannel {}
|
||||||
pub trait Channel {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// EXTI channel trait.
|
/// EXTI channel trait.
|
||||||
pub trait Channel: sealed::Channel + Sized {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Channel: SealedChannel + Sized {
|
||||||
/// Get the EXTI channel number.
|
/// Get the EXTI channel number.
|
||||||
fn number(&self) -> u8;
|
fn number(&self) -> u8;
|
||||||
|
|
||||||
@ -359,7 +358,7 @@ pub struct AnyChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl_peripheral!(AnyChannel);
|
impl_peripheral!(AnyChannel);
|
||||||
impl sealed::Channel for AnyChannel {}
|
impl SealedChannel for AnyChannel {}
|
||||||
impl Channel for AnyChannel {
|
impl Channel for AnyChannel {
|
||||||
fn number(&self) -> u8 {
|
fn number(&self) -> u8 {
|
||||||
self.number
|
self.number
|
||||||
@ -368,7 +367,7 @@ impl Channel for AnyChannel {
|
|||||||
|
|
||||||
macro_rules! impl_exti {
|
macro_rules! impl_exti {
|
||||||
($type:ident, $number:expr) => {
|
($type:ident, $number:expr) => {
|
||||||
impl sealed::Channel for peripherals::$type {}
|
impl SealedChannel for peripherals::$type {}
|
||||||
impl Channel for peripherals::$type {
|
impl Channel for peripherals::$type {
|
||||||
fn number(&self) -> u8 {
|
fn number(&self) -> u8 {
|
||||||
$number
|
$number
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::TryInto;
|
|
||||||
use core::ptr::write_volatile;
|
use core::ptr::write_volatile;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::TryInto;
|
|
||||||
use core::ptr::write_volatile;
|
use core::ptr::write_volatile;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::TryInto;
|
|
||||||
use core::ptr::write_volatile;
|
use core::ptr::write_volatile;
|
||||||
use core::sync::atomic::{fence, AtomicBool, Ordering};
|
use core::sync::atomic::{fence, AtomicBool, Ordering};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::TryInto;
|
|
||||||
use core::ptr::write_volatile;
|
use core::ptr::write_volatile;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::TryInto;
|
|
||||||
use core::ptr::write_volatile;
|
use core::ptr::write_volatile;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::TryInto;
|
|
||||||
use core::ptr::write_volatile;
|
use core::ptr::write_volatile;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use core::convert::TryInto;
|
|
||||||
use core::ptr::write_volatile;
|
use core::ptr::write_volatile;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
|
@ -3,8 +3,7 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use embassy_hal_internal::into_ref;
|
use embassy_hal_internal::into_ref;
|
||||||
|
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::{AFType, Pull, Speed};
|
||||||
use crate::gpio::{Pull, Speed};
|
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
|
|
||||||
/// FMC driver
|
/// FMC driver
|
||||||
@ -44,7 +43,7 @@ where
|
|||||||
|
|
||||||
/// Get the kernel clock currently in use for this FMC instance.
|
/// Get the kernel clock currently in use for this FMC instance.
|
||||||
pub fn source_clock_hz(&self) -> u32 {
|
pub fn source_clock_hz(&self) -> u32 {
|
||||||
<T as crate::rcc::sealed::RccPeripheral>::frequency().0
|
<T as crate::rcc::SealedRccPeripheral>::frequency().0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn source_clock_hz(&self) -> u32 {
|
fn source_clock_hz(&self) -> u32 {
|
||||||
<T as crate::rcc::sealed::RccPeripheral>::frequency().0
|
<T as crate::rcc::SealedRccPeripheral>::frequency().0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,18 +200,17 @@ impl<'d, T: Instance> Fmc<'d, T> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedInstance: crate::rcc::SealedRccPeripheral {
|
||||||
pub trait Instance: crate::rcc::sealed::RccPeripheral {
|
|
||||||
const REGS: crate::pac::fmc::Fmc;
|
const REGS: crate::pac::fmc::Fmc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FMC instance trait.
|
/// FMC instance trait.
|
||||||
pub trait Instance: sealed::Instance + 'static {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + 'static {}
|
||||||
|
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(fmc, $inst:ident) => {
|
(fmc, $inst:ident) => {
|
||||||
impl crate::fmc::sealed::Instance for crate::peripherals::$inst {
|
impl crate::fmc::SealedInstance for crate::peripherals::$inst {
|
||||||
const REGS: crate::pac::fmc::Fmc = crate::pac::$inst;
|
const REGS: crate::pac::fmc::Fmc = crate::pac::$inst;
|
||||||
}
|
}
|
||||||
impl crate::fmc::Instance for crate::peripherals::$inst {}
|
impl crate::fmc::Instance for crate::peripherals::$inst {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use core::fmt::{Debug, Display, LowerHex};
|
use core::fmt::{Debug, Display, LowerHex};
|
||||||
|
|
||||||
@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
pub(crate) struct Bytes<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> Debug for Bytes<'a> {
|
impl<'a> Debug for Bytes<'a> {
|
||||||
|
@ -6,7 +6,6 @@ use core::convert::Infallible;
|
|||||||
use critical_section::CriticalSection;
|
use critical_section::CriticalSection;
|
||||||
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
|
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
|
||||||
|
|
||||||
use self::sealed::Pin as _;
|
|
||||||
use crate::pac::gpio::{self, vals};
|
use crate::pac::gpio::{self, vals};
|
||||||
use crate::{pac, peripherals, Peripheral};
|
use crate::{pac, peripherals, Peripheral};
|
||||||
|
|
||||||
@ -129,6 +128,18 @@ impl<'d> Flex<'d> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Put the pin into AF mode, unchecked.
|
||||||
|
///
|
||||||
|
/// This puts the pin into the AF mode, with the requested number, pull and speed. This is
|
||||||
|
/// completely unchecked, it can attach the pin to literally any peripheral, so use with care.
|
||||||
|
#[inline]
|
||||||
|
pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AFType, pull: Pull, speed: Speed) {
|
||||||
|
critical_section::with(|_| {
|
||||||
|
self.pin.set_as_af_pull(af_num, af_type, pull);
|
||||||
|
self.pin.set_speed(speed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Get whether the pin input level is high.
|
/// Get whether the pin input level is high.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_high(&self) -> bool {
|
pub fn is_high(&self) -> bool {
|
||||||
@ -508,32 +519,28 @@ pub enum OutputType {
|
|||||||
OpenDrain,
|
OpenDrain,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OutputType> for sealed::AFType {
|
impl From<OutputType> for AFType {
|
||||||
fn from(value: OutputType) -> Self {
|
fn from(value: OutputType) -> Self {
|
||||||
match value {
|
match value {
|
||||||
OutputType::OpenDrain => sealed::AFType::OutputOpenDrain,
|
OutputType::OpenDrain => AFType::OutputOpenDrain,
|
||||||
OutputType::PushPull => sealed::AFType::OutputPushPull,
|
OutputType::PushPull => AFType::OutputPushPull,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
/// Alternate function type settings
|
||||||
pub(crate) mod sealed {
|
#[derive(Debug, Copy, Clone)]
|
||||||
use super::*;
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub enum AFType {
|
||||||
/// Alternate function type settings
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
|
||||||
pub enum AFType {
|
|
||||||
/// Input
|
/// Input
|
||||||
Input,
|
Input,
|
||||||
/// Output, drive the pin both high or low.
|
/// Output, drive the pin both high or low.
|
||||||
OutputPushPull,
|
OutputPushPull,
|
||||||
/// Output, drive the pin low, or don't drive it at all if the output level is high.
|
/// Output, drive the pin low, or don't drive it at all if the output level is high.
|
||||||
OutputOpenDrain,
|
OutputOpenDrain,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Pin {
|
pub(crate) trait SealedPin {
|
||||||
fn pin_port(&self) -> u8;
|
fn pin_port(&self) -> u8;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -669,11 +676,11 @@ pub(crate) mod sealed {
|
|||||||
#[cfg(gpio_v2)]
|
#[cfg(gpio_v2)]
|
||||||
self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into()));
|
self.block().ospeedr().modify(|w| w.set_ospeedr(pin, speed.into()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GPIO pin trait.
|
/// GPIO pin trait.
|
||||||
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static {
|
||||||
/// EXTI channel assigned to this pin.
|
/// EXTI channel assigned to this pin.
|
||||||
///
|
///
|
||||||
/// For example, PC4 uses EXTI4.
|
/// For example, PC4 uses EXTI4.
|
||||||
@ -737,7 +744,7 @@ impl Pin for AnyPin {
|
|||||||
#[cfg(feature = "exti")]
|
#[cfg(feature = "exti")]
|
||||||
type ExtiChannel = crate::exti::AnyChannel;
|
type ExtiChannel = crate::exti::AnyChannel;
|
||||||
}
|
}
|
||||||
impl sealed::Pin for AnyPin {
|
impl SealedPin for AnyPin {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pin_port(&self) -> u8 {
|
fn pin_port(&self) -> u8 {
|
||||||
self.pin_port
|
self.pin_port
|
||||||
@ -752,7 +759,7 @@ foreach_pin!(
|
|||||||
#[cfg(feature = "exti")]
|
#[cfg(feature = "exti")]
|
||||||
type ExtiChannel = peripherals::$exti_ch;
|
type ExtiChannel = peripherals::$exti_ch;
|
||||||
}
|
}
|
||||||
impl sealed::Pin for peripherals::$pin_name {
|
impl SealedPin for peripherals::$pin_name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pin_port(&self) -> u8 {
|
fn pin_port(&self) -> u8 {
|
||||||
$port_num * 16 + $pin_num
|
$port_num * 16 + $pin_num
|
||||||
@ -769,7 +776,7 @@ foreach_pin!(
|
|||||||
|
|
||||||
pub(crate) unsafe fn init(_cs: CriticalSection) {
|
pub(crate) unsafe fn init(_cs: CriticalSection) {
|
||||||
#[cfg(afio)]
|
#[cfg(afio)]
|
||||||
<crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable_and_reset_with_cs(_cs);
|
<crate::peripherals::AFIO as crate::rcc::SealedRccPeripheral>::enable_and_reset_with_cs(_cs);
|
||||||
|
|
||||||
crate::_generated::init_gpio();
|
crate::_generated::init_gpio();
|
||||||
|
|
||||||
@ -833,6 +840,18 @@ impl<'d> embedded_hal_02::digital::v2::ToggleableOutputPin for Output<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'d> embedded_hal_02::digital::v2::InputPin for OutputOpenDrain<'d> {
|
||||||
|
type Error = Infallible;
|
||||||
|
|
||||||
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_high())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_low())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d> embedded_hal_02::digital::v2::OutputPin for OutputOpenDrain<'d> {
|
impl<'d> embedded_hal_02::digital::v2::OutputPin for OutputOpenDrain<'d> {
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
@ -1049,9 +1068,3 @@ impl<'d> embedded_hal_1::digital::StatefulOutputPin for Flex<'d> {
|
|||||||
Ok((*self).is_set_low())
|
Ok((*self).is_set_low())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Low-level GPIO manipulation.
|
|
||||||
#[cfg(feature = "unstable-pac")]
|
|
||||||
pub mod low_level {
|
|
||||||
pub use super::sealed::*;
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,7 @@ use crate::dma::NoDma;
|
|||||||
use crate::dma::Transfer;
|
use crate::dma::Transfer;
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::peripherals::HASH;
|
use crate::peripherals::HASH;
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::SealedRccPeripheral;
|
||||||
use crate::{interrupt, pac, peripherals, Peripheral};
|
use crate::{interrupt, pac, peripherals, Peripheral};
|
||||||
|
|
||||||
#[cfg(hash_v1)]
|
#[cfg(hash_v1)]
|
||||||
@ -561,16 +561,13 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedInstance {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub trait Instance {
|
|
||||||
fn regs() -> pac::hash::Hash;
|
fn regs() -> pac::hash::Hash;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HASH instance trait.
|
/// HASH instance trait.
|
||||||
pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
|
||||||
/// Interrupt for this HASH instance.
|
/// Interrupt for this HASH instance.
|
||||||
type Interrupt: interrupt::typelevel::Interrupt;
|
type Interrupt: interrupt::typelevel::Interrupt;
|
||||||
}
|
}
|
||||||
@ -581,7 +578,7 @@ foreach_interrupt!(
|
|||||||
type Interrupt = crate::interrupt::typelevel::$irq;
|
type Interrupt = crate::interrupt::typelevel::$irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sealed::Instance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
fn regs() -> crate::pac::hash::Hash {
|
fn regs() -> crate::pac::hash::Hash {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,7 @@ use core::marker::PhantomData;
|
|||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||||
pub use traits::Instance;
|
pub use traits::Instance;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
use crate::gpio::{AFType, AnyPin};
|
||||||
use crate::gpio::sealed::{AFType, Pin};
|
|
||||||
use crate::gpio::AnyPin;
|
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
|
|
||||||
@ -54,16 +52,13 @@ pub struct ChF<T: Instance> {
|
|||||||
phantom: PhantomData<T>,
|
phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod sealed {
|
trait SealedAdvancedChannel<T: Instance> {
|
||||||
use super::Instance;
|
|
||||||
|
|
||||||
pub trait AdvancedChannel<T: Instance> {
|
|
||||||
fn raw() -> usize;
|
fn raw() -> usize;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Advanced channel instance trait.
|
/// Advanced channel instance trait.
|
||||||
pub trait AdvancedChannel<T: Instance>: sealed::AdvancedChannel<T> {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait AdvancedChannel<T: Instance>: SealedAdvancedChannel<T> {}
|
||||||
|
|
||||||
/// HRTIM PWM pin.
|
/// HRTIM PWM pin.
|
||||||
pub struct PwmPin<'d, T, C> {
|
pub struct PwmPin<'d, T, C> {
|
||||||
@ -113,7 +108,7 @@ macro_rules! advanced_channel_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Instance> sealed::AdvancedChannel<T> for $channel<T> {
|
impl<T: Instance> SealedAdvancedChannel<T> for $channel<T> {
|
||||||
fn raw() -> usize {
|
fn raw() -> usize {
|
||||||
$ch_num
|
$ch_num
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::RccPeripheral;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
@ -72,12 +72,10 @@ impl Prescaler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) trait SealedInstance: RccPeripheral {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub trait Instance: RccPeripheral {
|
|
||||||
fn regs() -> crate::pac::hrtim::Hrtim;
|
fn regs() -> crate::pac::hrtim::Hrtim;
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
fn set_master_frequency(frequency: Hertz) {
|
fn set_master_frequency(frequency: Hertz) {
|
||||||
let f = frequency.0;
|
let f = frequency.0;
|
||||||
|
|
||||||
@ -151,15 +149,15 @@ pub(crate) mod sealed {
|
|||||||
w.set_dtr(dt_val as u16);
|
w.set_dtr(dt_val as u16);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HRTIM instance trait.
|
/// HRTIM instance trait.
|
||||||
pub trait Instance: sealed::Instance + 'static {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + 'static {}
|
||||||
|
|
||||||
foreach_interrupt! {
|
foreach_interrupt! {
|
||||||
($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
|
($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
|
||||||
impl sealed::Instance for crate::peripherals::$inst {
|
impl SealedInstance for crate::peripherals::$inst {
|
||||||
fn regs() -> crate::pac::hrtim::Hrtim {
|
fn regs() -> crate::pac::hrtim::Hrtim {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,7 @@ use embassy_sync::waitqueue::AtomicWaker;
|
|||||||
use embassy_time::{Duration, Instant};
|
use embassy_time::{Duration, Instant};
|
||||||
|
|
||||||
use crate::dma::NoDma;
|
use crate::dma::NoDma;
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::{AFType, Pull};
|
||||||
use crate::gpio::Pull;
|
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::{interrupt, peripherals};
|
use crate::{interrupt, peripherals};
|
||||||
@ -175,30 +174,27 @@ impl Timeout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
struct State {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub struct State {
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub waker: AtomicWaker,
|
waker: AtomicWaker,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub const fn new() -> Self {
|
const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
waker: AtomicWaker::new(),
|
waker: AtomicWaker::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Instance: crate::rcc::RccPeripheral {
|
trait SealedInstance: crate::rcc::RccPeripheral {
|
||||||
fn regs() -> crate::pac::i2c::I2c;
|
fn regs() -> crate::pac::i2c::I2c;
|
||||||
fn state() -> &'static State;
|
fn state() -> &'static State;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// I2C peripheral instance
|
/// I2C peripheral instance
|
||||||
pub trait Instance: sealed::Instance + 'static {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + 'static {
|
||||||
/// Event interrupt for this instance
|
/// Event interrupt for this instance
|
||||||
type EventInterrupt: interrupt::typelevel::Interrupt;
|
type EventInterrupt: interrupt::typelevel::Interrupt;
|
||||||
/// Error interrupt for this instance
|
/// Error interrupt for this instance
|
||||||
@ -234,13 +230,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInte
|
|||||||
|
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(i2c, $inst:ident) => {
|
(i2c, $inst:ident) => {
|
||||||
impl sealed::Instance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
fn regs() -> crate::pac::i2c::I2c {
|
fn regs() -> crate::pac::i2c::I2c {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state() -> &'static sealed::State {
|
fn state() -> &'static State {
|
||||||
static STATE: sealed::State = sealed::State::new();
|
static STATE: State = State::new();
|
||||||
&STATE
|
&STATE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,10 +307,10 @@ impl<'d, T: Instance> embedded_hal_1::i2c::I2c for I2c<'d, T, NoDma, NoDma> {
|
|||||||
|
|
||||||
fn transaction(
|
fn transaction(
|
||||||
&mut self,
|
&mut self,
|
||||||
_address: u8,
|
address: u8,
|
||||||
_operations: &mut [embedded_hal_1::i2c::Operation<'_>],
|
operations: &mut [embedded_hal_1::i2c::Operation<'_>],
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
todo!();
|
self.blocking_transaction(address, operations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +10,11 @@ use core::task::Poll;
|
|||||||
use embassy_embedded_hal::SetConfig;
|
use embassy_embedded_hal::SetConfig;
|
||||||
use embassy_futures::select::{select, Either};
|
use embassy_futures::select::{select, Either};
|
||||||
use embassy_hal_internal::drop::OnDrop;
|
use embassy_hal_internal::drop::OnDrop;
|
||||||
|
use embedded_hal_1::i2c::Operation;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::dma::Transfer;
|
use crate::dma::Transfer;
|
||||||
use crate::pac::i2c;
|
use crate::pac::i2c;
|
||||||
use crate::time::Hertz;
|
|
||||||
|
|
||||||
// /!\ /!\
|
// /!\ /!\
|
||||||
// /!\ Implementation note! /!\
|
// /!\ Implementation note! /!\
|
||||||
@ -41,6 +41,68 @@ pub unsafe fn on_interrupt<T: Instance>() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Frame type in I2C transaction.
|
||||||
|
///
|
||||||
|
/// This tells each method what kind of framing to use, to generate a (repeated) start condition (ST
|
||||||
|
/// or SR), and/or a stop condition (SP). For read operations, this also controls whether to send an
|
||||||
|
/// ACK or NACK after the last byte received.
|
||||||
|
///
|
||||||
|
/// For write operations, the following options are identical because they differ only in the (N)ACK
|
||||||
|
/// treatment relevant for read operations:
|
||||||
|
///
|
||||||
|
/// - `FirstFrame` and `FirstAndNextFrame`
|
||||||
|
/// - `NextFrame` and `LastFrameNoStop`
|
||||||
|
///
|
||||||
|
/// Abbreviations used below:
|
||||||
|
///
|
||||||
|
/// - `ST` = start condition
|
||||||
|
/// - `SR` = repeated start condition
|
||||||
|
/// - `SP` = stop condition
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum FrameOptions {
|
||||||
|
/// `[ST/SR]+[NACK]+[SP]` First frame (of this type) in operation and last frame overall in this
|
||||||
|
/// transaction.
|
||||||
|
FirstAndLastFrame,
|
||||||
|
/// `[ST/SR]+[NACK]` First frame of this type in transaction, last frame in a read operation but
|
||||||
|
/// not the last frame overall.
|
||||||
|
FirstFrame,
|
||||||
|
/// `[ST/SR]+[ACK]` First frame of this type in transaction, neither last frame overall nor last
|
||||||
|
/// frame in a read operation.
|
||||||
|
FirstAndNextFrame,
|
||||||
|
/// `[ACK]` Middle frame in a read operation (neither first nor last).
|
||||||
|
NextFrame,
|
||||||
|
/// `[NACK]+[SP]` Last frame overall in this transaction but not the first frame.
|
||||||
|
LastFrame,
|
||||||
|
/// `[NACK]` Last frame in a read operation but not last frame overall in this transaction.
|
||||||
|
LastFrameNoStop,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FrameOptions {
|
||||||
|
/// Sends start or repeated start condition before transfer.
|
||||||
|
fn send_start(self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::FirstAndLastFrame | Self::FirstFrame | Self::FirstAndNextFrame => true,
|
||||||
|
Self::NextFrame | Self::LastFrame | Self::LastFrameNoStop => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends stop condition after transfer.
|
||||||
|
fn send_stop(self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::FirstAndLastFrame | Self::LastFrame => true,
|
||||||
|
Self::FirstFrame | Self::FirstAndNextFrame | Self::NextFrame | Self::LastFrameNoStop => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends NACK after last byte received, indicating end of read operation.
|
||||||
|
fn send_nack(self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::FirstAndLastFrame | Self::FirstFrame | Self::LastFrame | Self::LastFrameNoStop => true,
|
||||||
|
Self::FirstAndNextFrame | Self::NextFrame => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
||||||
pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
|
pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
|
||||||
T::regs().cr1().modify(|reg| {
|
T::regs().cr1().modify(|reg| {
|
||||||
@ -124,7 +186,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
Ok(sr1)
|
Ok(sr1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_bytes(&mut self, addr: u8, bytes: &[u8], timeout: Timeout) -> Result<(), Error> {
|
fn write_bytes(&mut self, addr: u8, bytes: &[u8], timeout: Timeout, frame: FrameOptions) -> Result<(), Error> {
|
||||||
|
if frame.send_start() {
|
||||||
// Send a START condition
|
// Send a START condition
|
||||||
|
|
||||||
T::regs().cr1().modify(|reg| {
|
T::regs().cr1().modify(|reg| {
|
||||||
@ -158,12 +221,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
|
|
||||||
// Clear condition by reading SR2
|
// Clear condition by reading SR2
|
||||||
let _ = T::regs().sr2().read();
|
let _ = T::regs().sr2().read();
|
||||||
|
}
|
||||||
|
|
||||||
// Send bytes
|
// Send bytes
|
||||||
for c in bytes {
|
for c in bytes {
|
||||||
self.send_byte(*c, timeout)?;
|
self.send_byte(*c, timeout)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if frame.send_stop() {
|
||||||
|
// Send a STOP condition
|
||||||
|
T::regs().cr1().modify(|reg| reg.set_stop(true));
|
||||||
|
// Wait for STOP condition to transmit.
|
||||||
|
while T::regs().cr1().read().stop() {
|
||||||
|
timeout.check()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fallthrough is success
|
// Fallthrough is success
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -205,8 +278,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blocking_read_timeout(&mut self, addr: u8, buffer: &mut [u8], timeout: Timeout) -> Result<(), Error> {
|
fn blocking_read_timeout(
|
||||||
if let Some((last, buffer)) = buffer.split_last_mut() {
|
&mut self,
|
||||||
|
addr: u8,
|
||||||
|
buffer: &mut [u8],
|
||||||
|
timeout: Timeout,
|
||||||
|
frame: FrameOptions,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let Some((last, buffer)) = buffer.split_last_mut() else {
|
||||||
|
return Err(Error::Overrun);
|
||||||
|
};
|
||||||
|
|
||||||
|
if frame.send_start() {
|
||||||
// Send a START condition and set ACK bit
|
// Send a START condition and set ACK bit
|
||||||
T::regs().cr1().modify(|reg| {
|
T::regs().cr1().modify(|reg| {
|
||||||
reg.set_start(true);
|
reg.set_start(true);
|
||||||
@ -237,6 +320,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
|
|
||||||
// Clear condition by reading SR2
|
// Clear condition by reading SR2
|
||||||
let _ = T::regs().sr2().read();
|
let _ = T::regs().sr2().read();
|
||||||
|
}
|
||||||
|
|
||||||
// Receive bytes into buffer
|
// Receive bytes into buffer
|
||||||
for c in buffer {
|
for c in buffer {
|
||||||
@ -245,41 +329,36 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
|
|
||||||
// Prepare to send NACK then STOP after next byte
|
// Prepare to send NACK then STOP after next byte
|
||||||
T::regs().cr1().modify(|reg| {
|
T::regs().cr1().modify(|reg| {
|
||||||
|
if frame.send_nack() {
|
||||||
reg.set_ack(false);
|
reg.set_ack(false);
|
||||||
|
}
|
||||||
|
if frame.send_stop() {
|
||||||
reg.set_stop(true);
|
reg.set_stop(true);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Receive last byte
|
// Receive last byte
|
||||||
*last = self.recv_byte(timeout)?;
|
*last = self.recv_byte(timeout)?;
|
||||||
|
|
||||||
|
if frame.send_stop() {
|
||||||
// Wait for the STOP to be sent.
|
// Wait for the STOP to be sent.
|
||||||
while T::regs().cr1().read().stop() {
|
while T::regs().cr1().read().stop() {
|
||||||
timeout.check()?;
|
timeout.check()?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fallthrough is success
|
// Fallthrough is success
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
|
||||||
Err(Error::Overrun)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Blocking read.
|
/// Blocking read.
|
||||||
pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Error> {
|
||||||
self.blocking_read_timeout(addr, read, self.timeout())
|
self.blocking_read_timeout(addr, read, self.timeout(), FrameOptions::FirstAndLastFrame)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Blocking write.
|
/// Blocking write.
|
||||||
pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> {
|
pub fn blocking_write(&mut self, addr: u8, write: &[u8]) -> Result<(), Error> {
|
||||||
let timeout = self.timeout();
|
self.write_bytes(addr, write, self.timeout(), FrameOptions::FirstAndLastFrame)?;
|
||||||
|
|
||||||
self.write_bytes(addr, write, timeout)?;
|
|
||||||
// Send a STOP condition
|
|
||||||
T::regs().cr1().modify(|reg| reg.set_stop(true));
|
|
||||||
// Wait for STOP condition to transmit.
|
|
||||||
while T::regs().cr1().read().stop() {
|
|
||||||
timeout.check()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallthrough is success
|
// Fallthrough is success
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -287,10 +366,85 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
|
|
||||||
/// Blocking write, restart, read.
|
/// Blocking write, restart, read.
|
||||||
pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_write_read(&mut self, addr: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
|
||||||
|
// Check empty read buffer before starting transaction. Otherwise, we would not generate the
|
||||||
|
// stop condition below.
|
||||||
|
if read.is_empty() {
|
||||||
|
return Err(Error::Overrun);
|
||||||
|
}
|
||||||
|
|
||||||
let timeout = self.timeout();
|
let timeout = self.timeout();
|
||||||
|
|
||||||
self.write_bytes(addr, write, timeout)?;
|
self.write_bytes(addr, write, timeout, FrameOptions::FirstFrame)?;
|
||||||
self.blocking_read_timeout(addr, read, timeout)?;
|
self.blocking_read_timeout(addr, read, timeout, FrameOptions::FirstAndLastFrame)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blocking transaction with operations.
|
||||||
|
///
|
||||||
|
/// Consecutive operations of same type are merged. See [transaction contract] for details.
|
||||||
|
///
|
||||||
|
/// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
|
||||||
|
pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
|
||||||
|
// Check empty read buffer before starting transaction. Otherwise, we would not generate the
|
||||||
|
// stop condition below.
|
||||||
|
if operations.iter().any(|op| match op {
|
||||||
|
Operation::Read(read) => read.is_empty(),
|
||||||
|
Operation::Write(_) => false,
|
||||||
|
}) {
|
||||||
|
return Err(Error::Overrun);
|
||||||
|
}
|
||||||
|
|
||||||
|
let timeout = self.timeout();
|
||||||
|
|
||||||
|
let mut operations = operations.iter_mut();
|
||||||
|
|
||||||
|
let mut prev_op: Option<&mut Operation<'_>> = None;
|
||||||
|
let mut next_op = operations.next();
|
||||||
|
|
||||||
|
while let Some(op) = next_op {
|
||||||
|
next_op = operations.next();
|
||||||
|
|
||||||
|
// Check if this is the first frame of this type. This is the case for the first overall
|
||||||
|
// frame in the transaction and whenever the type of operation changes.
|
||||||
|
let first_frame =
|
||||||
|
match (prev_op.as_ref(), &op) {
|
||||||
|
(None, _) => true,
|
||||||
|
(Some(Operation::Read(_)), Operation::Write(_))
|
||||||
|
| (Some(Operation::Write(_)), Operation::Read(_)) => true,
|
||||||
|
(Some(Operation::Read(_)), Operation::Read(_))
|
||||||
|
| (Some(Operation::Write(_)), Operation::Write(_)) => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let frame = match (first_frame, next_op.as_ref()) {
|
||||||
|
// If this is the first frame of this type, we generate a (repeated) start condition
|
||||||
|
// but have to consider the next operation: if it is the last, we generate the final
|
||||||
|
// stop condition. Otherwise, we branch on the operation: with read operations, only
|
||||||
|
// the last byte overall (before a write operation or the end of the transaction) is
|
||||||
|
// to be NACK'd, i.e. if another read operation follows, we must ACK this last byte.
|
||||||
|
(true, None) => FrameOptions::FirstAndLastFrame,
|
||||||
|
// Make sure to keep sending ACK for last byte in read operation when it is followed
|
||||||
|
// by another consecutive read operation. If the current operation is write, this is
|
||||||
|
// identical to `FirstFrame`.
|
||||||
|
(true, Some(Operation::Read(_))) => FrameOptions::FirstAndNextFrame,
|
||||||
|
// Otherwise, send NACK for last byte (in read operation). (For write, this does not
|
||||||
|
// matter and could also be `FirstAndNextFrame`.)
|
||||||
|
(true, Some(Operation::Write(_))) => FrameOptions::FirstFrame,
|
||||||
|
|
||||||
|
// If this is not the first frame of its type, we do not generate a (repeated) start
|
||||||
|
// condition. Otherwise, we branch the same way as above.
|
||||||
|
(false, None) => FrameOptions::LastFrame,
|
||||||
|
(false, Some(Operation::Read(_))) => FrameOptions::NextFrame,
|
||||||
|
(false, Some(Operation::Write(_))) => FrameOptions::LastFrameNoStop,
|
||||||
|
};
|
||||||
|
|
||||||
|
match op {
|
||||||
|
Operation::Read(read) => self.blocking_read_timeout(addr, read, timeout, frame)?,
|
||||||
|
Operation::Write(write) => self.write_bytes(addr, write, timeout, frame)?,
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_op = Some(op);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@ use core::task::Poll;
|
|||||||
|
|
||||||
use embassy_embedded_hal::SetConfig;
|
use embassy_embedded_hal::SetConfig;
|
||||||
use embassy_hal_internal::drop::OnDrop;
|
use embassy_hal_internal::drop::OnDrop;
|
||||||
|
use embedded_hal_1::i2c::Operation;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::dma::Transfer;
|
use crate::dma::Transfer;
|
||||||
use crate::pac::i2c;
|
use crate::pac::i2c;
|
||||||
use crate::time::Hertz;
|
|
||||||
|
|
||||||
pub(crate) unsafe fn on_interrupt<T: Instance>() {
|
pub(crate) unsafe fn on_interrupt<T: Instance>() {
|
||||||
let regs = T::regs();
|
let regs = T::regs();
|
||||||
@ -579,6 +579,17 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
// Automatic Stop
|
// Automatic Stop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Blocking transaction with operations.
|
||||||
|
///
|
||||||
|
/// Consecutive operations of same type are merged. See [transaction contract] for details.
|
||||||
|
///
|
||||||
|
/// [transaction contract]: embedded_hal_1::i2c::I2c::transaction
|
||||||
|
pub fn blocking_transaction(&mut self, addr: u8, operations: &mut [Operation<'_>]) -> Result<(), Error> {
|
||||||
|
let _ = addr;
|
||||||
|
let _ = operations;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Blocking write multiple buffers.
|
/// Blocking write multiple buffers.
|
||||||
///
|
///
|
||||||
/// The buffers are concatenated in a single write transaction.
|
/// The buffers are concatenated in a single write transaction.
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
//! Inter-IC Sound (I2S)
|
//! Inter-IC Sound (I2S)
|
||||||
use embassy_hal_internal::into_ref;
|
use embassy_hal_internal::into_ref;
|
||||||
|
|
||||||
use crate::gpio::sealed::{AFType, Pin as _};
|
use crate::gpio::{AFType, AnyPin, SealedPin};
|
||||||
use crate::gpio::AnyPin;
|
|
||||||
use crate::pac::spi::vals;
|
use crate::pac::spi::vals;
|
||||||
use crate::spi::{Config as SpiConfig, *};
|
use crate::spi::{Config as SpiConfig, *};
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
|
@ -4,11 +4,12 @@ use core::future::poll_fn;
|
|||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use self::sealed::Instance;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::peripherals::IPCC;
|
use crate::peripherals::IPCC;
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::SealedRccPeripheral;
|
||||||
|
|
||||||
/// Interrupt handler.
|
/// Interrupt handler.
|
||||||
pub struct ReceiveInterruptHandler {}
|
pub struct ReceiveInterruptHandler {}
|
||||||
@ -207,7 +208,7 @@ impl Ipcc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sealed::Instance for crate::peripherals::IPCC {
|
impl SealedInstance for crate::peripherals::IPCC {
|
||||||
fn regs() -> crate::pac::ipcc::Ipcc {
|
fn regs() -> crate::pac::ipcc::Ipcc {
|
||||||
crate::pac::IPCC
|
crate::pac::IPCC
|
||||||
}
|
}
|
||||||
@ -216,24 +217,19 @@ impl sealed::Instance for crate::peripherals::IPCC {
|
|||||||
crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled));
|
crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state() -> &'static self::sealed::State {
|
fn state() -> &'static State {
|
||||||
static STATE: self::sealed::State = self::sealed::State::new();
|
static STATE: State = State::new();
|
||||||
&STATE
|
&STATE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
struct State {
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub struct State {
|
|
||||||
rx_wakers: [AtomicWaker; 6],
|
rx_wakers: [AtomicWaker; 6],
|
||||||
tx_wakers: [AtomicWaker; 6],
|
tx_wakers: [AtomicWaker; 6],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub const fn new() -> Self {
|
const fn new() -> Self {
|
||||||
const WAKER: AtomicWaker = AtomicWaker::new();
|
const WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -242,7 +238,7 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
|
const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
|
||||||
match channel {
|
match channel {
|
||||||
IpccChannel::Channel1 => &self.rx_wakers[0],
|
IpccChannel::Channel1 => &self.rx_wakers[0],
|
||||||
IpccChannel::Channel2 => &self.rx_wakers[1],
|
IpccChannel::Channel2 => &self.rx_wakers[1],
|
||||||
@ -253,7 +249,7 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
|
const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker {
|
||||||
match channel {
|
match channel {
|
||||||
IpccChannel::Channel1 => &self.tx_wakers[0],
|
IpccChannel::Channel1 => &self.tx_wakers[0],
|
||||||
IpccChannel::Channel2 => &self.tx_wakers[1],
|
IpccChannel::Channel2 => &self.tx_wakers[1],
|
||||||
@ -263,11 +259,10 @@ pub(crate) mod sealed {
|
|||||||
IpccChannel::Channel6 => &self.tx_wakers[5],
|
IpccChannel::Channel6 => &self.tx_wakers[5],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Instance: crate::rcc::RccPeripheral {
|
trait SealedInstance: crate::rcc::RccPeripheral {
|
||||||
fn regs() -> crate::pac::ipcc::Ipcc;
|
fn regs() -> crate::pac::ipcc::Ipcc;
|
||||||
fn set_cpu2(enabled: bool);
|
fn set_cpu2(enabled: bool);
|
||||||
fn state() -> &'static State;
|
fn state() -> &'static State;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -79,10 +79,8 @@ pub mod ucpd;
|
|||||||
pub mod uid;
|
pub mod uid;
|
||||||
#[cfg(usart)]
|
#[cfg(usart)]
|
||||||
pub mod usart;
|
pub mod usart;
|
||||||
#[cfg(usb)]
|
#[cfg(any(usb, otg))]
|
||||||
pub mod usb;
|
pub mod usb;
|
||||||
#[cfg(otg)]
|
|
||||||
pub mod usb_otg;
|
|
||||||
#[cfg(iwdg)]
|
#[cfg(iwdg)]
|
||||||
pub mod wdg;
|
pub mod wdg;
|
||||||
|
|
||||||
@ -107,10 +105,10 @@ pub use crate::_generated::interrupt;
|
|||||||
/// Example of how to bind one interrupt:
|
/// Example of how to bind one interrupt:
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// use embassy_stm32::{bind_interrupts, usb_otg, peripherals};
|
/// use embassy_stm32::{bind_interrupts, usb, peripherals};
|
||||||
///
|
///
|
||||||
/// bind_interrupts!(struct Irqs {
|
/// bind_interrupts!(struct Irqs {
|
||||||
/// OTG_FS => usb_otg::InterruptHandler<peripherals::USB_OTG_FS>;
|
/// OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
@ -160,7 +158,7 @@ pub(crate) use stm32_metapac as pac;
|
|||||||
use crate::interrupt::Priority;
|
use crate::interrupt::Priority;
|
||||||
#[cfg(feature = "rt")]
|
#[cfg(feature = "rt")]
|
||||||
pub use crate::pac::NVIC_PRIO_BITS;
|
pub use crate::pac::NVIC_PRIO_BITS;
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::SealedRccPeripheral;
|
||||||
|
|
||||||
/// `embassy-stm32` global configuration.
|
/// `embassy-stm32` global configuration.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
@ -81,8 +81,8 @@ impl<'d, T: Instance> OpAmp<'d, T> {
|
|||||||
/// [`OpAmpOutput`] is dropped.
|
/// [`OpAmpOutput`] is dropped.
|
||||||
pub fn buffer_ext(
|
pub fn buffer_ext(
|
||||||
&'d mut self,
|
&'d mut self,
|
||||||
in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::sealed::Pin>,
|
in_pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>,
|
||||||
out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::sealed::Pin> + 'd,
|
out_pin: impl Peripheral<P = impl OutputPin<T> + crate::gpio::Pin> + 'd,
|
||||||
gain: OpAmpGain,
|
gain: OpAmpGain,
|
||||||
) -> OpAmpOutput<'d, T> {
|
) -> OpAmpOutput<'d, T> {
|
||||||
into_ref!(in_pin);
|
into_ref!(in_pin);
|
||||||
@ -122,7 +122,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
|
|||||||
#[cfg(opamp_g4)]
|
#[cfg(opamp_g4)]
|
||||||
pub fn buffer_int(
|
pub fn buffer_int(
|
||||||
&'d mut self,
|
&'d mut self,
|
||||||
pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::sealed::Pin>,
|
pin: impl Peripheral<P = impl NonInvertingPin<T> + crate::gpio::Pin>,
|
||||||
gain: OpAmpGain,
|
gain: OpAmpGain,
|
||||||
) -> OpAmpInternalOutput<'d, T> {
|
) -> OpAmpInternalOutput<'d, T> {
|
||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
@ -166,37 +166,39 @@ impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opamp instance trait.
|
pub(crate) trait SealedInstance {
|
||||||
pub trait Instance: sealed::Instance + 'static {}
|
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
|
||||||
pub trait Instance {
|
|
||||||
fn regs() -> crate::pac::opamp::Opamp;
|
fn regs() -> crate::pac::opamp::Opamp;
|
||||||
}
|
|
||||||
|
|
||||||
pub trait NonInvertingPin<T: Instance> {
|
|
||||||
fn channel(&self) -> u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait InvertingPin<T: Instance> {
|
|
||||||
fn channel(&self) -> u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait OutputPin<T: Instance> {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) trait SealedNonInvertingPin<T: Instance> {
|
||||||
|
fn channel(&self) -> u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) trait SealedInvertingPin<T: Instance> {
|
||||||
|
#[allow(unused)]
|
||||||
|
fn channel(&self) -> u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) trait SealedOutputPin<T: Instance> {}
|
||||||
|
|
||||||
|
/// Opamp instance trait.
|
||||||
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + 'static {}
|
||||||
/// Non-inverting pin trait.
|
/// Non-inverting pin trait.
|
||||||
pub trait NonInvertingPin<T: Instance>: sealed::NonInvertingPin<T> {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait NonInvertingPin<T: Instance>: SealedNonInvertingPin<T> {}
|
||||||
/// Inverting pin trait.
|
/// Inverting pin trait.
|
||||||
pub trait InvertingPin<T: Instance>: sealed::InvertingPin<T> {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait InvertingPin<T: Instance>: SealedInvertingPin<T> {}
|
||||||
/// Output pin trait.
|
/// Output pin trait.
|
||||||
pub trait OutputPin<T: Instance>: sealed::OutputPin<T> {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait OutputPin<T: Instance>: SealedOutputPin<T> {}
|
||||||
|
|
||||||
macro_rules! impl_opamp_external_output {
|
macro_rules! impl_opamp_external_output {
|
||||||
($inst:ident, $adc:ident, $ch:expr) => {
|
($inst:ident, $adc:ident, $ch:expr) => {
|
||||||
foreach_adc!(
|
foreach_adc!(
|
||||||
($adc, $common_inst:ident, $adc_clock:ident) => {
|
($adc, $common_inst:ident, $adc_clock:ident) => {
|
||||||
impl<'d> crate::adc::sealed::AdcPin<crate::peripherals::$adc>
|
impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc>
|
||||||
for OpAmpOutput<'d, crate::peripherals::$inst>
|
for OpAmpOutput<'d, crate::peripherals::$inst>
|
||||||
{
|
{
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
@ -242,7 +244,7 @@ macro_rules! impl_opamp_internal_output {
|
|||||||
($inst:ident, $adc:ident, $ch:expr) => {
|
($inst:ident, $adc:ident, $ch:expr) => {
|
||||||
foreach_adc!(
|
foreach_adc!(
|
||||||
($adc, $common_inst:ident, $adc_clock:ident) => {
|
($adc, $common_inst:ident, $adc_clock:ident) => {
|
||||||
impl<'d> crate::adc::sealed::AdcPin<crate::peripherals::$adc>
|
impl<'d> crate::adc::SealedAdcPin<crate::peripherals::$adc>
|
||||||
for OpAmpInternalOutput<'d, crate::peripherals::$inst>
|
for OpAmpInternalOutput<'d, crate::peripherals::$inst>
|
||||||
{
|
{
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
@ -291,7 +293,7 @@ foreach_peripheral!(
|
|||||||
|
|
||||||
foreach_peripheral! {
|
foreach_peripheral! {
|
||||||
(opamp, $inst:ident) => {
|
(opamp, $inst:ident) => {
|
||||||
impl sealed::Instance for crate::peripherals::$inst {
|
impl SealedInstance for crate::peripherals::$inst {
|
||||||
fn regs() -> crate::pac::opamp::Opamp {
|
fn regs() -> crate::pac::opamp::Opamp {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
@ -306,7 +308,7 @@ foreach_peripheral! {
|
|||||||
macro_rules! impl_opamp_vp_pin {
|
macro_rules! impl_opamp_vp_pin {
|
||||||
($inst:ident, $pin:ident, $ch:expr) => {
|
($inst:ident, $pin:ident, $ch:expr) => {
|
||||||
impl crate::opamp::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {}
|
impl crate::opamp::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {}
|
||||||
impl crate::opamp::sealed::NonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {
|
impl crate::opamp::SealedNonInvertingPin<peripherals::$inst> for crate::peripherals::$pin {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
$ch
|
$ch
|
||||||
}
|
}
|
||||||
@ -318,6 +320,6 @@ macro_rules! impl_opamp_vp_pin {
|
|||||||
macro_rules! impl_opamp_vout_pin {
|
macro_rules! impl_opamp_vout_pin {
|
||||||
($inst:ident, $pin:ident) => {
|
($inst:ident, $pin:ident) => {
|
||||||
impl crate::opamp::OutputPin<peripherals::$inst> for crate::peripherals::$pin {}
|
impl crate::opamp::OutputPin<peripherals::$inst> for crate::peripherals::$pin {}
|
||||||
impl crate::opamp::sealed::OutputPin<peripherals::$inst> for crate::peripherals::$pin {}
|
impl crate::opamp::SealedOutputPin<peripherals::$inst> for crate::peripherals::$pin {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
|
|||||||
use enums::*;
|
use enums::*;
|
||||||
|
|
||||||
use crate::dma::Transfer;
|
use crate::dma::Transfer;
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::{AFType, AnyPin, Pull};
|
||||||
use crate::gpio::{AnyPin, Pull};
|
|
||||||
use crate::pac::quadspi::Quadspi as Regs;
|
use crate::pac::quadspi::Quadspi as Regs;
|
||||||
use crate::rcc::RccPeripheral;
|
use crate::rcc::RccPeripheral;
|
||||||
use crate::{peripherals, Peripheral};
|
use crate::{peripherals, Peripheral};
|
||||||
@ -381,16 +380,13 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedInstance {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub trait Instance {
|
|
||||||
const REGS: Regs;
|
const REGS: Regs;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// QSPI instance trait.
|
/// QSPI instance trait.
|
||||||
pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
|
||||||
|
|
||||||
pin_trait!(SckPin, Instance);
|
pin_trait!(SckPin, Instance);
|
||||||
pin_trait!(BK1D0Pin, Instance);
|
pin_trait!(BK1D0Pin, Instance);
|
||||||
@ -409,7 +405,7 @@ dma_trait!(QuadDma, Instance);
|
|||||||
|
|
||||||
foreach_peripheral!(
|
foreach_peripheral!(
|
||||||
(quadspi, $inst:ident) => {
|
(quadspi, $inst:ident) => {
|
||||||
impl sealed::Instance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
const REGS: Regs = crate::pac::$inst;
|
const REGS: Regs = crate::pac::$inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::pac::crs::vals::Syncsrc;
|
use crate::pac::crs::vals::Syncsrc;
|
||||||
use crate::pac::{CRS, RCC};
|
use crate::pac::{CRS, RCC};
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::SealedRccPeripheral;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
|
|
||||||
/// HSI48 speed
|
/// HSI48 speed
|
||||||
|
@ -2,8 +2,7 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use embassy_hal_internal::into_ref;
|
use embassy_hal_internal::into_ref;
|
||||||
|
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::{AFType, Speed};
|
||||||
use crate::gpio::Speed;
|
|
||||||
#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
|
#[cfg(not(any(stm32f1, rcc_f0v1, rcc_f3v1, rcc_f37)))]
|
||||||
pub use crate::pac::rcc::vals::Mcopre as McoPrescaler;
|
pub use crate::pac::rcc::vals::Mcopre as McoPrescaler;
|
||||||
#[cfg(not(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))]
|
#[cfg(not(any(rcc_f2, rcc_f410, rcc_f4, rcc_f7, rcc_h50, rcc_h5, rcc_h7ab, rcc_h7rm0433, rcc_h7)))]
|
||||||
@ -19,23 +18,25 @@ pub enum McoPrescaler {
|
|||||||
DIV1,
|
DIV1,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) trait SealedMcoInstance {}
|
||||||
pub trait McoInstance {
|
|
||||||
type Source;
|
|
||||||
unsafe fn apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait McoInstance: sealed::McoInstance + 'static {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait McoInstance: SealedMcoInstance + 'static {
|
||||||
|
type Source;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
unsafe fn _apply_clock_settings(source: Self::Source, prescaler: super::McoPrescaler);
|
||||||
|
}
|
||||||
|
|
||||||
pin_trait!(McoPin, McoInstance);
|
pin_trait!(McoPin, McoInstance);
|
||||||
|
|
||||||
macro_rules! impl_peri {
|
macro_rules! impl_peri {
|
||||||
($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => {
|
($peri:ident, $source:ident, $set_source:ident, $set_prescaler:ident) => {
|
||||||
impl sealed::McoInstance for peripherals::$peri {
|
impl SealedMcoInstance for peripherals::$peri {}
|
||||||
|
impl McoInstance for peripherals::$peri {
|
||||||
type Source = $source;
|
type Source = $source;
|
||||||
|
|
||||||
unsafe fn apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) {
|
unsafe fn _apply_clock_settings(source: Self::Source, _prescaler: McoPrescaler) {
|
||||||
#[cfg(not(any(stm32u5, stm32wba)))]
|
#[cfg(not(any(stm32u5, stm32wba)))]
|
||||||
let r = RCC.cfgr();
|
let r = RCC.cfgr();
|
||||||
#[cfg(any(stm32u5, stm32wba))]
|
#[cfg(any(stm32u5, stm32wba))]
|
||||||
@ -48,8 +49,6 @@ macro_rules! impl_peri {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl McoInstance for peripherals::$peri {}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +78,7 @@ impl<'d, T: McoInstance> Mco<'d, T> {
|
|||||||
into_ref!(pin);
|
into_ref!(pin);
|
||||||
|
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
T::apply_clock_settings(source, prescaler);
|
T::_apply_clock_settings(source, prescaler);
|
||||||
pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
|
pin.set_as_af(pin.af_num(), AFType::OutputPushPull);
|
||||||
pin.set_speed(Speed::VeryHigh);
|
pin.set_speed(Speed::VeryHigh);
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,7 @@ pub use bd::*;
|
|||||||
|
|
||||||
#[cfg(any(mco, mco1, mco2))]
|
#[cfg(any(mco, mco1, mco2))]
|
||||||
mod mco;
|
mod mco;
|
||||||
|
use critical_section::CriticalSection;
|
||||||
#[cfg(any(mco, mco1, mco2))]
|
#[cfg(any(mco, mco1, mco2))]
|
||||||
pub use mco::*;
|
pub use mco::*;
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ mod _version;
|
|||||||
pub use _version::*;
|
pub use _version::*;
|
||||||
|
|
||||||
pub use crate::_generated::{mux, Clocks};
|
pub use crate::_generated::{mux, Clocks};
|
||||||
|
use crate::time::Hertz;
|
||||||
|
|
||||||
#[cfg(feature = "low-power")]
|
#[cfg(feature = "low-power")]
|
||||||
/// Must be written within a critical section
|
/// Must be written within a critical section
|
||||||
@ -63,15 +65,7 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks {
|
|||||||
CLOCK_FREQS.assume_init_ref()
|
CLOCK_FREQS.assume_init_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable-pac")]
|
pub(crate) trait SealedRccPeripheral {
|
||||||
pub mod low_level {
|
|
||||||
pub use super::sealed::*;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
|
||||||
use critical_section::CriticalSection;
|
|
||||||
|
|
||||||
pub trait RccPeripheral {
|
|
||||||
fn frequency() -> crate::time::Hertz;
|
fn frequency() -> crate::time::Hertz;
|
||||||
fn enable_and_reset_with_cs(cs: CriticalSection);
|
fn enable_and_reset_with_cs(cs: CriticalSection);
|
||||||
fn disable_with_cs(cs: CriticalSection);
|
fn disable_with_cs(cs: CriticalSection);
|
||||||
@ -82,10 +76,10 @@ pub(crate) mod sealed {
|
|||||||
fn disable() {
|
fn disable() {
|
||||||
critical_section::with(|cs| Self::disable_with_cs(cs))
|
critical_section::with(|cs| Self::disable_with_cs(cs))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait RccPeripheral: sealed::RccPeripheral + 'static {}
|
#[allow(private_bounds)]
|
||||||
|
pub trait RccPeripheral: SealedRccPeripheral + 'static {}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
mod util {
|
mod util {
|
||||||
@ -116,3 +110,12 @@ mod util {
|
|||||||
Ok(Some(x))
|
Ok(Some(x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the kernel clocok frequency of the peripheral `T`.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the clock is not active.
|
||||||
|
pub fn frequency<T: RccPeripheral>() -> Hertz {
|
||||||
|
T::frequency()
|
||||||
|
}
|
||||||
|
@ -222,16 +222,13 @@ impl<'d, T: Instance> RngCore for Rng<'d, T> {
|
|||||||
|
|
||||||
impl<'d, T: Instance> CryptoRng for Rng<'d, T> {}
|
impl<'d, T: Instance> CryptoRng for Rng<'d, T> {}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedInstance {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub trait Instance {
|
|
||||||
fn regs() -> pac::rng::Rng;
|
fn regs() -> pac::rng::Rng;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RNG instance trait.
|
/// RNG instance trait.
|
||||||
pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send {
|
||||||
/// Interrupt for this RNG instance.
|
/// Interrupt for this RNG instance.
|
||||||
type Interrupt: interrupt::typelevel::Interrupt;
|
type Interrupt: interrupt::typelevel::Interrupt;
|
||||||
}
|
}
|
||||||
@ -242,7 +239,7 @@ foreach_interrupt!(
|
|||||||
type Interrupt = crate::interrupt::typelevel::$irq;
|
type Interrupt = crate::interrupt::typelevel::$irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sealed::Instance for peripherals::$inst {
|
impl SealedInstance for peripherals::$inst {
|
||||||
fn regs() -> crate::pac::rng::Rng {
|
fn regs() -> crate::pac::rng::Rng {
|
||||||
crate::pac::$inst
|
crate::pac::$inst
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "chrono")]
|
||||||
use core::convert::From;
|
use chrono::{Datelike, NaiveDate, Timelike, Weekday};
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
use chrono::{self, Datelike, NaiveDate, Timelike, Weekday};
|
|
||||||
|
|
||||||
#[cfg(any(feature = "defmt", feature = "time"))]
|
#[cfg(any(feature = "defmt", feature = "time"))]
|
||||||
use crate::peripherals::RTC;
|
use crate::peripherals::RTC;
|
||||||
#[cfg(any(feature = "defmt", feature = "time"))]
|
#[cfg(any(feature = "defmt", feature = "time"))]
|
||||||
use crate::rtc::sealed::Instance;
|
use crate::rtc::SealedInstance;
|
||||||
|
|
||||||
/// Represents an instant in time that can be substracted to compute a duration
|
/// Represents an instant in time that can be substracted to compute a duration
|
||||||
pub struct RtcInstant {
|
pub struct RtcInstant {
|
||||||
|
@ -31,7 +31,6 @@ pub use _version::*;
|
|||||||
use embassy_hal_internal::Peripheral;
|
use embassy_hal_internal::Peripheral;
|
||||||
|
|
||||||
use crate::peripherals::RTC;
|
use crate::peripherals::RTC;
|
||||||
use crate::rtc::sealed::Instance;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
@ -212,7 +211,7 @@ impl Rtc {
|
|||||||
/// Create a new RTC instance.
|
/// Create a new RTC instance.
|
||||||
pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
|
pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
|
||||||
#[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
|
#[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
|
||||||
<RTC as crate::rcc::sealed::RccPeripheral>::enable_and_reset();
|
<RTC as crate::rcc::SealedRccPeripheral>::enable_and_reset();
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
#[cfg(feature = "low-power")]
|
#[cfg(feature = "low-power")]
|
||||||
@ -437,7 +436,7 @@ impl Rtc {
|
|||||||
.fpr(0)
|
.fpr(0)
|
||||||
.modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
.modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
||||||
|
|
||||||
<RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
|
<RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,8 +448,8 @@ impl Rtc {
|
|||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
use crate::pac::EXTI;
|
use crate::pac::EXTI;
|
||||||
|
|
||||||
<RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
|
<RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
|
||||||
unsafe { <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::enable() };
|
unsafe { <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::enable() };
|
||||||
|
|
||||||
EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
EXTI.rtsr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
||||||
EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
EXTI.imr(0).modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
|
||||||
@ -477,10 +476,7 @@ pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 {
|
|||||||
tmp + (value & 0x0F)
|
tmp + (value & 0x0F)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
trait SealedInstance {
|
||||||
use crate::pac::rtc::Rtc;
|
|
||||||
|
|
||||||
pub trait Instance {
|
|
||||||
const BACKUP_REGISTER_COUNT: usize;
|
const BACKUP_REGISTER_COUNT: usize;
|
||||||
|
|
||||||
#[cfg(feature = "low-power")]
|
#[cfg(feature = "low-power")]
|
||||||
@ -489,7 +485,7 @@ pub(crate) mod sealed {
|
|||||||
#[cfg(feature = "low-power")]
|
#[cfg(feature = "low-power")]
|
||||||
type WakeupInterrupt: crate::interrupt::typelevel::Interrupt;
|
type WakeupInterrupt: crate::interrupt::typelevel::Interrupt;
|
||||||
|
|
||||||
fn regs() -> Rtc {
|
fn regs() -> crate::pac::rtc::Rtc {
|
||||||
crate::pac::RTC
|
crate::pac::RTC
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,14 +493,13 @@ pub(crate) mod sealed {
|
|||||||
///
|
///
|
||||||
/// The registers retain their values during wakes from standby mode or system resets. They also
|
/// The registers retain their values during wakes from standby mode or system resets. They also
|
||||||
/// retain their value when Vdd is switched off as long as V_BAT is powered.
|
/// retain their value when Vdd is switched off as long as V_BAT is powered.
|
||||||
fn read_backup_register(rtc: &Rtc, register: usize) -> Option<u32>;
|
fn read_backup_register(rtc: &crate::pac::rtc::Rtc, register: usize) -> Option<u32>;
|
||||||
|
|
||||||
/// Set content of the backup register.
|
/// Set content of the backup register.
|
||||||
///
|
///
|
||||||
/// The registers retain their values during wakes from standby mode or system resets. They also
|
/// The registers retain their values during wakes from standby mode or system resets. They also
|
||||||
/// retain their value when Vdd is switched off as long as V_BAT is powered.
|
/// retain their value when Vdd is switched off as long as V_BAT is powered.
|
||||||
fn write_backup_register(rtc: &Rtc, register: usize, value: u32);
|
fn write_backup_register(rtc: &crate::pac::rtc::Rtc, register: usize, value: u32);
|
||||||
|
|
||||||
// fn apply_config(&mut self, rtc_config: RtcConfig);
|
// fn apply_config(&mut self, rtc_config: RtcConfig);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user