Merge branch 'embassy-rs:main' into feat/radio-ieee802154
This commit is contained in:
commit
f451168842
41 changed files with 1994 additions and 543 deletions
docs/modules/ROOT/pages
embassy-executor
embassy-stm32
examples
stm32f334/src/bin
stm32f7
stm32g0/src/bin
stm32g4/src/bin
stm32h5/src/bin
stm32h7/src/bin
stm32l4/src/bin
tests/stm32
|
@ -17,22 +17,13 @@ The first thing you’ll notice are two attributes at the top of the file. These
|
|||
include::example$basic/src/main.rs[lines="1..2"]
|
||||
----
|
||||
|
||||
=== Rust Nightly
|
||||
|
||||
The next declaration is a Rust Unstable feature, which means that Embassy requires Rust Nightly:
|
||||
|
||||
[source,rust]
|
||||
----
|
||||
include::example$basic/src/main.rs[lines="3"]
|
||||
----
|
||||
|
||||
=== Dealing with errors
|
||||
|
||||
Then, what follows are some declarations on how to deal with panics and faults. During development, a good practice is to rely on `defmt-rtt` and `panic-probe` to print diagnostics to the terminal:
|
||||
|
||||
[source,rust]
|
||||
----
|
||||
include::example$basic/src/main.rs[lines="10"]
|
||||
include::example$basic/src/main.rs[lines="8"]
|
||||
----
|
||||
|
||||
=== Task declaration
|
||||
|
@ -41,7 +32,7 @@ After a bit of import declaration, the tasks run by the application should be de
|
|||
|
||||
[source,rust]
|
||||
----
|
||||
include::example$basic/src/main.rs[lines="12..20"]
|
||||
include::example$basic/src/main.rs[lines="10..18"]
|
||||
----
|
||||
|
||||
An embassy task must be declared `async`, and may NOT take generic arguments. In this case, we are handed the LED that should be blinked and the interval of the blinking.
|
||||
|
@ -56,7 +47,7 @@ We then initialize the HAL with a default config, which gives us a `Peripherals`
|
|||
|
||||
[source,rust]
|
||||
----
|
||||
include::example$basic/src/main.rs[lines="22..-1"]
|
||||
include::example$basic/src/main.rs[lines="20..-1"]
|
||||
----
|
||||
|
||||
What happens when the `blinker` task has been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy_executor::main]` macro. The macro does the following:
|
||||
|
|
|
@ -40,8 +40,7 @@ critical-section = "1.1"
|
|||
|
||||
document-features = "0.2.7"
|
||||
|
||||
# needed for riscv and avr
|
||||
# remove when https://github.com/rust-lang/rust/pull/114499 lands on stable (on 1.76)
|
||||
# needed for AVR
|
||||
portable-atomic = { version = "1.5", optional = true }
|
||||
|
||||
# arch-cortex-m dependencies
|
||||
|
@ -78,7 +77,7 @@ arch-std = ["_arch", "critical-section/std"]
|
|||
## Cortex-M
|
||||
arch-cortex-m = ["_arch", "dep:cortex-m"]
|
||||
## RISC-V 32
|
||||
arch-riscv32 = ["_arch", "dep:portable-atomic"]
|
||||
arch-riscv32 = ["_arch"]
|
||||
## WASM
|
||||
arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"]
|
||||
## AVR
|
||||
|
|
|
@ -6,9 +6,9 @@ pub use thread::*;
|
|||
#[cfg(feature = "executor-thread")]
|
||||
mod thread {
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
pub use embassy_executor_macros::main_riscv as main;
|
||||
use portable_atomic::{AtomicBool, Ordering};
|
||||
|
||||
use crate::{raw, Spawner};
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ rand_core = "0.6.3"
|
|||
sdio-host = "0.5.0"
|
||||
critical-section = "1.1"
|
||||
#stm32-metapac = { version = "15" }
|
||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4a0bcec33362449fb733c066936d25cbabab396a" }
|
||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e853cf944b150898312984d092d63926970c340d" }
|
||||
vcell = "0.1.3"
|
||||
bxcan = "0.7.0"
|
||||
nb = "1.0.0"
|
||||
|
@ -94,7 +94,7 @@ critical-section = { version = "1.1", features = ["std"] }
|
|||
proc-macro2 = "1.0.36"
|
||||
quote = "1.0.15"
|
||||
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
|
||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4a0bcec33362449fb733c066936d25cbabab396a", default-features = false, features = ["metadata"]}
|
||||
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e853cf944b150898312984d092d63926970c340d", default-features = false, features = ["metadata"]}
|
||||
|
||||
|
||||
[features]
|
||||
|
|
|
@ -5,7 +5,9 @@ use std::{env, fs};
|
|||
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccKernelClock, StopMode, METADATA};
|
||||
use stm32_metapac::metadata::{
|
||||
MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, METADATA,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
|
@ -374,12 +376,130 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
let force_refcount = HashSet::from(["usart"]);
|
||||
let mut refcount_statics = BTreeSet::new();
|
||||
struct ClockGen<'a> {
|
||||
rcc_registers: &'a PeripheralRegisters,
|
||||
chained_muxes: HashMap<&'a str, &'a PeripheralRccRegister>,
|
||||
force_refcount: HashSet<&'a str>,
|
||||
|
||||
let mut clock_names = BTreeSet::new();
|
||||
refcount_statics: BTreeSet<Ident>,
|
||||
clock_names: BTreeSet<String>,
|
||||
muxes: BTreeSet<(Ident, Ident, Ident)>,
|
||||
}
|
||||
|
||||
let mut rcc_cfgr_regs = BTreeSet::new();
|
||||
let mut clock_gen = ClockGen {
|
||||
rcc_registers,
|
||||
chained_muxes: HashMap::new(),
|
||||
force_refcount: HashSet::from(["usart"]),
|
||||
|
||||
refcount_statics: BTreeSet::new(),
|
||||
clock_names: BTreeSet::new(),
|
||||
muxes: BTreeSet::new(),
|
||||
};
|
||||
if chip_name.starts_with("stm32h5") {
|
||||
clock_gen.chained_muxes.insert(
|
||||
"PER",
|
||||
&PeripheralRccRegister {
|
||||
register: "CCIPR5",
|
||||
field: "PERSEL",
|
||||
},
|
||||
);
|
||||
}
|
||||
if chip_name.starts_with("stm32h7") {
|
||||
clock_gen.chained_muxes.insert(
|
||||
"PER",
|
||||
&PeripheralRccRegister {
|
||||
register: "D1CCIPR",
|
||||
field: "PERSEL",
|
||||
},
|
||||
);
|
||||
}
|
||||
if chip_name.starts_with("stm32u5") {
|
||||
clock_gen.chained_muxes.insert(
|
||||
"ICLK",
|
||||
&PeripheralRccRegister {
|
||||
register: "CCIPR1",
|
||||
field: "ICLKSEL",
|
||||
},
|
||||
);
|
||||
}
|
||||
if chip_name.starts_with("stm32wb") && !chip_name.starts_with("stm32wba") {
|
||||
clock_gen.chained_muxes.insert(
|
||||
"CLK48",
|
||||
&PeripheralRccRegister {
|
||||
register: "CCIPR",
|
||||
field: "CLK48SEL",
|
||||
},
|
||||
);
|
||||
}
|
||||
if chip_name.starts_with("stm32f7") {
|
||||
clock_gen.chained_muxes.insert(
|
||||
"CLK48",
|
||||
&PeripheralRccRegister {
|
||||
register: "DCKCFGR2",
|
||||
field: "CLK48SEL",
|
||||
},
|
||||
);
|
||||
}
|
||||
if chip_name.starts_with("stm32f4") && !chip_name.starts_with("stm32f410") {
|
||||
clock_gen.chained_muxes.insert(
|
||||
"CLK48",
|
||||
&PeripheralRccRegister {
|
||||
register: "DCKCFGR",
|
||||
field: "CLK48SEL",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
impl<'a> ClockGen<'a> {
|
||||
fn gen_clock(&mut self, name: &str) -> TokenStream {
|
||||
let clock_name = format_ident!("{}", name.to_ascii_lowercase());
|
||||
self.clock_names.insert(name.to_ascii_lowercase());
|
||||
quote!( unsafe { crate::rcc::get_freqs().#clock_name.unwrap() } )
|
||||
}
|
||||
|
||||
fn gen_mux(&mut self, mux: &PeripheralRccRegister) -> TokenStream {
|
||||
let ir = &self.rcc_registers.ir;
|
||||
let fieldset_name = mux.register.to_ascii_lowercase();
|
||||
let fieldset = ir
|
||||
.fieldsets
|
||||
.iter()
|
||||
.find(|i| i.name.eq_ignore_ascii_case(&fieldset_name))
|
||||
.unwrap();
|
||||
let field_name = mux.field.to_ascii_lowercase();
|
||||
let field = fieldset.fields.iter().find(|i| i.name == field_name).unwrap();
|
||||
let enum_name = field.enumm.unwrap();
|
||||
let enumm = ir.enums.iter().find(|i| i.name == enum_name).unwrap();
|
||||
|
||||
let fieldset_name = format_ident!("{}", fieldset_name);
|
||||
let field_name = format_ident!("{}", field_name);
|
||||
let enum_name = format_ident!("{}", enum_name);
|
||||
|
||||
self.muxes
|
||||
.insert((fieldset_name.clone(), field_name.clone(), enum_name.clone()));
|
||||
|
||||
let mut match_arms = TokenStream::new();
|
||||
|
||||
for v in enumm.variants.iter().filter(|v| v.name != "DISABLE") {
|
||||
let variant_name = format_ident!("{}", v.name);
|
||||
let expr = if let Some(mux) = self.chained_muxes.get(&v.name) {
|
||||
self.gen_mux(mux)
|
||||
} else {
|
||||
self.gen_clock(&v.name)
|
||||
};
|
||||
match_arms.extend(quote! {
|
||||
crate::pac::rcc::vals::#enum_name::#variant_name => #expr,
|
||||
});
|
||||
}
|
||||
|
||||
quote! {
|
||||
match crate::pac::RCC.#fieldset_name().read().#field_name() {
|
||||
#match_arms
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for p in METADATA.peripherals {
|
||||
if !singletons.contains(&p.name.to_string()) {
|
||||
|
@ -416,12 +536,12 @@ fn main() {
|
|||
let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase());
|
||||
|
||||
let refcount =
|
||||
force_refcount.contains(ptype) || *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1;
|
||||
clock_gen.force_refcount.contains(ptype) || *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1;
|
||||
let (before_enable, before_disable) = if refcount {
|
||||
let refcount_static =
|
||||
format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase());
|
||||
|
||||
refcount_statics.insert(refcount_static.clone());
|
||||
clock_gen.refcount_statics.insert(refcount_static.clone());
|
||||
|
||||
(
|
||||
quote! {
|
||||
|
@ -442,63 +562,12 @@ fn main() {
|
|||
};
|
||||
|
||||
let clock_frequency = match &rcc.kernel_clock {
|
||||
PeripheralRccKernelClock::Mux(mux) => {
|
||||
let ir = &rcc_registers.ir;
|
||||
let fieldset_name = mux.register.to_ascii_lowercase();
|
||||
let fieldset = ir
|
||||
.fieldsets
|
||||
.iter()
|
||||
.find(|i| i.name.eq_ignore_ascii_case(&fieldset_name))
|
||||
.unwrap();
|
||||
let field_name = mux.field.to_ascii_lowercase();
|
||||
let field = fieldset.fields.iter().find(|i| i.name == field_name).unwrap();
|
||||
let enum_name = field.enumm.unwrap();
|
||||
let enumm = ir.enums.iter().find(|i| i.name == enum_name).unwrap();
|
||||
|
||||
let fieldset_name = format_ident!("{}", fieldset_name);
|
||||
let field_name = format_ident!("{}", field_name);
|
||||
let enum_name = format_ident!("{}", enum_name);
|
||||
|
||||
rcc_cfgr_regs.insert((fieldset_name.clone(), field_name.clone(), enum_name.clone()));
|
||||
|
||||
let match_arms: TokenStream = enumm
|
||||
.variants
|
||||
.iter()
|
||||
.filter(|v| v.name != "DISABLE")
|
||||
.map(|v| {
|
||||
let variant_name = format_ident!("{}", v.name);
|
||||
let clock_name = format_ident!("{}", v.name.to_ascii_lowercase());
|
||||
clock_names.insert(v.name.to_ascii_lowercase());
|
||||
quote! {
|
||||
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
quote! {
|
||||
use crate::pac::rcc::vals::#enum_name;
|
||||
|
||||
#[allow(unreachable_patterns)]
|
||||
match crate::pac::RCC.#fieldset_name().read().#field_name() {
|
||||
#match_arms
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
PeripheralRccKernelClock::Clock(clock) => {
|
||||
let clock = clock.to_ascii_lowercase();
|
||||
let clock_name = format_ident!("{}", clock);
|
||||
clock_names.insert(clock.to_string());
|
||||
quote! {
|
||||
unsafe { crate::rcc::get_freqs().#clock_name.unwrap() }
|
||||
}
|
||||
}
|
||||
PeripheralRccKernelClock::Mux(mux) => clock_gen.gen_mux(mux),
|
||||
PeripheralRccKernelClock::Clock(clock) => clock_gen.gen_clock(clock),
|
||||
};
|
||||
|
||||
/*
|
||||
A refcount leak can result if the same field is shared by peripherals with different stop modes
|
||||
This condition should be checked in stm32-data
|
||||
*/
|
||||
// A refcount leak can result if the same field is shared by peripherals with different stop modes
|
||||
// This condition should be checked in stm32-data
|
||||
let stop_refcount = match rcc.stop_mode {
|
||||
StopMode::Standby => None,
|
||||
StopMode::Stop2 => Some(quote! { REFCOUNT_STOP2 }),
|
||||
|
@ -543,74 +612,79 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
if !rcc_cfgr_regs.is_empty() {
|
||||
println!("cargo:rustc-cfg=clock_mux");
|
||||
let struct_fields: Vec<_> = clock_gen
|
||||
.muxes
|
||||
.iter()
|
||||
.map(|(_fieldset, fieldname, enum_name)| {
|
||||
quote! {
|
||||
pub #fieldname: #enum_name
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let struct_fields: Vec<_> = rcc_cfgr_regs
|
||||
let mut inits = TokenStream::new();
|
||||
for fieldset in clock_gen
|
||||
.muxes
|
||||
.iter()
|
||||
.map(|(f, _, _)| f)
|
||||
.collect::<BTreeSet<_>>()
|
||||
.into_iter()
|
||||
{
|
||||
let setters: Vec<_> = clock_gen
|
||||
.muxes
|
||||
.iter()
|
||||
.map(|(_fieldset, fieldname, enum_name)| {
|
||||
quote! {
|
||||
pub #fieldname: Option<#enum_name>
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let field_names: Vec<_> = rcc_cfgr_regs
|
||||
.iter()
|
||||
.map(|(_fieldset, fieldname, _enum_name)| fieldname)
|
||||
.collect();
|
||||
|
||||
let inits: Vec<_> = rcc_cfgr_regs
|
||||
.iter()
|
||||
.map(|(fieldset, fieldname, _enum_name)| {
|
||||
.filter(|(f, _, _)| f == fieldset)
|
||||
.map(|(_, fieldname, _)| {
|
||||
let setter = format_ident!("set_{}", fieldname);
|
||||
quote! {
|
||||
match self.#fieldname {
|
||||
None => {}
|
||||
Some(val) => {
|
||||
crate::pac::RCC.#fieldset()
|
||||
.modify(|w| w.#setter(val));
|
||||
}
|
||||
};
|
||||
w.#setter(self.#fieldname);
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let enum_names: BTreeSet<_> = rcc_cfgr_regs
|
||||
.iter()
|
||||
.map(|(_fieldset, _fieldname, enum_name)| enum_name)
|
||||
.collect();
|
||||
|
||||
g.extend(quote! {
|
||||
pub mod mux {
|
||||
#(pub use crate::pac::rcc::vals::#enum_names as #enum_names; )*
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ClockMux {
|
||||
#( #struct_fields, )*
|
||||
}
|
||||
|
||||
impl Default for ClockMux {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
#( #field_names: None, )*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClockMux {
|
||||
pub fn init(self) {
|
||||
#( #inits )*
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
inits.extend(quote! {
|
||||
crate::pac::RCC.#fieldset().modify(|w| {
|
||||
#(#setters)*
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
let enum_names: BTreeSet<_> = clock_gen.muxes.iter().map(|(_, _, enum_name)| enum_name).collect();
|
||||
|
||||
g.extend(quote! {
|
||||
pub mod mux {
|
||||
#(pub use crate::pac::rcc::vals::#enum_names as #enum_names; )*
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ClockMux {
|
||||
#( #struct_fields, )*
|
||||
}
|
||||
|
||||
impl ClockMux {
|
||||
pub(crate) const fn default() -> Self {
|
||||
// safety: zero value is valid for all PAC enums.
|
||||
unsafe { ::core::mem::zeroed() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ClockMux {
|
||||
fn default() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl ClockMux {
|
||||
pub(crate) fn init(&self) {
|
||||
#inits
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Generate RCC
|
||||
clock_names.insert("sys".to_string());
|
||||
clock_names.insert("rtc".to_string());
|
||||
let clock_idents: Vec<_> = clock_names.iter().map(|n| format_ident!("{}", n)).collect();
|
||||
clock_gen.clock_names.insert("sys".to_string());
|
||||
clock_gen.clock_names.insert("rtc".to_string());
|
||||
let clock_idents: Vec<_> = clock_gen.clock_names.iter().map(|n| format_ident!("{}", n)).collect();
|
||||
g.extend(quote! {
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
|
@ -640,7 +714,8 @@ fn main() {
|
|||
}
|
||||
);
|
||||
|
||||
let refcount_mod: TokenStream = refcount_statics
|
||||
let refcount_mod: TokenStream = clock_gen
|
||||
.refcount_statics
|
||||
.iter()
|
||||
.map(|refcount_static| {
|
||||
quote! {
|
||||
|
|
|
@ -436,7 +436,31 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S
|
|||
}
|
||||
|
||||
/// Sender that can be used for sending CAN frames.
|
||||
pub type BufferedCanSender = embassy_sync::channel::DynamicSender<'static, ClassicFrame>;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct BufferedCanSender {
|
||||
tx_buf: embassy_sync::channel::DynamicSender<'static, ClassicFrame>,
|
||||
waker: fn(),
|
||||
}
|
||||
|
||||
impl BufferedCanSender {
|
||||
/// Async write frame to TX buffer.
|
||||
pub fn try_write(&mut self, frame: ClassicFrame) -> Result<(), embassy_sync::channel::TrySendError<ClassicFrame>> {
|
||||
self.tx_buf.try_send(frame)?;
|
||||
(self.waker)();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Async write frame to TX buffer.
|
||||
pub async fn write(&mut self, frame: ClassicFrame) {
|
||||
self.tx_buf.send(frame).await;
|
||||
(self.waker)();
|
||||
}
|
||||
|
||||
/// Allows a poll_fn to poll until the channel is ready to write
|
||||
pub fn poll_ready_to_send(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
|
||||
self.tx_buf.poll_ready_to_send(cx)
|
||||
}
|
||||
}
|
||||
|
||||
/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
|
||||
pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>;
|
||||
|
@ -489,7 +513,10 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
|||
|
||||
/// Returns a sender that can be used for sending CAN frames.
|
||||
pub fn writer(&self) -> BufferedCanSender {
|
||||
self.tx_buf.sender().into()
|
||||
BufferedCanSender {
|
||||
tx_buf: self.tx_buf.sender().into(),
|
||||
waker: T::IT0Interrupt::pend,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
|
||||
|
@ -525,7 +552,31 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF
|
|||
}
|
||||
|
||||
/// Sender that can be used for sending CAN frames.
|
||||
pub type BufferedFdCanSender = embassy_sync::channel::DynamicSender<'static, FdFrame>;
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct BufferedFdCanSender {
|
||||
tx_buf: embassy_sync::channel::DynamicSender<'static, FdFrame>,
|
||||
waker: fn(),
|
||||
}
|
||||
|
||||
impl BufferedFdCanSender {
|
||||
/// Async write frame to TX buffer.
|
||||
pub fn try_write(&mut self, frame: FdFrame) -> Result<(), embassy_sync::channel::TrySendError<FdFrame>> {
|
||||
self.tx_buf.try_send(frame)?;
|
||||
(self.waker)();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Async write frame to TX buffer.
|
||||
pub async fn write(&mut self, frame: FdFrame) {
|
||||
self.tx_buf.send(frame).await;
|
||||
(self.waker)();
|
||||
}
|
||||
|
||||
/// Allows a poll_fn to poll until the channel is ready to write
|
||||
pub fn poll_ready_to_send(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
|
||||
self.tx_buf.poll_ready_to_send(cx)
|
||||
}
|
||||
}
|
||||
|
||||
/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
|
||||
pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>;
|
||||
|
@ -578,7 +629,10 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
|||
|
||||
/// Returns a sender that can be used for sending CAN frames.
|
||||
pub fn writer(&self) -> BufferedFdCanSender {
|
||||
self.tx_buf.sender().into()
|
||||
BufferedFdCanSender {
|
||||
tx_buf: self.tx_buf.sender().into(),
|
||||
waker: T::IT0Interrupt::pend,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
|
||||
|
|
|
@ -206,7 +206,7 @@ impl embedded_can::Frame for ClassicFrame {
|
|||
fn is_extended(&self) -> bool {
|
||||
match self.can_header.id {
|
||||
embedded_can::Id::Extended(_) => true,
|
||||
embedded_can::Id::Standard(_) => true,
|
||||
embedded_can::Id::Standard(_) => false,
|
||||
}
|
||||
}
|
||||
fn is_remote_frame(&self) -> bool {
|
||||
|
@ -369,7 +369,7 @@ impl embedded_can::Frame for FdFrame {
|
|||
fn is_extended(&self) -> bool {
|
||||
match self.can_header.id {
|
||||
embedded_can::Id::Extended(_) => true,
|
||||
embedded_can::Id::Standard(_) => true,
|
||||
embedded_can::Id::Standard(_) => false,
|
||||
}
|
||||
}
|
||||
fn is_remote_frame(&self) -> bool {
|
||||
|
|
1356
embassy-stm32/src/cryp/mod.rs
Normal file
1356
embassy-stm32/src/cryp/mod.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -7,7 +7,6 @@ use core::task::Poll;
|
|||
use self::sealed::Instance;
|
||||
use crate::interrupt;
|
||||
use crate::interrupt::typelevel::Interrupt;
|
||||
use crate::pac::rcc::vals::{Lptim1sel, Lptim2sel};
|
||||
use crate::peripherals::IPCC;
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
|
||||
|
@ -105,7 +104,8 @@ impl Ipcc {
|
|||
IPCC::enable_and_reset();
|
||||
IPCC::set_cpu2(true);
|
||||
|
||||
_configure_pwr();
|
||||
// set RF wake-up clock = LSE
|
||||
crate::pac::RCC.csr().modify(|w| w.set_rfwkpsel(0b01));
|
||||
|
||||
let regs = IPCC::regs();
|
||||
|
||||
|
@ -271,18 +271,3 @@ pub(crate) mod sealed {
|
|||
fn state() -> &'static State;
|
||||
}
|
||||
}
|
||||
|
||||
fn _configure_pwr() {
|
||||
// TODO: move the rest of this to rcc
|
||||
let rcc = crate::pac::RCC;
|
||||
|
||||
// TODO: required
|
||||
// set RF wake-up clock = LSE
|
||||
rcc.csr().modify(|w| w.set_rfwkpsel(0b01));
|
||||
|
||||
// set LPTIM1 & LPTIM2 clock source
|
||||
rcc.ccipr().modify(|w| {
|
||||
w.set_lptim1sel(Lptim1sel::PCLK1);
|
||||
w.set_lptim2sel(Lptim2sel::PCLK1);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ pub mod adc;
|
|||
pub mod can;
|
||||
#[cfg(crc)]
|
||||
pub mod crc;
|
||||
#[cfg(cryp)]
|
||||
pub mod cryp;
|
||||
#[cfg(dac)]
|
||||
pub mod dac;
|
||||
#[cfg(dcmi)]
|
||||
|
|
|
@ -21,6 +21,9 @@ pub struct Config {
|
|||
pub ahb_pre: AHBPrescaler,
|
||||
pub apb_pre: APBPrescaler,
|
||||
pub ls: super::LsConfig,
|
||||
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -31,6 +34,7 @@ impl Default for Config {
|
|||
ahb_pre: AHBPrescaler::DIV1,
|
||||
apb_pre: APBPrescaler::DIV1,
|
||||
ls: Default::default(),
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,28 +101,25 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
|
||||
if !set_flash_latency_after {
|
||||
// Spin until the effective flash latency is compatible with the clock change
|
||||
while FLASH.acr().read().latency().to_bits() < target_flash_latency.to_bits() {}
|
||||
while FLASH.acr().read().latency() < target_flash_latency {}
|
||||
}
|
||||
|
||||
// Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once
|
||||
let (sw, hpre, ppre) = (sw.into(), config.ahb_pre, config.apb_pre);
|
||||
RCC.cfgr().modify(|w| {
|
||||
w.set_sw(sw);
|
||||
w.set_hpre(hpre);
|
||||
w.set_ppre(ppre);
|
||||
w.set_hpre(config.ahb_pre);
|
||||
w.set_ppre(config.apb_pre);
|
||||
});
|
||||
|
||||
if set_flash_latency_after {
|
||||
// We can make the flash require fewer wait states
|
||||
// Spin until the SYSCLK changes have taken effect
|
||||
loop {
|
||||
let cfgr = RCC.cfgr().read();
|
||||
if cfgr.sw() == sw && cfgr.hpre() == hpre && cfgr.ppre() == ppre {
|
||||
break;
|
||||
}
|
||||
// Spin until the SYSCLK changes have taken effect
|
||||
loop {
|
||||
let cfgr = RCC.cfgr().read();
|
||||
if cfgr.sw() == sw && cfgr.hpre() == config.ahb_pre && cfgr.ppre() == config.apb_pre {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the flash latency to require fewer wait states
|
||||
// Set the flash latency to require fewer wait states
|
||||
if set_flash_latency_after {
|
||||
FLASH.acr().modify(|w| w.set_latency(target_flash_latency));
|
||||
}
|
||||
|
||||
|
@ -132,6 +133,11 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
}
|
||||
};
|
||||
|
||||
config.mux.init();
|
||||
|
||||
// without this, the ringbuffered uart test fails.
|
||||
cortex_m::asm::dsb();
|
||||
|
||||
set_clocks!(
|
||||
hsi: None,
|
||||
lse: None,
|
||||
|
|
|
@ -98,8 +98,8 @@ pub struct Config {
|
|||
#[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
|
||||
pub adc34: AdcClockSource,
|
||||
|
||||
#[cfg(clock_mux)]
|
||||
pub mux: crate::rcc::mux::ClockMux,
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
|
||||
pub ls: super::LsConfig,
|
||||
}
|
||||
|
@ -128,7 +128,6 @@ impl Default for Config {
|
|||
#[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
|
||||
adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
|
||||
|
||||
#[cfg(clock_mux)]
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +369,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
};
|
||||
*/
|
||||
|
||||
#[cfg(clock_mux)]
|
||||
config.mux.init();
|
||||
|
||||
set_clocks!(
|
||||
|
|
|
@ -95,6 +95,9 @@ pub struct Config {
|
|||
|
||||
pub ls: super::LsConfig,
|
||||
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
|
||||
#[cfg(stm32f2)]
|
||||
pub voltage: VoltageScale,
|
||||
}
|
||||
|
@ -120,6 +123,7 @@ impl Default for Config {
|
|||
|
||||
#[cfg(stm32f2)]
|
||||
voltage: VoltageScale::Range3,
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -256,6 +260,8 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
});
|
||||
while RCC.cfgr().read().sws() != config.sys {}
|
||||
|
||||
config.mux.init();
|
||||
|
||||
set_clocks!(
|
||||
hsi: hsi,
|
||||
hse: hse,
|
||||
|
@ -286,7 +292,9 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
#[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
|
||||
pllsai1_r: pllsai.r,
|
||||
|
||||
clk48: pll.q,
|
||||
// TODO workaround until f4 rcc is fixed in stm32-data
|
||||
#[cfg(not(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7)))]
|
||||
pllsai1_q: None,
|
||||
|
||||
hsi_div488: hsi.map(|hsi| hsi/488u32),
|
||||
hsi_hse: None,
|
||||
|
|
|
@ -71,22 +71,6 @@ pub enum PllSource {
|
|||
HSE(Hertz, HseMode),
|
||||
}
|
||||
|
||||
/// Sets the source for the 48MHz clock to the USB peripheral.
|
||||
#[cfg(any(stm32g0b1, stm32g0c1, stm32g0b0))]
|
||||
pub enum UsbSrc {
|
||||
/// Use the High Speed Internal Oscillator. The CRS must be used to calibrate the
|
||||
/// oscillator to comply with the USB specification for oscillator tolerance.
|
||||
#[cfg(any(stm32g0b1, stm32g0c1))]
|
||||
Hsi48(super::Hsi48Config),
|
||||
/// Use the PLLQ output. The PLL must be configured to output a 48MHz clock. The
|
||||
/// PLL needs to be using the HSE source to comply with the USB specification for oscillator
|
||||
/// tolerance.
|
||||
PllQ,
|
||||
/// Use the HSE source directly. The HSE must be a 48MHz source. The HSE source must comply
|
||||
/// with the USB specification for oscillator tolerance.
|
||||
HSE,
|
||||
}
|
||||
|
||||
/// Clocks configutation
|
||||
pub struct Config {
|
||||
pub sys: Sysclk,
|
||||
|
@ -94,8 +78,10 @@ pub struct Config {
|
|||
pub apb_pre: APBPrescaler,
|
||||
pub low_power_run: bool,
|
||||
pub ls: super::LsConfig,
|
||||
#[cfg(any(stm32g0b1, stm32g0c1, stm32g0b0))]
|
||||
pub usb_src: Option<UsbSrc>,
|
||||
#[cfg(crs)]
|
||||
pub hsi48: Option<super::Hsi48Config>,
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -107,8 +93,9 @@ impl Default for Config {
|
|||
apb_pre: APBPrescaler::DIV1,
|
||||
low_power_run: false,
|
||||
ls: Default::default(),
|
||||
#[cfg(any(stm32g0b1, stm32g0c1, stm32g0b0))]
|
||||
usb_src: None,
|
||||
#[cfg(crs)]
|
||||
hsi48: Some(Default::default()),
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -322,34 +309,12 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
let lsi_freq = (sw == Sw::LSI).then_some(super::LSI_FREQ);
|
||||
let hse_freq = (sw == Sw::HSE).then_some(sys_clk);
|
||||
|
||||
#[cfg(any(stm32g0b1, stm32g0c1, stm32g0b0))]
|
||||
let hsi48_freq = config.usb_src.and_then(|config| {
|
||||
match config {
|
||||
UsbSrc::PllQ => {
|
||||
// Make sure the PLLQ is enabled and running at 48Mhz
|
||||
assert!(pll1_q_freq.is_some() && pll1_q_freq.unwrap().0 == 48_000_000);
|
||||
RCC.ccipr2()
|
||||
.modify(|w| w.set_usbsel(crate::pac::rcc::vals::Usbsel::PLL1_Q));
|
||||
None
|
||||
}
|
||||
UsbSrc::HSE => {
|
||||
// Make sure the HSE is enabled and running at 48Mhz
|
||||
assert!(hse_freq.is_some() && hse_freq.unwrap().0 == 48_000_000);
|
||||
RCC.ccipr2()
|
||||
.modify(|w| w.set_usbsel(crate::pac::rcc::vals::Usbsel::HSE));
|
||||
None
|
||||
}
|
||||
#[cfg(any(stm32g0b1, stm32g0c1))]
|
||||
UsbSrc::Hsi48(config) => {
|
||||
let freq = super::init_hsi48(config);
|
||||
RCC.ccipr2()
|
||||
.modify(|w| w.set_usbsel(crate::pac::rcc::vals::Usbsel::HSI48));
|
||||
Some(freq)
|
||||
}
|
||||
}
|
||||
});
|
||||
#[cfg(not(any(stm32g0b1, stm32g0c1, stm32g0b0)))]
|
||||
let hsi48_freq: Option<Hertz> = None;
|
||||
#[cfg(crs)]
|
||||
let hsi48 = config.hsi48.map(super::init_hsi48);
|
||||
#[cfg(not(crs))]
|
||||
let hsi48: Option<Hertz> = None;
|
||||
|
||||
config.mux.init();
|
||||
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
|
@ -357,7 +322,7 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
pclk1: Some(apb_freq),
|
||||
pclk1_tim: Some(apb_tim_freq),
|
||||
hsi: hsi_freq,
|
||||
hsi48: hsi48_freq,
|
||||
hsi48: hsi48,
|
||||
hsi_div_8: hsi_div_8_freq,
|
||||
hse: hse_freq,
|
||||
lse: lse_freq,
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use stm32_metapac::flash::vals::Latency;
|
||||
use stm32_metapac::rcc::vals::{Adcsel, Sw};
|
||||
use stm32_metapac::rcc::vals::Sw;
|
||||
use stm32_metapac::FLASH;
|
||||
|
||||
pub use crate::pac::rcc::vals::{
|
||||
Adcsel as AdcClockSource, Clk48sel as Clk48Src, Fdcansel as FdCanClockSource, Hpre as AHBPrescaler,
|
||||
Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc, Ppre as APBPrescaler,
|
||||
Sw as Sysclk,
|
||||
Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc,
|
||||
Ppre as APBPrescaler, Sw as Sysclk,
|
||||
};
|
||||
use crate::pac::{PWR, RCC};
|
||||
use crate::time::Hertz;
|
||||
|
@ -82,24 +81,15 @@ pub struct Config {
|
|||
|
||||
pub low_power_run: bool,
|
||||
|
||||
/// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals.
|
||||
pub clk48_src: Clk48Src,
|
||||
|
||||
/// Low-Speed Clock Configuration
|
||||
pub ls: super::LsConfig,
|
||||
|
||||
/// Clock Source for ADCs 1 and 2
|
||||
pub adc12_clock_source: AdcClockSource,
|
||||
|
||||
/// Clock Source for ADCs 3, 4 and 5
|
||||
pub adc345_clock_source: AdcClockSource,
|
||||
|
||||
/// Clock Source for FDCAN
|
||||
pub fdcan_clock_source: FdCanClockSource,
|
||||
|
||||
/// Enable range1 boost mode
|
||||
/// Recommended when the SYSCLK frequency is greater than 150MHz.
|
||||
pub boost: bool,
|
||||
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -115,12 +105,9 @@ impl Default for Config {
|
|||
apb1_pre: APBPrescaler::DIV1,
|
||||
apb2_pre: APBPrescaler::DIV1,
|
||||
low_power_run: false,
|
||||
clk48_src: Clk48Src::HSI48,
|
||||
ls: Default::default(),
|
||||
adc12_clock_source: Adcsel::DISABLE,
|
||||
adc345_clock_source: Adcsel::DISABLE,
|
||||
fdcan_clock_source: FdCanClockSource::PCLK1,
|
||||
boost: false,
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,9 +152,7 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
};
|
||||
|
||||
// Configure HSI48 if required
|
||||
if let Some(hsi48_config) = config.hsi48 {
|
||||
super::init_hsi48(hsi48_config);
|
||||
}
|
||||
let hsi48 = config.hsi48.map(super::init_hsi48);
|
||||
|
||||
let pll_freq = config.pll.map(|pll_config| {
|
||||
let src_freq = match pll_config.source {
|
||||
|
@ -176,13 +161,13 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
assert!(max::PLL_IN.contains(&src_freq));
|
||||
|
||||
// Disable PLL before configuration
|
||||
RCC.cr().modify(|w| w.set_pllon(false));
|
||||
while RCC.cr().read().pllrdy() {}
|
||||
|
||||
let internal_freq = src_freq / pll_config.prediv * pll_config.mul;
|
||||
let in_freq = src_freq / pll_config.prediv;
|
||||
assert!(max::PLL_IN.contains(&in_freq));
|
||||
let internal_freq = in_freq * pll_config.mul;
|
||||
|
||||
assert!(max::PLL_VCO.contains(&internal_freq));
|
||||
|
||||
|
@ -301,42 +286,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
let (apb1_freq, apb1_tim_freq) = super::util::calc_pclk(hclk, config.apb1_pre);
|
||||
let (apb2_freq, apb2_tim_freq) = super::util::calc_pclk(hclk, config.apb2_pre);
|
||||
|
||||
// Configure the 48MHz clock source for USB and RNG peripherals.
|
||||
RCC.ccipr().modify(|w| {
|
||||
w.set_clk48sel(match config.clk48_src {
|
||||
Clk48Src::PLL1_Q => {
|
||||
// Not checking that PLL1_Q is 48MHz here so as not to require the user to have a 48MHz clock.
|
||||
// Peripherals which require one (USB, RNG) should check that they‘re driven by a valid 48MHz
|
||||
// clock at init.
|
||||
crate::pac::rcc::vals::Clk48sel::PLL1_Q
|
||||
}
|
||||
Clk48Src::HSI48 => {
|
||||
// Make sure HSI48 is enabled
|
||||
assert!(config.hsi48.is_some());
|
||||
crate::pac::rcc::vals::Clk48sel::HSI48
|
||||
}
|
||||
_ => unreachable!(),
|
||||
})
|
||||
});
|
||||
|
||||
RCC.ccipr().modify(|w| w.set_adc12sel(config.adc12_clock_source));
|
||||
RCC.ccipr().modify(|w| w.set_adc345sel(config.adc345_clock_source));
|
||||
RCC.ccipr().modify(|w| w.set_fdcansel(config.fdcan_clock_source));
|
||||
|
||||
let adc12_ck = match config.adc12_clock_source {
|
||||
AdcClockSource::DISABLE => None,
|
||||
AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p,
|
||||
AdcClockSource::SYS => Some(sys_clk),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let adc345_ck = match config.adc345_clock_source {
|
||||
AdcClockSource::DISABLE => None,
|
||||
AdcClockSource::PLL1_P => pll_freq.as_ref().unwrap().pll_p,
|
||||
AdcClockSource::SYS => Some(sys_clk),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if config.low_power_run {
|
||||
assert!(sys_clk <= Hertz(2_000_000));
|
||||
PWR.cr1().modify(|w| w.set_lpr(true));
|
||||
|
@ -344,6 +293,8 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
|
||||
let rtc = config.ls.init();
|
||||
|
||||
config.mux.init();
|
||||
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(hclk),
|
||||
|
@ -353,12 +304,11 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
pclk1_tim: Some(apb1_tim_freq),
|
||||
pclk2: Some(apb2_freq),
|
||||
pclk2_tim: Some(apb2_tim_freq),
|
||||
adc: adc12_ck,
|
||||
adc34: adc345_ck,
|
||||
pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p),
|
||||
pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_q),
|
||||
pll1_r: pll_freq.as_ref().and_then(|pll| pll.pll_r),
|
||||
hse: hse,
|
||||
hsi48: hsi48,
|
||||
rtc: rtc,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,15 +2,10 @@ use core::ops::RangeInclusive;
|
|||
|
||||
use crate::pac;
|
||||
use crate::pac::pwr::vals::Vos;
|
||||
#[cfg(stm32h5)]
|
||||
pub use crate::pac::rcc::vals::Adcdacsel as AdcClockSource;
|
||||
#[cfg(stm32h7)]
|
||||
pub use crate::pac::rcc::vals::Adcsel as AdcClockSource;
|
||||
pub use crate::pac::rcc::vals::{
|
||||
Ckpersel as PerClockSource, Fdcansel as FdCanClockSource, Hsidiv as HSIPrescaler, Plldiv as PllDiv,
|
||||
Pllm as PllPreDiv, Plln as PllMul, Pllsrc as PllSource, Sw as Sysclk,
|
||||
Hsidiv as HSIPrescaler, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul, Pllsrc as PllSource, Sw as Sysclk,
|
||||
};
|
||||
use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre};
|
||||
use crate::pac::rcc::vals::{Pllrge, Pllvcosel, Timpre};
|
||||
use crate::pac::{FLASH, PWR, RCC};
|
||||
use crate::time::Hertz;
|
||||
|
||||
|
@ -194,16 +189,15 @@ pub struct Config {
|
|||
#[cfg(stm32h7)]
|
||||
pub apb4_pre: APBPrescaler,
|
||||
|
||||
pub per_clock_source: PerClockSource,
|
||||
pub adc_clock_source: AdcClockSource,
|
||||
pub fdcan_clock_source: FdCanClockSource,
|
||||
|
||||
pub timer_prescaler: TimerPrescaler,
|
||||
pub voltage_scale: VoltageScale,
|
||||
pub ls: super::LsConfig,
|
||||
|
||||
#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))]
|
||||
pub supply_config: SupplyConfig,
|
||||
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -227,21 +221,14 @@ impl Default for Config {
|
|||
#[cfg(stm32h7)]
|
||||
apb4_pre: APBPrescaler::DIV1,
|
||||
|
||||
per_clock_source: PerClockSource::HSI,
|
||||
|
||||
#[cfg(stm32h5)]
|
||||
adc_clock_source: AdcClockSource::HCLK1,
|
||||
#[cfg(stm32h7)]
|
||||
adc_clock_source: AdcClockSource::PER,
|
||||
|
||||
fdcan_clock_source: FdCanClockSource::from_bits(0), // HSE
|
||||
|
||||
timer_prescaler: TimerPrescaler::DefaultX2,
|
||||
voltage_scale: VoltageScale::Scale0,
|
||||
ls: Default::default(),
|
||||
|
||||
#[cfg(any(pwr_h7rm0399, pwr_h7rm0455, pwr_h7rm0468))]
|
||||
supply_config: SupplyConfig::Default,
|
||||
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -504,31 +491,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
#[cfg(stm32h7)]
|
||||
assert!(apb4 <= pclk_max);
|
||||
|
||||
let _per_ck = match config.per_clock_source {
|
||||
Ckpersel::HSI => hsi,
|
||||
Ckpersel::CSI => csi,
|
||||
Ckpersel::HSE => hse,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
#[cfg(stm32h7)]
|
||||
let adc = match config.adc_clock_source {
|
||||
AdcClockSource::PLL2_P => pll2.p,
|
||||
AdcClockSource::PLL3_R => pll3.r,
|
||||
AdcClockSource::PER => _per_ck,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
#[cfg(stm32h5)]
|
||||
let adc = match config.adc_clock_source {
|
||||
AdcClockSource::HCLK1 => Some(hclk),
|
||||
AdcClockSource::SYS => Some(sys),
|
||||
AdcClockSource::PLL2_R => pll2.r,
|
||||
AdcClockSource::HSE => hse,
|
||||
AdcClockSource::HSI => hsi,
|
||||
AdcClockSource::CSI => csi,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
flash_setup(hclk, config.voltage_scale);
|
||||
|
||||
let rtc = config.ls.init();
|
||||
|
@ -550,16 +512,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
RCC.d3cfgr().modify(|w| {
|
||||
w.set_d3ppre(config.apb4_pre);
|
||||
});
|
||||
|
||||
RCC.d1ccipr().modify(|w| {
|
||||
w.set_ckpersel(config.per_clock_source);
|
||||
});
|
||||
RCC.d3ccipr().modify(|w| {
|
||||
w.set_adcsel(config.adc_clock_source);
|
||||
});
|
||||
RCC.d2ccip1r().modify(|w| {
|
||||
w.set_fdcansel(config.fdcan_clock_source);
|
||||
});
|
||||
}
|
||||
#[cfg(stm32h5)]
|
||||
{
|
||||
|
@ -573,12 +525,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
w.set_ppre2(config.apb2_pre);
|
||||
w.set_ppre3(config.apb3_pre);
|
||||
});
|
||||
|
||||
RCC.ccipr5().modify(|w| {
|
||||
w.set_ckpersel(config.per_clock_source);
|
||||
w.set_adcdacsel(config.adc_clock_source);
|
||||
w.set_fdcan12sel(config.fdcan_clock_source)
|
||||
});
|
||||
}
|
||||
|
||||
RCC.cfgr().modify(|w| w.set_timpre(config.timer_prescaler.into()));
|
||||
|
@ -601,6 +547,8 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
while !pac::SYSCFG.cccsr().read().ready() {}
|
||||
}
|
||||
|
||||
config.mux.init();
|
||||
|
||||
set_clocks!(
|
||||
sys: Some(sys),
|
||||
hclk1: Some(hclk),
|
||||
|
@ -614,7 +562,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
pclk4: Some(apb4),
|
||||
pclk1_tim: Some(apb1_tim),
|
||||
pclk2_tim: Some(apb2_tim),
|
||||
adc: adc,
|
||||
rtc: rtc,
|
||||
|
||||
hsi: hsi,
|
||||
|
@ -646,7 +593,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
|
||||
#[cfg(stm32h5)]
|
||||
audioclk: None,
|
||||
per: None,
|
||||
i2s_ckin: None,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#[cfg(any(stm32l0, stm32l1))]
|
||||
pub use crate::pac::pwr::vals::Vos as VoltageScale;
|
||||
use crate::pac::rcc::regs::Cfgr;
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
|
||||
pub use crate::pac::rcc::vals::Adcsel as AdcClockSource;
|
||||
#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
|
||||
pub use crate::pac::rcc::vals::Clk48sel as Clk48Src;
|
||||
#[cfg(any(stm32wb, stm32wl))]
|
||||
pub use crate::pac::rcc::vals::Hsepre as HsePrescaler;
|
||||
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as Sysclk};
|
||||
|
@ -59,18 +55,14 @@ pub struct Config {
|
|||
#[cfg(any(stm32wl, stm32wb))]
|
||||
pub shared_ahb_pre: AHBPrescaler,
|
||||
|
||||
// muxes
|
||||
#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
|
||||
pub clk48_src: Clk48Src,
|
||||
|
||||
// low speed LSI/LSE/RTC
|
||||
pub ls: super::LsConfig,
|
||||
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
|
||||
pub adc_clock_source: AdcClockSource,
|
||||
|
||||
#[cfg(any(stm32l0, stm32l1))]
|
||||
pub voltage_scale: VoltageScale,
|
||||
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -95,13 +87,10 @@ impl Default for Config {
|
|||
pllsai2: None,
|
||||
#[cfg(crs)]
|
||||
hsi48: Some(Default::default()),
|
||||
#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
|
||||
clk48_src: Clk48Src::HSI48,
|
||||
ls: Default::default(),
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
|
||||
adc_clock_source: AdcClockSource::SYS,
|
||||
#[cfg(any(stm32l0, stm32l1))]
|
||||
voltage_scale: VoltageScale::RANGE1,
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +107,6 @@ pub const WPAN_DEFAULT: Config = Config {
|
|||
hsi48: Some(super::Hsi48Config { sync_from_usb: false }),
|
||||
msi: None,
|
||||
hsi: false,
|
||||
clk48_src: Clk48Src::PLL1_Q,
|
||||
|
||||
ls: super::LsConfig::default_lse(),
|
||||
|
||||
|
@ -137,7 +125,8 @@ pub const WPAN_DEFAULT: Config = Config {
|
|||
shared_ahb_pre: AHBPrescaler::DIV1,
|
||||
apb1_pre: APBPrescaler::DIV1,
|
||||
apb2_pre: APBPrescaler::DIV1,
|
||||
adc_clock_source: AdcClockSource::SYS,
|
||||
|
||||
mux: super::mux::ClockMux::default(),
|
||||
};
|
||||
|
||||
fn msi_enable(range: MSIRange) {
|
||||
|
@ -267,21 +256,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
Sysclk::PLL1_R => pll.r.unwrap(),
|
||||
};
|
||||
|
||||
#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
|
||||
RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src));
|
||||
#[cfg(any(rcc_l0_v2))]
|
||||
let clk48 = match config.clk48_src {
|
||||
Clk48Src::HSI48 => hsi48,
|
||||
Clk48Src::PLL1_VCO_DIV_2 => pll.clk48,
|
||||
};
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb))]
|
||||
let clk48 = match config.clk48_src {
|
||||
Clk48Src::HSI48 => hsi48,
|
||||
Clk48Src::MSI => msi,
|
||||
Clk48Src::PLLSAI1_Q => pllsai1.q,
|
||||
Clk48Src::PLL1_Q => pll.q,
|
||||
};
|
||||
|
||||
#[cfg(rcc_l4plus)]
|
||||
assert!(sys_clk.0 <= 120_000_000);
|
||||
#[cfg(all(stm32l4, not(rcc_l4plus)))]
|
||||
|
@ -357,9 +331,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
});
|
||||
while RCC.cfgr().read().sws() != config.sys {}
|
||||
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
|
||||
RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source));
|
||||
|
||||
#[cfg(any(stm32wl, stm32wb))]
|
||||
{
|
||||
RCC.extcfgr().modify(|w| {
|
||||
|
@ -372,6 +343,8 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
while !RCC.extcfgr().read().c2hpref() {}
|
||||
}
|
||||
|
||||
config.mux.init();
|
||||
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(hclk1),
|
||||
|
@ -388,10 +361,11 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
hsi: hsi,
|
||||
hse: hse,
|
||||
msi: msi,
|
||||
#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
|
||||
clk48: clk48,
|
||||
hsi48: hsi48,
|
||||
|
||||
#[cfg(any(stm32l0, stm32l1))]
|
||||
pll1_vco_div_2: pll.vco.map(|c| c/2u32),
|
||||
|
||||
#[cfg(not(any(stm32l0, stm32l1)))]
|
||||
pll1_p: pll.p,
|
||||
#[cfg(not(any(stm32l0, stm32l1)))]
|
||||
|
@ -511,7 +485,7 @@ mod pll {
|
|||
#[derive(Default)]
|
||||
pub(super) struct PllOutput {
|
||||
pub r: Option<Hertz>,
|
||||
pub clk48: Option<Hertz>,
|
||||
pub vco: Option<Hertz>,
|
||||
}
|
||||
|
||||
pub(super) fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> PllOutput {
|
||||
|
@ -528,7 +502,6 @@ mod pll {
|
|||
let vco_freq = pll_src * pll.mul;
|
||||
|
||||
let r = vco_freq / pll.div;
|
||||
let clk48 = (vco_freq == Hertz(96_000_000)).then_some(Hertz(48_000_000));
|
||||
|
||||
assert!(r <= Hertz(32_000_000));
|
||||
|
||||
|
@ -541,7 +514,10 @@ mod pll {
|
|||
// Enable PLL
|
||||
pll_enable(instance, true);
|
||||
|
||||
PllOutput { r: Some(r), clk48 }
|
||||
PllOutput {
|
||||
r: Some(r),
|
||||
vco: Some(vco_freq),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,7 @@ mod _version;
|
|||
|
||||
pub use _version::*;
|
||||
|
||||
#[cfg(clock_mux)]
|
||||
pub use crate::_generated::mux;
|
||||
pub use crate::_generated::Clocks;
|
||||
pub use crate::_generated::{mux, Clocks};
|
||||
|
||||
#[cfg(feature = "low-power")]
|
||||
/// Must be written within a critical section
|
||||
|
|
|
@ -85,6 +85,9 @@ pub struct Config {
|
|||
/// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits.
|
||||
pub voltage_range: VoltageScale,
|
||||
pub ls: super::LsConfig,
|
||||
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -104,6 +107,7 @@ impl Default for Config {
|
|||
apb3_pre: APBPrescaler::DIV1,
|
||||
voltage_range: VoltageScale::RANGE1,
|
||||
ls: Default::default(),
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -259,6 +263,8 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
|
||||
let rtc = config.ls.init();
|
||||
|
||||
config.mux.init();
|
||||
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(hclk),
|
||||
|
@ -289,7 +295,6 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
lse: None,
|
||||
lsi: None,
|
||||
msik: None,
|
||||
iclk: None,
|
||||
shsi: None,
|
||||
shsi_div_2: None,
|
||||
);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
pub use crate::pac::pwr::vals::Vos as VoltageScale;
|
||||
use crate::pac::rcc::regs::Cfgr1;
|
||||
pub use crate::pac::rcc::vals::{
|
||||
Adcsel as AdcClockSource, Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as Sysclk,
|
||||
};
|
||||
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as Sysclk};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::time::Hertz;
|
||||
|
||||
|
@ -32,9 +30,10 @@ pub struct Config {
|
|||
// low speed LSI/LSE/RTC
|
||||
pub ls: super::LsConfig,
|
||||
|
||||
pub adc_clock_source: AdcClockSource,
|
||||
|
||||
pub voltage_scale: VoltageScale,
|
||||
|
||||
/// Per-peripheral kernel clock selection muxes
|
||||
pub mux: super::mux::ClockMux,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -49,8 +48,8 @@ impl Default for Config {
|
|||
apb2_pre: APBPrescaler::DIV1,
|
||||
apb7_pre: APBPrescaler::DIV1,
|
||||
ls: Default::default(),
|
||||
adc_clock_source: AdcClockSource::HCLK4,
|
||||
voltage_scale: VoltageScale::RANGE2,
|
||||
mux: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +151,7 @@ pub(crate) unsafe fn init(config: Config) {
|
|||
w.set_ppre2(config.apb2_pre);
|
||||
});
|
||||
|
||||
RCC.ccipr3().modify(|w| w.set_adcsel(config.adc_clock_source));
|
||||
config.mux.init();
|
||||
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
|
|
|
@ -606,13 +606,6 @@ impl<'d, T: Instance> Bus<'d, T> {
|
|||
// Wait for USB power to stabilize
|
||||
while !crate::pac::PWR.cr3().read().usb33rdy() {}
|
||||
|
||||
// Use internal 48MHz HSI clock. Should be enabled in RCC by default.
|
||||
critical_section::with(|_| {
|
||||
crate::pac::RCC
|
||||
.d2ccip2r()
|
||||
.modify(|w| w.set_usbsel(crate::pac::rcc::vals::Usbsel::HSI48))
|
||||
});
|
||||
|
||||
// Enable ULPI clock if external PHY is used
|
||||
let ulpien = !self.phy_type.internal();
|
||||
critical_section::with(|_| {
|
||||
|
@ -645,13 +638,6 @@ impl<'d, T: Instance> Bus<'d, T> {
|
|||
|
||||
// Wait for USB power to stabilize
|
||||
while !crate::pac::PWR.svmsr().read().vddusbrdy() {}
|
||||
|
||||
// Select HSI48 as USB clock source.
|
||||
critical_section::with(|_| {
|
||||
crate::pac::RCC.ccipr1().modify(|w| {
|
||||
w.set_iclksel(crate::pac::rcc::vals::Iclksel::HSI48);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
<T as RccPeripheral>::enable_and_reset();
|
||||
|
|
|
@ -28,7 +28,7 @@ async fn main(_spawner: Spawner) {
|
|||
config.rcc.apb1_pre = APBPrescaler::DIV2;
|
||||
config.rcc.apb2_pre = APBPrescaler::DIV1;
|
||||
|
||||
config.rcc.mux.hrtim1sw = Some(embassy_stm32::rcc::mux::Timsw::PLL1_P);
|
||||
config.rcc.mux.hrtim1sw = embassy_stm32::rcc::mux::Timsw::PLL1_P;
|
||||
}
|
||||
let p = embassy_stm32::init(config);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ embedded-storage = "0.3.1"
|
|||
static_cell = "2"
|
||||
sha2 = { version = "0.10.8", default-features = false }
|
||||
hmac = "0.12.1"
|
||||
aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] }
|
||||
|
||||
[profile.release]
|
||||
debug = 2
|
||||
|
|
74
examples/stm32f7/src/bin/cryp.rs
Normal file
74
examples/stm32f7/src/bin/cryp.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use aes_gcm::aead::heapless::Vec;
|
||||
use aes_gcm::aead::{AeadInPlace, KeyInit};
|
||||
use aes_gcm::Aes128Gcm;
|
||||
use defmt::info;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_stm32::cryp::*;
|
||||
use embassy_stm32::Config;
|
||||
use embassy_time::Instant;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
let config = Config::default();
|
||||
let p = embassy_stm32::init(config);
|
||||
|
||||
let payload: &[u8] = b"hello world";
|
||||
let aad: &[u8] = b"additional data";
|
||||
|
||||
let hw_cryp = Cryp::new(p.CRYP);
|
||||
let key: [u8; 16] = [0; 16];
|
||||
let mut ciphertext: [u8; 11] = [0; 11];
|
||||
let mut plaintext: [u8; 11] = [0; 11];
|
||||
let iv: [u8; 12] = [0; 12];
|
||||
|
||||
let hw_start_time = Instant::now();
|
||||
|
||||
// Encrypt in hardware using AES-GCM 128-bit
|
||||
let aes_gcm = AesGcm::new(&key, &iv);
|
||||
let mut gcm_encrypt = hw_cryp.start(&aes_gcm, Direction::Encrypt);
|
||||
hw_cryp.aad_blocking(&mut gcm_encrypt, aad, true);
|
||||
hw_cryp.payload_blocking(&mut gcm_encrypt, payload, &mut ciphertext, true);
|
||||
let encrypt_tag = hw_cryp.finish_blocking(gcm_encrypt);
|
||||
|
||||
// Decrypt in hardware using AES-GCM 128-bit
|
||||
let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt);
|
||||
hw_cryp.aad_blocking(&mut gcm_decrypt, aad, true);
|
||||
hw_cryp.payload_blocking(&mut gcm_decrypt, &ciphertext, &mut plaintext, true);
|
||||
let decrypt_tag = hw_cryp.finish_blocking(gcm_decrypt);
|
||||
|
||||
let hw_end_time = Instant::now();
|
||||
let hw_execution_time = hw_end_time - hw_start_time;
|
||||
|
||||
info!("AES-GCM Ciphertext: {:?}", ciphertext);
|
||||
info!("AES-GCM Plaintext: {:?}", plaintext);
|
||||
assert_eq!(payload, plaintext);
|
||||
assert_eq!(encrypt_tag, decrypt_tag);
|
||||
|
||||
let sw_start_time = Instant::now();
|
||||
|
||||
// Encrypt in software using AES-GCM 128-bit
|
||||
let mut payload_vec: Vec<u8, 32> = Vec::from_slice(&payload).unwrap();
|
||||
let cipher = Aes128Gcm::new(&key.into());
|
||||
let _ = cipher.encrypt_in_place(&iv.into(), aad.into(), &mut payload_vec);
|
||||
|
||||
assert_eq!(ciphertext, payload_vec[0..ciphertext.len()]);
|
||||
assert_eq!(
|
||||
encrypt_tag,
|
||||
payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]
|
||||
);
|
||||
|
||||
// Decrypt in software using AES-GCM 128-bit
|
||||
let _ = cipher.decrypt_in_place(&iv.into(), aad.into(), &mut payload_vec);
|
||||
|
||||
let sw_end_time = Instant::now();
|
||||
let sw_execution_time = sw_end_time - sw_start_time;
|
||||
|
||||
info!("Hardware Execution Time: {:?}", hw_execution_time);
|
||||
info!("Software Execution Time: {:?}", sw_execution_time);
|
||||
|
||||
loop {}
|
||||
}
|
|
@ -4,37 +4,35 @@
|
|||
use defmt::info;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_stm32::gpio::OutputType;
|
||||
use embassy_stm32::pac::rcc::vals::Tim1sel;
|
||||
use embassy_stm32::rcc::{Config as RccConfig, PllConfig, PllSource, Pllm, Plln, Pllq, Pllr, Sysclk};
|
||||
use embassy_stm32::time::khz;
|
||||
use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
|
||||
use embassy_stm32::timer::simple_pwm::PwmPin;
|
||||
use embassy_stm32::timer::Channel;
|
||||
use embassy_stm32::{pac, Config as PeripheralConfig};
|
||||
use embassy_stm32::Config as PeripheralConfig;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let mut rcc_config = RccConfig::default();
|
||||
rcc_config.sys = Sysclk::PLL(PllConfig {
|
||||
source: PllSource::HSI,
|
||||
m: Pllm::DIV1,
|
||||
n: Plln::MUL16,
|
||||
r: Pllr::DIV4, // CPU clock comes from PLLR (HSI (16MHz) / 1 * 16 / 4 = 64MHz)
|
||||
q: Some(Pllq::DIV2), // TIM1 or TIM15 can be sourced from PLLQ (HSI (16MHz) / 1 * 16 / 2 = 128MHz)
|
||||
p: None,
|
||||
});
|
||||
let mut config = PeripheralConfig::default();
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
|
||||
let mut peripheral_config = PeripheralConfig::default();
|
||||
peripheral_config.rcc = rcc_config;
|
||||
config.rcc.sys = Sysclk::PLL(PllConfig {
|
||||
source: PllSource::HSI,
|
||||
m: Pllm::DIV1,
|
||||
n: Plln::MUL16,
|
||||
r: Pllr::DIV4, // CPU clock comes from PLLR (HSI (16MHz) / 1 * 16 / 4 = 64MHz)
|
||||
q: Some(Pllq::DIV2), // TIM1 or TIM15 can be sourced from PLLQ (HSI (16MHz) / 1 * 16 / 2 = 128MHz)
|
||||
p: None,
|
||||
});
|
||||
|
||||
let p = embassy_stm32::init(peripheral_config);
|
||||
|
||||
// configure TIM1 mux to select PLLQ as clock source
|
||||
// https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
|
||||
// RM0444 page 210
|
||||
// RCC - Peripherals Independent Clock Control Register - bit 22 -> 1
|
||||
pac::RCC.ccipr().modify(|w| w.set_tim1sel(Tim1sel::PLL1_Q));
|
||||
// configure TIM1 mux to select PLLQ as clock source
|
||||
// https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
|
||||
// RM0444 page 210
|
||||
// RCC - Peripherals Independent Clock Control Register - bit 22 -> 1
|
||||
config.rcc.mux.tim1sel = embassy_stm32::rcc::mux::Tim1sel::PLL1_Q;
|
||||
}
|
||||
let p = embassy_stm32::init(config);
|
||||
|
||||
let ch1 = PwmPin::new_ch1(p.PA8, OutputType::PushPull);
|
||||
let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull);
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
use defmt::{panic, *};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_stm32::rcc::{Hsi48Config, UsbSrc};
|
||||
use embassy_stm32::usb::{Driver, Instance};
|
||||
use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
|
||||
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
|
||||
|
@ -19,10 +18,11 @@ bind_interrupts!(struct Irqs {
|
|||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let mut config = Config::default();
|
||||
config.rcc.usb_src = Some(UsbSrc::Hsi48(Hsi48Config {
|
||||
sync_from_usb: true,
|
||||
..Default::default()
|
||||
}));
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true });
|
||||
config.rcc.mux.usbsel = mux::Usbsel::HSI48;
|
||||
}
|
||||
let p = embassy_stm32::init(config);
|
||||
|
||||
info!("Hello World!");
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_stm32::adc::{Adc, SampleTime};
|
||||
use embassy_stm32::rcc::{AdcClockSource, Pll, PllMul, PllPreDiv, PllRDiv, Pllsrc, Sysclk};
|
||||
use embassy_stm32::Config;
|
||||
use embassy_time::{Delay, Timer};
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
@ -12,20 +11,20 @@ use {defmt_rtt as _, panic_probe as _};
|
|||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let mut config = Config::default();
|
||||
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: Pllsrc::HSI,
|
||||
prediv: PllPreDiv::DIV4,
|
||||
mul: PllMul::MUL85,
|
||||
divp: None,
|
||||
divq: None,
|
||||
// Main system clock at 170 MHz
|
||||
divr: Some(PllRDiv::DIV2),
|
||||
});
|
||||
|
||||
config.rcc.adc12_clock_source = AdcClockSource::SYS;
|
||||
config.rcc.sys = Sysclk::PLL1_R;
|
||||
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: Pllsrc::HSI,
|
||||
prediv: PllPreDiv::DIV4,
|
||||
mul: PllMul::MUL85,
|
||||
divp: None,
|
||||
divq: None,
|
||||
// Main system clock at 170 MHz
|
||||
divr: Some(PllRDiv::DIV2),
|
||||
});
|
||||
config.rcc.mux.adc12sel = mux::Adcsel::SYS;
|
||||
config.rcc.sys = Sysclk::PLL1_R;
|
||||
}
|
||||
let mut p = embassy_stm32::init(config);
|
||||
info!("Hello World!");
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_stm32::peripherals::*;
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::{bind_interrupts, can, Config};
|
||||
use embassy_time::Timer;
|
||||
use static_cell::StaticCell;
|
||||
|
@ -15,8 +16,24 @@ bind_interrupts!(struct Irqs {
|
|||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let config = Config::default();
|
||||
|
||||
let mut config = Config::default();
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(24_000_000),
|
||||
mode: HseMode::Oscillator,
|
||||
});
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: Pllsrc::HSE,
|
||||
prediv: PllPreDiv::DIV6,
|
||||
mul: PllMul::MUL85,
|
||||
divp: None,
|
||||
divq: Some(PllQDiv::DIV8), // 42.5 Mhz for fdcan.
|
||||
divr: Some(PllRDiv::DIV2), // Main system clock at 170 MHz
|
||||
});
|
||||
config.rcc.mux.fdcansel = mux::Fdcansel::PLL1_Q;
|
||||
config.rcc.sys = Sysclk::PLL1_R;
|
||||
}
|
||||
let peripherals = embassy_stm32::init(config);
|
||||
|
||||
let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
|
||||
|
@ -184,7 +201,11 @@ async fn main(_spawner: Spawner) {
|
|||
let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
|
||||
info!("Writing frame");
|
||||
|
||||
_ = can.write(frame).await;
|
||||
// You can use any of these approaches to send. The writer makes it
|
||||
// easy to share sending from multiple tasks.
|
||||
//_ = can.write(frame).await;
|
||||
//can.writer().try_write(frame).unwrap();
|
||||
can.writer().write(frame).await;
|
||||
|
||||
match can.read().await {
|
||||
Ok((rx_frame, ts)) => {
|
||||
|
|
|
@ -12,6 +12,7 @@ use {defmt_rtt as _, panic_probe as _};
|
|||
async fn main(_spawner: Spawner) {
|
||||
let mut config = Config::default();
|
||||
|
||||
config.rcc.hsi = true;
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: Pllsrc::HSI,
|
||||
prediv: PllPreDiv::DIV4,
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
|
||||
use defmt::{panic, *};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_stm32::rcc::{
|
||||
Clk48Src, Hse, HseMode, Hsi48Config, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, Pllsrc, Sysclk,
|
||||
};
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::usb::{self, Driver, Instance};
|
||||
use embassy_stm32::{bind_interrupts, peripherals, Config};
|
||||
|
@ -22,38 +19,27 @@ bind_interrupts!(struct Irqs {
|
|||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let mut config = Config::default();
|
||||
|
||||
// Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE.
|
||||
const USE_HSI48: bool = true;
|
||||
|
||||
let plldivq = if USE_HSI48 { None } else { Some(PllQDiv::DIV6) };
|
||||
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
mode: HseMode::Oscillator,
|
||||
});
|
||||
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: Pllsrc::HSE,
|
||||
prediv: PllPreDiv::DIV2,
|
||||
mul: PllMul::MUL72,
|
||||
divp: None,
|
||||
divq: plldivq,
|
||||
// Main system clock at 144 MHz
|
||||
divr: Some(PllRDiv::DIV2),
|
||||
});
|
||||
|
||||
config.rcc.sys = Sysclk::PLL1_R;
|
||||
config.rcc.boost = true; // BOOST!
|
||||
|
||||
if USE_HSI48 {
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
// Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
|
||||
config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true });
|
||||
config.rcc.clk48_src = Clk48Src::HSI48;
|
||||
} else {
|
||||
config.rcc.clk48_src = Clk48Src::PLL1_Q;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
mode: HseMode::Oscillator,
|
||||
});
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: Pllsrc::HSE,
|
||||
prediv: PllPreDiv::DIV2,
|
||||
mul: PllMul::MUL72,
|
||||
divp: None,
|
||||
divq: Some(PllQDiv::DIV6), // 48mhz
|
||||
divr: Some(PllRDiv::DIV2), // Main system clock at 144 MHz
|
||||
});
|
||||
config.rcc.sys = Sysclk::PLL1_R;
|
||||
config.rcc.boost = true; // BOOST!
|
||||
config.rcc.mux.clk48sel = mux::Clk48sel::HSI48;
|
||||
//config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; // uncomment to use PLL1_Q instead.
|
||||
}
|
||||
|
||||
let p = embassy_stm32::init(config);
|
||||
|
||||
info!("Hello World!");
|
||||
|
|
|
@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) {
|
|||
freq: embassy_stm32::time::Hertz(25_000_000),
|
||||
mode: rcc::HseMode::Oscillator,
|
||||
});
|
||||
config.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE;
|
||||
config.rcc.mux.fdcan12sel = rcc::mux::Fdcansel::HSE;
|
||||
|
||||
let peripherals = embassy_stm32::init(config);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use defmt::{panic, *};
|
|||
use embassy_executor::Spawner;
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::usb::{Driver, Instance};
|
||||
use embassy_stm32::{bind_interrupts, pac, peripherals, usb, Config};
|
||||
use embassy_stm32::{bind_interrupts, peripherals, usb, Config};
|
||||
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
|
||||
use embassy_usb::driver::EndpointError;
|
||||
use embassy_usb::Builder;
|
||||
|
@ -41,15 +41,12 @@ async fn main(_spawner: Spawner) {
|
|||
config.rcc.apb3_pre = APBPrescaler::DIV4;
|
||||
config.rcc.sys = Sysclk::PLL1_P;
|
||||
config.rcc.voltage_scale = VoltageScale::Scale0;
|
||||
config.rcc.mux.usbsel = mux::Usbsel::HSI48;
|
||||
}
|
||||
let p = embassy_stm32::init(config);
|
||||
|
||||
info!("Hello World!");
|
||||
|
||||
pac::RCC.ccipr4().write(|w| {
|
||||
w.set_usbsel(pac::rcc::vals::Usbsel::HSI48);
|
||||
});
|
||||
|
||||
// Create the driver, from the HAL.
|
||||
let driver = Driver::new(p.USB, Irqs, p.PA12, p.PA11);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ async fn main(_spawner: Spawner) {
|
|||
config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
|
||||
config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
|
||||
config.rcc.voltage_scale = VoltageScale::Scale1;
|
||||
config.rcc.adc_clock_source = AdcClockSource::PLL2_P;
|
||||
config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
|
||||
}
|
||||
let mut p = embassy_stm32::init(config);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) {
|
|||
freq: embassy_stm32::time::Hertz(25_000_000),
|
||||
mode: rcc::HseMode::Oscillator,
|
||||
});
|
||||
config.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE;
|
||||
config.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
|
||||
|
||||
let peripherals = embassy_stm32::init(config);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ fn main() -> ! {
|
|||
config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
|
||||
config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
|
||||
config.rcc.voltage_scale = VoltageScale::Scale1;
|
||||
config.rcc.adc_clock_source = AdcClockSource::PLL2_P;
|
||||
config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
|
||||
}
|
||||
let p = embassy_stm32::init(config);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ async fn main(spawner: Spawner) {
|
|||
config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
|
||||
config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
|
||||
config.rcc.voltage_scale = VoltageScale::Scale1;
|
||||
config.rcc.adc_clock_source = AdcClockSource::PLL2_P;
|
||||
config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
|
||||
}
|
||||
|
||||
// Initialize the board and obtain a Peripherals instance
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use defmt::*;
|
||||
use embassy_stm32::adc::{Adc, Resolution};
|
||||
use embassy_stm32::pac;
|
||||
use embassy_stm32::Config;
|
||||
use embassy_time::Delay;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
|
@ -11,12 +11,12 @@ use {defmt_rtt as _, panic_probe as _};
|
|||
fn main() -> ! {
|
||||
info!("Hello World!");
|
||||
|
||||
pac::RCC.ccipr().modify(|w| {
|
||||
w.set_adcsel(pac::rcc::vals::Adcsel::SYS);
|
||||
});
|
||||
pac::RCC.ahb2enr().modify(|w| w.set_adcen(true));
|
||||
|
||||
let p = embassy_stm32::init(Default::default());
|
||||
let mut config = Config::default();
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.mux.adcsel = mux::Adcsel::SYS;
|
||||
}
|
||||
let p = embassy_stm32::init(config);
|
||||
|
||||
let mut adc = Adc::new(p.ADC1, &mut Delay);
|
||||
//adc.enable_vref();
|
||||
|
|
|
@ -16,8 +16,8 @@ stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"]
|
|||
stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac"]
|
||||
stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan"]
|
||||
stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "hash"]
|
||||
stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash"]
|
||||
stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash"]
|
||||
stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"]
|
||||
stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"]
|
||||
stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng", "fdcan"]
|
||||
stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"]
|
||||
stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"]
|
||||
|
@ -33,6 +33,7 @@ stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"]
|
|||
stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"]
|
||||
stm32h503rb = ["embassy-stm32/stm32h503rb", "rng"]
|
||||
|
||||
cryp = []
|
||||
hash = []
|
||||
eth = ["embassy-executor/task-arena-size-16384"]
|
||||
rng = []
|
||||
|
@ -80,6 +81,7 @@ portable-atomic = { version = "1.5", features = [] }
|
|||
chrono = { version = "^0.4", default-features = false, optional = true}
|
||||
sha2 = { version = "0.10.8", default-features = false }
|
||||
hmac = "0.12.1"
|
||||
aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] }
|
||||
|
||||
# BEGIN TESTS
|
||||
# Generated by gen_test.py. DO NOT EDIT.
|
||||
|
@ -88,6 +90,11 @@ name = "can"
|
|||
path = "src/bin/can.rs"
|
||||
required-features = [ "can",]
|
||||
|
||||
[[bin]]
|
||||
name = "cryp"
|
||||
path = "src/bin/cryp.rs"
|
||||
required-features = [ "cryp",]
|
||||
|
||||
[[bin]]
|
||||
name = "dac"
|
||||
path = "src/bin/dac.rs"
|
||||
|
|
69
tests/stm32/src/bin/cryp.rs
Normal file
69
tests/stm32/src/bin/cryp.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
// required-features: cryp
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[path = "../common.rs"]
|
||||
mod common;
|
||||
|
||||
use aes_gcm::aead::heapless::Vec;
|
||||
use aes_gcm::aead::{AeadInPlace, KeyInit};
|
||||
use aes_gcm::Aes128Gcm;
|
||||
use common::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_stm32::cryp::*;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let p: embassy_stm32::Peripherals = embassy_stm32::init(config());
|
||||
|
||||
const PAYLOAD1: &[u8] = b"payload data 1 ;zdfhzdfhS;GKJASBDG;ASKDJBAL,zdfhzdfhzdfhzdfhvljhb,jhbjhb,sdhsdghsdhsfhsghzdfhzdfhzdfhzdfdhsdthsthsdhsgaadfhhgkdgfuoyguoft6783567";
|
||||
const PAYLOAD2: &[u8] = b"payload data 2 ;SKEzdfhzdfhzbhgvljhb,jhbjhb,sdhsdghsdhsfhsghshsfhshstsdthadfhsdfjhsfgjsfgjxfgjzdhgDFghSDGHjtfjtjszftjzsdtjhstdsdhsdhsdhsdhsdthsthsdhsgfh";
|
||||
const AAD1: &[u8] = b"additional data 1 stdargadrhaethaethjatjatjaetjartjstrjsfkk;'jopofyuisrteytweTASTUIKFUKIXTRDTEREharhaeryhaterjartjarthaethjrtjarthaetrhartjatejatrjsrtjartjyt1";
|
||||
const AAD2: &[u8] = b"additional data 2 stdhthsthsthsrthsrthsrtjdykjdukdyuldadfhsdghsdghsdghsadghjk'hioethjrtjarthaetrhartjatecfgjhzdfhgzdfhzdfghzdfhzdfhzfhjatrjsrtjartjytjfytjfyg";
|
||||
|
||||
let hw_cryp = Cryp::new(p.CRYP);
|
||||
let key: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
|
||||
let mut ciphertext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()];
|
||||
let mut plaintext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()];
|
||||
let iv: [u8; 12] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
||||
|
||||
// Encrypt in hardware using AES-GCM 128-bit
|
||||
let aes_gcm = AesGcm::new(&key, &iv);
|
||||
let mut gcm_encrypt = hw_cryp.start(&aes_gcm, Direction::Encrypt);
|
||||
hw_cryp.aad_blocking(&mut gcm_encrypt, AAD1, false);
|
||||
hw_cryp.aad_blocking(&mut gcm_encrypt, AAD2, true);
|
||||
hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD1, &mut ciphertext[..PAYLOAD1.len()], false);
|
||||
hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD2, &mut ciphertext[PAYLOAD1.len()..], true);
|
||||
let encrypt_tag = hw_cryp.finish_blocking(gcm_encrypt);
|
||||
|
||||
// Decrypt in hardware using AES-GCM 128-bit
|
||||
let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt);
|
||||
hw_cryp.aad_blocking(&mut gcm_decrypt, AAD1, false);
|
||||
hw_cryp.aad_blocking(&mut gcm_decrypt, AAD2, true);
|
||||
hw_cryp.payload_blocking(&mut gcm_decrypt, &ciphertext, &mut plaintext, true);
|
||||
let decrypt_tag = hw_cryp.finish_blocking(gcm_decrypt);
|
||||
|
||||
info!("AES-GCM Ciphertext: {:?}", ciphertext);
|
||||
info!("AES-GCM Plaintext: {:?}", plaintext);
|
||||
defmt::assert!(PAYLOAD1 == &plaintext[..PAYLOAD1.len()]);
|
||||
defmt::assert!(PAYLOAD2 == &plaintext[PAYLOAD1.len()..]);
|
||||
defmt::assert!(encrypt_tag == decrypt_tag);
|
||||
|
||||
// Encrypt in software using AES-GCM 128-bit
|
||||
let mut payload_vec: Vec<u8, { PAYLOAD1.len() + PAYLOAD2.len() + 16 }> = Vec::from_slice(&PAYLOAD1).unwrap();
|
||||
payload_vec.extend_from_slice(&PAYLOAD2).unwrap();
|
||||
let cipher = Aes128Gcm::new(&key.into());
|
||||
let mut aad: Vec<u8, { AAD1.len() + AAD2.len() }> = Vec::from_slice(&AAD1).unwrap();
|
||||
aad.extend_from_slice(&AAD2).unwrap();
|
||||
let _ = cipher.encrypt_in_place(&iv.into(), &aad, &mut payload_vec);
|
||||
|
||||
defmt::assert!(ciphertext == payload_vec[0..ciphertext.len()]);
|
||||
defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]);
|
||||
|
||||
// Decrypt in software using AES-GCM 128-bit
|
||||
let _ = cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec);
|
||||
|
||||
info!("Test OK");
|
||||
cortex_m::asm::bkpt();
|
||||
}
|
|
@ -33,7 +33,7 @@ fn options() -> TestOptions {
|
|||
freq: embassy_stm32::time::Hertz(25_000_000),
|
||||
mode: rcc::HseMode::Oscillator,
|
||||
});
|
||||
c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE;
|
||||
c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
|
||||
TestOptions {
|
||||
config: c,
|
||||
max_latency: Duration::from_micros(1200),
|
||||
|
@ -50,7 +50,7 @@ fn options() -> TestOptions {
|
|||
freq: embassy_stm32::time::Hertz(25_000_000),
|
||||
mode: rcc::HseMode::Oscillator,
|
||||
});
|
||||
c.rcc.fdcan_clock_source = rcc::FdCanClockSource::HSE;
|
||||
c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE;
|
||||
TestOptions {
|
||||
config: c,
|
||||
max_latency: Duration::from_micros(1200),
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
pub use defmt::*;
|
||||
#[allow(unused)]
|
||||
use embassy_stm32::rcc::*;
|
||||
#[allow(unused)]
|
||||
use embassy_stm32::time::Hertz;
|
||||
use embassy_stm32::Config;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
@ -265,7 +267,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32f091rc")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
mode: HseMode::Bypass,
|
||||
|
@ -281,7 +282,6 @@ pub fn config() -> Config {
|
|||
}
|
||||
#[cfg(feature = "stm32f103c8")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
mode: HseMode::Oscillator,
|
||||
|
@ -298,7 +298,6 @@ pub fn config() -> Config {
|
|||
}
|
||||
#[cfg(feature = "stm32f207zg")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
// By default, HSE on the board comes from a 8 MHz clock signal (not a crystal)
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
|
@ -327,7 +326,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32f303ze")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
mode: HseMode::Bypass,
|
||||
|
@ -345,7 +343,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32f429zi")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
mode: HseMode::Bypass,
|
||||
|
@ -366,7 +363,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32f446re")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
mode: HseMode::Oscillator,
|
||||
|
@ -387,7 +383,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32f767zi")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(8_000_000),
|
||||
mode: HseMode::Bypass,
|
||||
|
@ -408,7 +403,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32h563zi")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi = None;
|
||||
config.rcc.hsi48 = Some(Default::default()); // needed for RNG
|
||||
config.rcc.hse = Some(Hse {
|
||||
|
@ -433,7 +427,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32h503rb")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi = None;
|
||||
config.rcc.hsi48 = Some(Default::default()); // needed for RNG
|
||||
config.rcc.hse = Some(Hse {
|
||||
|
@ -456,9 +449,26 @@ pub fn config() -> Config {
|
|||
config.rcc.voltage_scale = VoltageScale::Scale0;
|
||||
}
|
||||
|
||||
#[cfg(feature = "stm32g491re")]
|
||||
{
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(24_000_000),
|
||||
mode: HseMode::Oscillator,
|
||||
});
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: Pllsrc::HSE,
|
||||
prediv: PllPreDiv::DIV6,
|
||||
mul: PllMul::MUL85,
|
||||
divp: None,
|
||||
divq: Some(PllQDiv::DIV8), // 42.5 Mhz for fdcan.
|
||||
divr: Some(PllRDiv::DIV2), // Main system clock at 170 MHz
|
||||
});
|
||||
config.rcc.mux.fdcansel = mux::Fdcansel::PLL1_Q;
|
||||
config.rcc.sys = Sysclk::PLL1_R;
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
||||
config.rcc.csi = true;
|
||||
config.rcc.hsi48 = Some(Default::default()); // needed for RNG
|
||||
|
@ -485,7 +495,7 @@ pub fn config() -> Config {
|
|||
config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
|
||||
config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
|
||||
config.rcc.voltage_scale = VoltageScale::Scale1;
|
||||
config.rcc.adc_clock_source = AdcClockSource::PLL2_P;
|
||||
config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
|
||||
#[cfg(any(feature = "stm32h755zi"))]
|
||||
{
|
||||
config.rcc.supply_config = SupplyConfig::DirectSMPS;
|
||||
|
@ -494,7 +504,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(any(feature = "stm32h7a3zi"))]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi = Some(HSIPrescaler::DIV1);
|
||||
config.rcc.csi = true;
|
||||
config.rcc.hsi48 = Some(Default::default()); // needed for RNG
|
||||
|
@ -521,12 +530,11 @@ pub fn config() -> Config {
|
|||
config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz
|
||||
config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz
|
||||
config.rcc.voltage_scale = VoltageScale::Scale0;
|
||||
config.rcc.adc_clock_source = AdcClockSource::PLL2_P;
|
||||
config.rcc.mux.adcsel = mux::Adcsel::PLL2_P;
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.sys = Sysclk::PLL1_R;
|
||||
config.rcc.hsi = true;
|
||||
config.rcc.pll = Some(Pll {
|
||||
|
@ -541,7 +549,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32wl55jc")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hse = Some(Hse {
|
||||
freq: Hertz(32_000_000),
|
||||
mode: HseMode::Bypass,
|
||||
|
@ -560,7 +567,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(any(feature = "stm32l552ze"))]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi = true;
|
||||
config.rcc.sys = Sysclk::PLL1_R;
|
||||
config.rcc.pll = Some(Pll {
|
||||
|
@ -576,7 +582,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi = true;
|
||||
config.rcc.pll1 = Some(Pll {
|
||||
source: PllSource::HSI, // 16 MHz
|
||||
|
@ -593,17 +598,12 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(feature = "stm32wba52cg")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.sys = Sysclk::HSI;
|
||||
|
||||
embassy_stm32::pac::RCC.ccipr2().write(|w| {
|
||||
w.set_rngsel(embassy_stm32::pac::rcc::vals::Rngsel::HSI);
|
||||
});
|
||||
config.rcc.mux.rngsel = mux::Rngsel::HSI;
|
||||
}
|
||||
|
||||
#[cfg(feature = "stm32l073rz")]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi = true;
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: PllSource::HSI,
|
||||
|
@ -615,7 +615,6 @@ pub fn config() -> Config {
|
|||
|
||||
#[cfg(any(feature = "stm32l152re"))]
|
||||
{
|
||||
use embassy_stm32::rcc::*;
|
||||
config.rcc.hsi = true;
|
||||
config.rcc.pll = Some(Pll {
|
||||
source: PllSource::HSI,
|
||||
|
|
Loading…
Add table
Reference in a new issue