aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorFelipe Balbi <[email protected]>2025-12-11 09:48:32 -0800
committerFelipe Balbi <[email protected]>2025-12-11 09:48:32 -0800
commit86de5d04b91f38ab4322eaa8ff5b0f371824b57a (patch)
treef758f462bd3cc7f670fdb7613282d1beaedefb95 /examples
parentaf02ef481498441289a6decfe3baf7f3878f7871 (diff)
parent3588023e3e04b18cf98a2a0d10756e1f236ca351 (diff)
Merge remote-tracking branch 'upstream/main' into mcxa/trng
Diffstat (limited to 'examples')
-rw-r--r--examples/mcxa/src/bin/adc_interrupt.rs65
-rw-r--r--examples/mcxa/src/bin/adc_polling.rs58
-rw-r--r--examples/mcxa/src/bin/clkout.rs3
-rw-r--r--examples/mcxa/src/bin/i2c-scan-blocking.rs3
-rw-r--r--examples/mcxa/src/bin/reset-reason.rs15
-rw-r--r--examples/mcxa/src/lib.rs16
-rw-r--r--examples/rp/src/bin/wifi_tcp_server.rs2
-rw-r--r--examples/rp/src/bin/wifi_webrequest.rs2
-rw-r--r--examples/stm32f4/src/bin/sdmmc.rs38
-rw-r--r--examples/stm32f7/src/bin/sdmmc.rs11
-rw-r--r--examples/stm32h7/src/bin/sdmmc.rs13
-rw-r--r--examples/stm32n6/Cargo.toml2
-rw-r--r--examples/stm32n6/src/bin/crc.rs31
-rw-r--r--examples/stm32n6/src/bin/hash.rs78
-rw-r--r--examples/stm32wba/src/bin/rtc.rs62
-rw-r--r--examples/stm32wba6/src/bin/rtc.rs62
16 files changed, 343 insertions, 118 deletions
diff --git a/examples/mcxa/src/bin/adc_interrupt.rs b/examples/mcxa/src/bin/adc_interrupt.rs
index c88b1fe8d..d2cda631c 100644
--- a/examples/mcxa/src/bin/adc_interrupt.rs
+++ b/examples/mcxa/src/bin/adc_interrupt.rs
@@ -2,34 +2,31 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa_examples::init_adc_pins; 5use embassy_time::{Duration, Ticker};
6use hal::adc::{LpadcConfig, TriggerPriorityPolicy}; 6use hal::adc::{Adc, InterruptHandler, LpadcConfig, TriggerPriorityPolicy};
7use hal::bind_interrupts;
7use hal::clocks::PoweredClock; 8use hal::clocks::PoweredClock;
9use hal::clocks::config::Div8;
8use hal::clocks::periph_helpers::{AdcClockSel, Div4}; 10use hal::clocks::periph_helpers::{AdcClockSel, Div4};
11use hal::config::Config;
9use hal::pac::adc1::cfg::{Pwrsel, Refsel}; 12use hal::pac::adc1::cfg::{Pwrsel, Refsel};
10use hal::pac::adc1::cmdl1::{Adch, Mode}; 13use hal::pac::adc1::cmdl1::Mode;
11use hal::pac::adc1::ctrl::CalAvgs; 14use hal::pac::adc1::ctrl::CalAvgs;
12use hal::pac::adc1::tctrl::Tcmd; 15use hal::peripherals::ADC1;
13use hal::{InterruptExt, bind_interrupts};
14use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 16use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
15 17
16bind_interrupts!(struct Irqs { 18bind_interrupts!(struct Irqs {
17 ADC1 => hal::adc::AdcHandler; 19 ADC1 => InterruptHandler<ADC1>;
18}); 20});
19 21
20#[used]
21#[no_mangle]
22static KEEP_ADC: unsafe extern "C" fn() = ADC1;
23
24#[embassy_executor::main] 22#[embassy_executor::main]
25async fn main(_spawner: Spawner) { 23async fn main(_spawner: Spawner) {
26 let p = hal::init(hal::config::Config::default()); 24 let mut config = Config::default();
25 config.clock_cfg.sirc.fro_lf_div = Div8::from_divisor(1);
27 26
28 defmt::info!("ADC interrupt Example"); 27 let p = hal::init(config);
29 28
30 unsafe { 29 defmt::info!("ADC interrupt Example");
31 init_adc_pins();
32 }
33 30
34 let adc_config = LpadcConfig { 31 let adc_config = LpadcConfig {
35 enable_in_doze_mode: true, 32 enable_in_doze_mode: true,
@@ -41,44 +38,28 @@ async fn main(_spawner: Spawner) {
41 trigger_priority_policy: TriggerPriorityPolicy::ConvPreemptImmediatelyNotAutoResumed, 38 trigger_priority_policy: TriggerPriorityPolicy::ConvPreemptImmediatelyNotAutoResumed,
42 enable_conv_pause: false, 39 enable_conv_pause: false,
43 conv_pause_delay: 0, 40 conv_pause_delay: 0,
44 fifo_watermark: 0,
45 power: PoweredClock::NormalEnabledDeepSleepDisabled, 41 power: PoweredClock::NormalEnabledDeepSleepDisabled,
46 source: AdcClockSel::FroLfDiv, 42 source: AdcClockSel::FroLfDiv,
47 div: Div4::no_div(), 43 div: Div4::no_div(),
48 }; 44 };
49 let adc = hal::adc::Adc::<hal::adc::Adc1>::new(p.ADC1, adc_config); 45 let mut adc = Adc::new_async(p.ADC1, p.P1_10, Irqs, adc_config).unwrap();
50 46
51 adc.do_offset_calibration(); 47 adc.do_offset_calibration();
52 adc.do_auto_calibration(); 48 adc.do_auto_calibration();
53 49 adc.set_resolution(Mode::Data16Bits);
54 let mut conv_command_config = adc.get_default_conv_command_config();
55 conv_command_config.channel_number = Adch::SelectCorrespondingChannel8;
56 conv_command_config.conversion_resolution_mode = Mode::Data16Bits;
57 adc.set_conv_command_config(1, &conv_command_config);
58
59 let mut conv_trigger_config = adc.get_default_conv_trigger_config();
60 conv_trigger_config.target_command_id = Tcmd::ExecuteCmd1;
61 conv_trigger_config.enable_hardware_trigger = false;
62 adc.set_conv_trigger_config(0, &conv_trigger_config);
63 50
64 defmt::info!("ADC configuration done..."); 51 defmt::info!("ADC configuration done...");
65 52 let mut ticker = Ticker::every(Duration::from_millis(100));
66 adc.enable_interrupt(0x1);
67
68 unsafe {
69 hal::interrupt::ADC1.enable();
70 }
71
72 unsafe {
73 cortex_m::interrupt::enable();
74 }
75 53
76 loop { 54 loop {
77 adc.do_software_trigger(1); 55 ticker.next().await;
78 while !adc.is_interrupt_triggered() { 56 match adc.read().await {
79 // Wait until the interrupt is triggered 57 Ok(value) => {
58 defmt::info!("ADC value: {}", value);
59 }
60 Err(e) => {
61 defmt::error!("ADC read error: {:?}", e);
62 }
80 } 63 }
81 defmt::info!("*** ADC interrupt TRIGGERED! ***");
82 //TBD need to print the value
83 } 64 }
84} 65}
diff --git a/examples/mcxa/src/bin/adc_polling.rs b/examples/mcxa/src/bin/adc_polling.rs
index 07c50f224..5c4d5524c 100644
--- a/examples/mcxa/src/bin/adc_polling.rs
+++ b/examples/mcxa/src/bin/adc_polling.rs
@@ -2,12 +2,15 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa_examples::init_adc_pins; 5use embassy_mcxa::adc::{ConvCommandConfig, ConvTriggerConfig};
6use hal::adc::{ConvResult, LpadcConfig, TriggerPriorityPolicy}; 6use embassy_time::{Duration, Ticker};
7use hal::adc::{Adc, LpadcConfig, TriggerPriorityPolicy};
7use hal::clocks::PoweredClock; 8use hal::clocks::PoweredClock;
9use hal::clocks::config::Div8;
8use hal::clocks::periph_helpers::{AdcClockSel, Div4}; 10use hal::clocks::periph_helpers::{AdcClockSel, Div4};
11use hal::config::Config;
9use hal::pac::adc1::cfg::{Pwrsel, Refsel}; 12use hal::pac::adc1::cfg::{Pwrsel, Refsel};
10use hal::pac::adc1::cmdl1::{Adch, Mode}; 13use hal::pac::adc1::cmdl1::Mode;
11use hal::pac::adc1::ctrl::CalAvgs; 14use hal::pac::adc1::ctrl::CalAvgs;
12use hal::pac::adc1::tctrl::Tcmd; 15use hal::pac::adc1::tctrl::Tcmd;
13use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 16use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
@@ -16,11 +19,10 @@ const G_LPADC_RESULT_SHIFT: u32 = 0;
16 19
17#[embassy_executor::main] 20#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 21async fn main(_spawner: Spawner) {
19 let p = hal::init(hal::config::Config::default()); 22 let mut config = Config::default();
23 config.clock_cfg.sirc.fro_lf_div = Div8::from_divisor(1);
20 24
21 unsafe { 25 let p = hal::init(config);
22 init_adc_pins();
23 }
24 26
25 defmt::info!("=== ADC polling Example ==="); 27 defmt::info!("=== ADC polling Example ===");
26 28
@@ -34,35 +36,43 @@ async fn main(_spawner: Spawner) {
34 trigger_priority_policy: TriggerPriorityPolicy::ConvPreemptImmediatelyNotAutoResumed, 36 trigger_priority_policy: TriggerPriorityPolicy::ConvPreemptImmediatelyNotAutoResumed,
35 enable_conv_pause: false, 37 enable_conv_pause: false,
36 conv_pause_delay: 0, 38 conv_pause_delay: 0,
37 fifo_watermark: 0,
38 power: PoweredClock::NormalEnabledDeepSleepDisabled, 39 power: PoweredClock::NormalEnabledDeepSleepDisabled,
39 source: AdcClockSel::FroLfDiv, 40 source: AdcClockSel::FroLfDiv,
40 div: Div4::no_div(), 41 div: Div4::no_div(),
41 }; 42 };
42 let adc = hal::adc::Adc::<hal::adc::Adc1>::new(p.ADC1, adc_config); 43 let adc = Adc::new_blocking(p.ADC1, p.P1_10, adc_config).unwrap();
43 44
44 adc.do_offset_calibration(); 45 adc.do_offset_calibration();
45 adc.do_auto_calibration(); 46 adc.do_auto_calibration();
46 47
47 let mut conv_command_config = adc.get_default_conv_command_config(); 48 let conv_command_config = ConvCommandConfig {
48 conv_command_config.channel_number = Adch::SelectCorrespondingChannel8; 49 conversion_resolution_mode: Mode::Data16Bits,
49 conv_command_config.conversion_resolution_mode = Mode::Data16Bits; 50 ..ConvCommandConfig::default()
50 adc.set_conv_command_config(1, &conv_command_config); 51 };
52 adc.set_conv_command_config(1, &conv_command_config).unwrap();
51 53
52 let mut conv_trigger_config = adc.get_default_conv_trigger_config(); 54 let conv_trigger_config = ConvTriggerConfig {
53 conv_trigger_config.target_command_id = Tcmd::ExecuteCmd1; 55 target_command_id: Tcmd::ExecuteCmd1,
54 conv_trigger_config.enable_hardware_trigger = false; 56 enable_hardware_trigger: false,
55 adc.set_conv_trigger_config(0, &conv_trigger_config); 57 ..Default::default()
58 };
59 adc.set_conv_trigger_config(0, &conv_trigger_config).unwrap();
56 60
57 defmt::info!("=== ADC configuration done... ==="); 61 defmt::info!("=== ADC configuration done... ===");
62 let mut tick = Ticker::every(Duration::from_millis(100));
58 63
59 loop { 64 loop {
60 adc.do_software_trigger(1); 65 tick.next().await;
61 let mut result: Option<ConvResult> = None; 66 adc.do_software_trigger(1).unwrap();
62 while result.is_none() { 67 let result = loop {
63 result = hal::adc::get_conv_result(); 68 match adc.get_conv_result() {
64 } 69 Ok(res) => break res,
65 let value = result.unwrap().conv_value >> G_LPADC_RESULT_SHIFT; 70 Err(_) => {
66 defmt::info!("value: {=u16}", value); 71 // Conversion not ready, continue polling
72 }
73 }
74 };
75 let value = result.conv_value >> G_LPADC_RESULT_SHIFT;
76 defmt::info!("ADC value: {=u16}", value);
67 } 77 }
68} 78}
diff --git a/examples/mcxa/src/bin/clkout.rs b/examples/mcxa/src/bin/clkout.rs
index bfd963540..1e52912d3 100644
--- a/examples/mcxa/src/bin/clkout.rs
+++ b/examples/mcxa/src/bin/clkout.rs
@@ -4,8 +4,7 @@
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa::clkout::{ClockOut, ClockOutSel, Config, Div4}; 5use embassy_mcxa::clkout::{ClockOut, ClockOutSel, Config, Div4};
6use embassy_mcxa::clocks::PoweredClock; 6use embassy_mcxa::clocks::PoweredClock;
7use embassy_mcxa::gpio::{DriveStrength, SlewRate}; 7use embassy_mcxa::gpio::{DriveStrength, Level, Output, SlewRate};
8use embassy_mcxa::{Level, Output};
9use embassy_time::Timer; 8use embassy_time::Timer;
10use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 9use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
11 10
diff --git a/examples/mcxa/src/bin/i2c-scan-blocking.rs b/examples/mcxa/src/bin/i2c-scan-blocking.rs
index 0197f9b1d..bd706d712 100644
--- a/examples/mcxa/src/bin/i2c-scan-blocking.rs
+++ b/examples/mcxa/src/bin/i2c-scan-blocking.rs
@@ -2,8 +2,7 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa::Input; 5use embassy_mcxa::gpio::{Input, Pull};
6use embassy_mcxa::gpio::Pull;
7use embassy_time::Timer; 6use embassy_time::Timer;
8use hal::clocks::config::Div8; 7use hal::clocks::config::Div8;
9use hal::config::Config; 8use hal::config::Config;
diff --git a/examples/mcxa/src/bin/reset-reason.rs b/examples/mcxa/src/bin/reset-reason.rs
new file mode 100644
index 000000000..c244fbe04
--- /dev/null
+++ b/examples/mcxa/src/bin/reset-reason.rs
@@ -0,0 +1,15 @@
1#![no_std]
2#![no_main]
3
4use embassy_executor::Spawner;
5use hal::config::Config;
6use hal::reset_reason::reset_reason;
7use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
8
9#[embassy_executor::main]
10async fn main(_spawner: Spawner) {
11 let config = Config::default();
12 let _p = hal::init(config);
13
14 defmt::info!("Reset Reason: '{}'", reset_reason());
15}
diff --git a/examples/mcxa/src/lib.rs b/examples/mcxa/src/lib.rs
deleted file mode 100644
index 2573a6adc..000000000
--- a/examples/mcxa/src/lib.rs
+++ /dev/null
@@ -1,16 +0,0 @@
1#![no_std]
2#![allow(clippy::missing_safety_doc)]
3
4//! Shared board-specific helpers for the FRDM-MCXA276 examples.
5//! These live with the examples so the HAL stays generic.
6
7use hal::{clocks, pins};
8use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
9
10/// Initialize clocks and pin muxing for ADC.
11pub unsafe fn init_adc_pins() {
12 // NOTE: Lpuart has been updated to properly enable + reset its own clocks.
13 // GPIO has not.
14 _ = clocks::enable_and_reset::<hal::peripherals::PORT1>(&clocks::periph_helpers::NoConfig);
15 pins::configure_adc_pins();
16}
diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs
index e39de4902..ef8d08b76 100644
--- a/examples/rp/src/bin/wifi_tcp_server.rs
+++ b/examples/rp/src/bin/wifi_tcp_server.rs
@@ -101,7 +101,7 @@ async fn main(spawner: Spawner) {
101 .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) 101 .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))
102 .await 102 .await
103 { 103 {
104 info!("join failed with status={}", err.status); 104 info!("join failed: {:?}", err);
105 } 105 }
106 106
107 info!("waiting for link..."); 107 info!("waiting for link...");
diff --git a/examples/rp/src/bin/wifi_webrequest.rs b/examples/rp/src/bin/wifi_webrequest.rs
index ce85f4b9a..069afc794 100644
--- a/examples/rp/src/bin/wifi_webrequest.rs
+++ b/examples/rp/src/bin/wifi_webrequest.rs
@@ -106,7 +106,7 @@ async fn main(spawner: Spawner) {
106 .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) 106 .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))
107 .await 107 .await
108 { 108 {
109 info!("join failed with status={}", err.status); 109 info!("join failed: {:?}", err);
110 } 110 }
111 111
112 info!("waiting for link..."); 112 info!("waiting for link...");
diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs
index fe0f887bf..098fd6986 100644
--- a/examples/stm32f4/src/bin/sdmmc.rs
+++ b/examples/stm32f4/src/bin/sdmmc.rs
@@ -3,7 +3,8 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::sdmmc::{DataBlock, Sdmmc}; 6use embassy_stm32::sdmmc::Sdmmc;
7use embassy_stm32::sdmmc::sd::{CmdBlock, DataBlock, StorageDevice};
7use embassy_stm32::time::{Hertz, mhz}; 8use embassy_stm32::time::{Hertz, mhz};
8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc}; 9use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc};
9use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -57,31 +58,24 @@ async fn main(_spawner: Spawner) {
57 // Should print 400kHz for initialization 58 // Should print 400kHz for initialization
58 info!("Configured clock: {}", sdmmc.clock().0); 59 info!("Configured clock: {}", sdmmc.clock().0);
59 60
60 let mut err = None; 61 let mut cmd_block = CmdBlock::new();
61 loop { 62
62 match sdmmc.init_sd_card(mhz(24)).await { 63 let mut storage = StorageDevice::new_sd_card(&mut sdmmc, &mut cmd_block, mhz(24))
63 Ok(_) => break, 64 .await
64 Err(e) => { 65 .unwrap();
65 if err != Some(e) {
66 info!("waiting for card error, retrying: {:?}", e);
67 err = Some(e);
68 }
69 }
70 }
71 }
72 66
73 let card = unwrap!(sdmmc.card()); 67 let card = storage.card();
74 68
75 info!("Card: {:#?}", Debug2Format(card)); 69 info!("Card: {:#?}", Debug2Format(&card));
76 info!("Clock: {}", sdmmc.clock()); 70 info!("Clock: {}", storage.sdmmc.clock());
77 71
78 // Arbitrary block index 72 // Arbitrary block index
79 let block_idx = 16; 73 let block_idx = 16;
80 74
81 // SDMMC uses `DataBlock` instead of `&[u8]` to ensure 4 byte alignment required by the hardware. 75 // SDMMC uses `DataBlock` instead of `&[u8]` to ensure 4 byte alignment required by the hardware.
82 let mut block = DataBlock([0u8; 512]); 76 let mut block = DataBlock::new();
83 77
84 sdmmc.read_block(block_idx, &mut block).await.unwrap(); 78 storage.read_block(block_idx, &mut block).await.unwrap();
85 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]); 79 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
86 80
87 if !ALLOW_WRITES { 81 if !ALLOW_WRITES {
@@ -91,17 +85,17 @@ async fn main(_spawner: Spawner) {
91 85
92 info!("Filling block with 0x55"); 86 info!("Filling block with 0x55");
93 block.fill(0x55); 87 block.fill(0x55);
94 sdmmc.write_block(block_idx, &block).await.unwrap(); 88 storage.write_block(block_idx, &block).await.unwrap();
95 info!("Write done"); 89 info!("Write done");
96 90
97 sdmmc.read_block(block_idx, &mut block).await.unwrap(); 91 storage.read_block(block_idx, &mut block).await.unwrap();
98 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]); 92 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
99 93
100 info!("Filling block with 0xAA"); 94 info!("Filling block with 0xAA");
101 block.fill(0xAA); 95 block.fill(0xAA);
102 sdmmc.write_block(block_idx, &block).await.unwrap(); 96 storage.write_block(block_idx, &block).await.unwrap();
103 info!("Write done"); 97 info!("Write done");
104 98
105 sdmmc.read_block(block_idx, &mut block).await.unwrap(); 99 storage.read_block(block_idx, &mut block).await.unwrap();
106 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]); 100 info!("Read: {=[u8]:X}...{=[u8]:X}", block[..8], block[512 - 8..]);
107} 101}
diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs
index 8809b5d0c..e5d261d89 100644
--- a/examples/stm32f7/src/bin/sdmmc.rs
+++ b/examples/stm32f7/src/bin/sdmmc.rs
@@ -4,6 +4,7 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::sdmmc::Sdmmc; 6use embassy_stm32::sdmmc::Sdmmc;
7use embassy_stm32::sdmmc::sd::{CmdBlock, StorageDevice};
7use embassy_stm32::time::{Hertz, mhz}; 8use embassy_stm32::time::{Hertz, mhz};
8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc}; 9use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc};
9use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -54,9 +55,13 @@ async fn main(_spawner: Spawner) {
54 // Should print 400kHz for initialization 55 // Should print 400kHz for initialization
55 info!("Configured clock: {}", sdmmc.clock().0); 56 info!("Configured clock: {}", sdmmc.clock().0);
56 57
57 unwrap!(sdmmc.init_sd_card(mhz(25)).await); 58 let mut cmd_block = CmdBlock::new();
58 59
59 let card = unwrap!(sdmmc.card()); 60 let storage = StorageDevice::new_sd_card(&mut sdmmc, &mut cmd_block, mhz(25))
61 .await
62 .unwrap();
60 63
61 info!("Card: {:#?}", Debug2Format(card)); 64 let card = storage.card();
65
66 info!("Card: {:#?}", Debug2Format(&card));
62} 67}
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs
index 4977fec79..f2e5bedeb 100644
--- a/examples/stm32h7/src/bin/sdmmc.rs
+++ b/examples/stm32h7/src/bin/sdmmc.rs
@@ -4,6 +4,7 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::sdmmc::Sdmmc; 6use embassy_stm32::sdmmc::Sdmmc;
7use embassy_stm32::sdmmc::sd::{CmdBlock, StorageDevice};
7use embassy_stm32::time::mhz; 8use embassy_stm32::time::mhz;
8use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc}; 9use embassy_stm32::{Config, bind_interrupts, peripherals, sdmmc};
9use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -13,7 +14,7 @@ bind_interrupts!(struct Irqs {
13}); 14});
14 15
15#[embassy_executor::main] 16#[embassy_executor::main]
16async fn main(_spawner: Spawner) -> ! { 17async fn main(_spawner: Spawner) {
17 let mut config = Config::default(); 18 let mut config = Config::default();
18 { 19 {
19 use embassy_stm32::rcc::*; 20 use embassy_stm32::rcc::*;
@@ -53,11 +54,13 @@ async fn main(_spawner: Spawner) -> ! {
53 // Should print 400kHz for initialization 54 // Should print 400kHz for initialization
54 info!("Configured clock: {}", sdmmc.clock().0); 55 info!("Configured clock: {}", sdmmc.clock().0);
55 56
56 unwrap!(sdmmc.init_sd_card(mhz(25)).await); 57 let mut cmd_block = CmdBlock::new();
57 58
58 let card = unwrap!(sdmmc.card()); 59 let storage = StorageDevice::new_sd_card(&mut sdmmc, &mut cmd_block, mhz(25))
60 .await
61 .unwrap();
59 62
60 info!("Card: {:#?}", Debug2Format(card)); 63 let card = storage.card();
61 64
62 loop {} 65 info!("Card: {:#?}", Debug2Format(&card));
63} 66}
diff --git a/examples/stm32n6/Cargo.toml b/examples/stm32n6/Cargo.toml
index 5ed28eed1..5ad5b97ce 100644
--- a/examples/stm32n6/Cargo.toml
+++ b/examples/stm32n6/Cargo.toml
@@ -32,6 +32,8 @@ micromath = "2.0.0"
32stm32-fmc = "0.3.0" 32stm32-fmc = "0.3.0"
33embedded-storage = "0.3.1" 33embedded-storage = "0.3.1"
34static_cell = "2" 34static_cell = "2"
35hmac = "0.12.1"
36sha2 = { version = "0.10.9", default-features = false }
35 37
36 38
37# cargo build/run 39# cargo build/run
diff --git a/examples/stm32n6/src/bin/crc.rs b/examples/stm32n6/src/bin/crc.rs
new file mode 100644
index 000000000..d1b545d5b
--- /dev/null
+++ b/examples/stm32n6/src/bin/crc.rs
@@ -0,0 +1,31 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::crc::{Config, Crc, InputReverseConfig, PolySize};
7use {defmt_rtt as _, panic_probe as _};
8
9#[embassy_executor::main]
10async fn main(_spawner: Spawner) {
11 let p = embassy_stm32::init(Default::default());
12 info!("Hello World!");
13
14 // Setup for: https://crccalc.com/?crc=Life, it never dieWomen are my favorite guy&method=crc32&datatype=ascii&outtype=0
15 let mut crc = Crc::new(
16 p.CRC,
17 unwrap!(Config::new(
18 InputReverseConfig::Byte,
19 true,
20 PolySize::Width32,
21 0xFFFFFFFF,
22 0x04C11DB7
23 )),
24 );
25
26 let output = crc.feed_bytes(b"Life, it never die\nWomen are my favorite guy") ^ 0xFFFFFFFF;
27
28 defmt::assert_eq!(output, 0x33F0E26B);
29
30 cortex_m::asm::bkpt();
31}
diff --git a/examples/stm32n6/src/bin/hash.rs b/examples/stm32n6/src/bin/hash.rs
new file mode 100644
index 000000000..9f248318f
--- /dev/null
+++ b/examples/stm32n6/src/bin/hash.rs
@@ -0,0 +1,78 @@
1#![no_std]
2#![no_main]
3
4use defmt::info;
5use embassy_executor::Spawner;
6use embassy_stm32::hash::*;
7use embassy_stm32::{Config, bind_interrupts, hash, peripherals};
8use embassy_time::Instant;
9use hmac::{Hmac, Mac};
10use sha2::{Digest, Sha256};
11use {defmt_rtt as _, panic_probe as _};
12
13type HmacSha256 = Hmac<Sha256>;
14
15bind_interrupts!(struct Irqs {
16 HASH => hash::InterruptHandler<peripherals::HASH>;
17});
18
19#[embassy_executor::main]
20async fn main(_spawner: Spawner) -> ! {
21 let config = Config::default();
22 let p = embassy_stm32::init(config);
23
24 let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh";
25 let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr";
26
27 let mut hw_hasher = Hash::new_blocking(p.HASH, Irqs);
28
29 let hw_start_time = Instant::now();
30
31 // Compute a digest in hardware.
32 let mut context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, None);
33 hw_hasher.update_blocking(&mut context, test_1);
34 hw_hasher.update_blocking(&mut context, test_2);
35 let mut hw_digest: [u8; 32] = [0; 32];
36 hw_hasher.finish_blocking(context, &mut hw_digest);
37
38 let hw_end_time = Instant::now();
39 let hw_execution_time = hw_end_time - hw_start_time;
40
41 let sw_start_time = Instant::now();
42
43 // Compute a digest in software.
44 let mut sw_hasher = Sha256::new();
45 sw_hasher.update(test_1);
46 sw_hasher.update(test_2);
47 let sw_digest = sw_hasher.finalize();
48
49 let sw_end_time = Instant::now();
50 let sw_execution_time = sw_end_time - sw_start_time;
51
52 info!("Hardware Digest: {:?}", hw_digest);
53 info!("Software Digest: {:?}", sw_digest[..]);
54 info!("Hardware Execution Time: {:?}", hw_execution_time);
55 info!("Software Execution Time: {:?}", sw_execution_time);
56 assert_eq!(hw_digest, sw_digest[..]);
57
58 let hmac_key: [u8; 64] = [0x55; 64];
59
60 // Compute HMAC in hardware.
61 let mut sha256hmac_context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, Some(&hmac_key));
62 hw_hasher.update_blocking(&mut sha256hmac_context, test_1);
63 hw_hasher.update_blocking(&mut sha256hmac_context, test_2);
64 let mut hw_hmac: [u8; 32] = [0; 32];
65 hw_hasher.finish_blocking(sha256hmac_context, &mut hw_hmac);
66
67 // Compute HMAC in software.
68 let mut sw_mac = HmacSha256::new_from_slice(&hmac_key).unwrap();
69 sw_mac.update(test_1);
70 sw_mac.update(test_2);
71 let sw_hmac = sw_mac.finalize().into_bytes();
72
73 info!("Hardware HMAC: {:?}", hw_hmac);
74 info!("Software HMAC: {:?}", sw_hmac[..]);
75 assert_eq!(hw_hmac, sw_hmac[..]);
76
77 loop {}
78}
diff --git a/examples/stm32wba/src/bin/rtc.rs b/examples/stm32wba/src/bin/rtc.rs
new file mode 100644
index 000000000..cef8501e0
--- /dev/null
+++ b/examples/stm32wba/src/bin/rtc.rs
@@ -0,0 +1,62 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::Config;
7use embassy_stm32::rcc::*;
8use embassy_stm32::rtc::{DateTime, DayOfWeek, Rtc, RtcConfig};
9use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _};
11
12pub fn pll_init(config: &mut Config) {
13 config.rcc.pll1 = Some(embassy_stm32::rcc::Pll {
14 source: PllSource::HSI,
15 prediv: PllPreDiv::DIV1, // PLLM = 1 → HSI / 1 = 16 MHz
16 mul: PllMul::MUL30, // PLLN = 30 → 16 MHz * 30 = 480 MHz VCO
17 divr: Some(PllDiv::DIV5), // PLLR = 5 → 96 MHz (Sysclk)
18 // divq: Some(PllDiv::DIV10), // PLLQ = 10 → 48 MHz (NOT USED)
19 divq: None,
20 divp: Some(PllDiv::DIV30), // PLLP = 30 → 16 MHz (USBOTG)
21 frac: Some(0), // Fractional part (enabled)
22 });
23
24 config.rcc.ahb_pre = AHBPrescaler::DIV1;
25 config.rcc.apb1_pre = APBPrescaler::DIV1;
26 config.rcc.apb2_pre = APBPrescaler::DIV1;
27 config.rcc.apb7_pre = APBPrescaler::DIV1;
28 config.rcc.ahb5_pre = AHB5Prescaler::DIV4;
29
30 // voltage scale for max performance
31 config.rcc.voltage_scale = VoltageScale::RANGE1;
32 // route PLL1_P into the USB‐OTG‐HS block
33 config.rcc.sys = Sysclk::PLL1_R;
34}
35
36#[embassy_executor::main]
37async fn main(_spawner: Spawner) {
38 let mut config = Config::default();
39
40 pll_init(&mut config);
41
42 let p = embassy_stm32::init(config);
43
44 let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
45
46 // Setting datetime
47 let initial_datetime = DateTime::from(1970, 1, 1, DayOfWeek::Thursday, 0, 00, 00, 0).unwrap();
48 match rtc.0.set_datetime(initial_datetime) {
49 Ok(()) => info!("RTC set successfully."),
50 Err(e) => error!("Failed to set RTC date/time: {:?}", e),
51 }
52
53 // Reading datetime every 1s
54 loop {
55 match rtc.1.now() {
56 Ok(result) => info!("{}", result),
57 Err(e) => error!("Failed to set RTC date/time: {:?}", e),
58 }
59
60 Timer::after_millis(1000).await;
61 }
62}
diff --git a/examples/stm32wba6/src/bin/rtc.rs b/examples/stm32wba6/src/bin/rtc.rs
new file mode 100644
index 000000000..cef8501e0
--- /dev/null
+++ b/examples/stm32wba6/src/bin/rtc.rs
@@ -0,0 +1,62 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::Config;
7use embassy_stm32::rcc::*;
8use embassy_stm32::rtc::{DateTime, DayOfWeek, Rtc, RtcConfig};
9use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _};
11
12pub fn pll_init(config: &mut Config) {
13 config.rcc.pll1 = Some(embassy_stm32::rcc::Pll {
14 source: PllSource::HSI,
15 prediv: PllPreDiv::DIV1, // PLLM = 1 → HSI / 1 = 16 MHz
16 mul: PllMul::MUL30, // PLLN = 30 → 16 MHz * 30 = 480 MHz VCO
17 divr: Some(PllDiv::DIV5), // PLLR = 5 → 96 MHz (Sysclk)
18 // divq: Some(PllDiv::DIV10), // PLLQ = 10 → 48 MHz (NOT USED)
19 divq: None,
20 divp: Some(PllDiv::DIV30), // PLLP = 30 → 16 MHz (USBOTG)
21 frac: Some(0), // Fractional part (enabled)
22 });
23
24 config.rcc.ahb_pre = AHBPrescaler::DIV1;
25 config.rcc.apb1_pre = APBPrescaler::DIV1;
26 config.rcc.apb2_pre = APBPrescaler::DIV1;
27 config.rcc.apb7_pre = APBPrescaler::DIV1;
28 config.rcc.ahb5_pre = AHB5Prescaler::DIV4;
29
30 // voltage scale for max performance
31 config.rcc.voltage_scale = VoltageScale::RANGE1;
32 // route PLL1_P into the USB‐OTG‐HS block
33 config.rcc.sys = Sysclk::PLL1_R;
34}
35
36#[embassy_executor::main]
37async fn main(_spawner: Spawner) {
38 let mut config = Config::default();
39
40 pll_init(&mut config);
41
42 let p = embassy_stm32::init(config);
43
44 let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
45
46 // Setting datetime
47 let initial_datetime = DateTime::from(1970, 1, 1, DayOfWeek::Thursday, 0, 00, 00, 0).unwrap();
48 match rtc.0.set_datetime(initial_datetime) {
49 Ok(()) => info!("RTC set successfully."),
50 Err(e) => error!("Failed to set RTC date/time: {:?}", e),
51 }
52
53 // Reading datetime every 1s
54 loop {
55 match rtc.1.now() {
56 Ok(result) => info!("{}", result),
57 Err(e) => error!("Failed to set RTC date/time: {:?}", e),
58 }
59
60 Timer::after_millis(1000).await;
61 }
62}