2 Commits

Author SHA1 Message Date
Filipriec
621de5f37c examples builded 2025-10-20 18:06:32 +02:00
Filipriec
bab60914b0 cleared rust repo for stm32 2025-10-20 17:45:49 +02:00
30 changed files with 173 additions and 305 deletions

View File

@@ -0,0 +1,22 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = ["probe-rs", "run", "--chip", "STM32U575ZI", "--log-format=oneline"]
rustflags = [
"-C", "linker=flip-link",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
"-C", "link-arg=--nmagic",
]
[build]
target = "thumbv8m.main-none-eabihf"
[target.thumbv8m.main-none-eabihf]
runner = "probe-rs run --chip STM32U575ZI"
[alias]
rb = "run --bin"
rrb = "run --release --bin"
[env]
DEFMT_LOG = "info"

View File

@@ -1,34 +1,22 @@
[package]
# TODO(1) fix `authors` and `name` if you didn't use `cargo-generate`
authors = ["Priec <filippriec@gmail.com>"]
name = "stm32u5-tim2"
name = "stm32u5-blinky"
edition = "2024"
version = "0.1.0"
[[bin]]
name = "main"
path = "src/bin/main.rs"
test = false
[lib]
harness = false
# needed for each integration test
[[test]]
name = "integration"
harness = false
[dependencies]
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
defmt = "1.0"
defmt-rtt = "1.0"
panic-halt = "1.0.0"
panic-probe = { version = "1.0", features = ["print-defmt"] }
embassy-stm32 = { version = "0.4.0", features = ["stm32u575zi", "time-driver-tim1", "defmt", "low-power", "memory-x"] }
embassy-time = "0.5.0"
semihosting = "0.1.20"
stm32u5 = { version = "0.16.0", features = ["rt", "stm32u575"] }
# TODO(4) enter your HAL here
# some-hal = "1.2.3"
embedded-hal = "1.0.0"
embassy-executor = { version = "0.9.1", features = ["arch-cortex-m", "executor-thread"] }
[dev-dependencies]
defmt-test = "0.3"

93
hal_adc/src/bin/main.rs Normal file
View File

@@ -0,0 +1,93 @@
// src/bin/main.rs
#![no_std]
#![no_main]
use defmt::*;
use embassy_stm32::adc;
use embassy_stm32::adc::{AdcChannel, adc4};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(_spawner: embassy_executor::Spawner) {
let config = embassy_stm32::Config::default();
let mut p = embassy_stm32::init(config);
// **** ADC1 init ****
let mut adc1 = adc::Adc::new(p.ADC1);
let mut adc1_pin1 = p.PA3; // A0 on nucleo u5a5
let mut adc1_pin2 = p.PA2; // A1
adc1.set_resolution(adc::Resolution::BITS14);
adc1.set_averaging(adc::Averaging::Samples1024);
adc1.set_sample_time(adc::SampleTime::CYCLES160_5);
let max1 = adc::resolution_to_max_count(adc::Resolution::BITS14);
// **** ADC4 init ****
let mut adc4 = adc4::Adc4::new(p.ADC4);
let mut adc4_pin1 = p.PC1; // A4
let mut adc4_pin2 = p.PC0; // A5
adc4.set_resolution(adc4::Resolution::BITS12);
adc4.set_averaging(adc4::Averaging::Samples256);
adc4.set_sample_time(adc4::SampleTime::CYCLES1_5);
let max4 = adc4::resolution_to_max_count(adc4::Resolution::BITS12);
// **** ADC1 blocking read ****
let raw: u16 = adc1.blocking_read(&mut adc1_pin1);
let volt: f32 = 3.3 * raw as f32 / max1 as f32;
info!("Read adc1 pin 1 {}", volt);
let raw: u16 = adc1.blocking_read(&mut adc1_pin2);
let volt: f32 = 3.3 * raw as f32 / max1 as f32;
info!("Read adc1 pin 2 {}", volt);
// **** ADC4 blocking read ****
let raw: u16 = adc4.blocking_read(&mut adc4_pin1);
let volt: f32 = 3.3 * raw as f32 / max4 as f32;
info!("Read adc4 pin 1 {}", volt);
let raw: u16 = adc4.blocking_read(&mut adc4_pin2);
let volt: f32 = 3.3 * raw as f32 / max4 as f32;
info!("Read adc4 pin 2 {}", volt);
// **** ADC1 async read ****
let mut degraded11 = adc1_pin1.degrade_adc();
let mut degraded12 = adc1_pin2.degrade_adc();
let mut measurements = [0u16; 2];
adc1.read(
p.GPDMA1_CH0.reborrow(),
[
(&mut degraded11, adc::SampleTime::CYCLES160_5),
(&mut degraded12, adc::SampleTime::CYCLES160_5),
]
.into_iter(),
&mut measurements,
)
.await;
let volt1: f32 = 3.3 * measurements[0] as f32 / max1 as f32;
let volt2: f32 = 3.3 * measurements[1] as f32 / max1 as f32;
info!("Async read 1 pin 1 {}", volt1);
info!("Async read 1 pin 2 {}", volt2);
// **** ADC2 does not support async read ****
// **** ADC4 async read ****
let mut degraded41 = adc4_pin1.degrade_adc();
let mut degraded42 = adc4_pin2.degrade_adc();
let mut measurements = [0u16; 2];
// The channels must be in ascending order and can't repeat for ADC4
adc4.read(
p.GPDMA1_CH1.reborrow(),
[&mut degraded42, &mut degraded41].into_iter(),
&mut measurements,
)
.await
.unwrap();
let volt2: f32 = 3.3 * measurements[0] as f32 / max4 as f32;
let volt1: f32 = 3.3 * measurements[1] as f32 / max4 as f32;
info!("Async read 4 pin 1 {}", volt1);
info!("Async read 4 pin 2 {}", volt2);
}

View File

@@ -0,0 +1,22 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = ["probe-rs", "run", "--chip", "STM32U575ZI", "--log-format=oneline"]
rustflags = [
"-C", "linker=flip-link",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
"-C", "link-arg=--nmagic",
]
[build]
target = "thumbv8m.main-none-eabihf"
[target.thumbv8m.main-none-eabihf]
runner = "probe-rs run --chip STM32U575ZI"
[alias]
rb = "run --bin"
rrb = "run --release --bin"
[env]
DEFMT_LOG = "info"

View File

@@ -6,59 +6,17 @@ edition = "2024"
version = "0.1.0"
# To run all the tests via `cargo test` the tests need to be explicitly disabled for the binary targets
# If you use a standard main.rs file the following is sufficient:
# [[bin]]
# name = "stm32u5-blinky"
# test = false
[[bin]]
name = "bitfield"
path = "src/bin/bitfield.rs"
test = false
[[bin]]
name = "format"
path = "src/bin/format.rs"
test = false
[[bin]]
name = "hello"
path = "src/bin/hello.rs"
test = false
[[bin]]
name = "levels"
path = "src/bin/levels.rs"
test = false
[[bin]]
name = "overflow"
path = "src/bin/overflow.rs"
test = false
[[bin]]
name = "panic"
path = "src/bin/panic.rs"
test = false
[lib]
harness = false
# needed for each integration test
[[test]]
name = "integration"
harness = false
[dependencies]
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
defmt = "1.0"
defmt-rtt = "1.0"
panic-probe = { version = "1.0", features = ["print-defmt"] }
embassy-stm32 = { version = "0.4.0", features = ["stm32u575zi", "time-driver-tim1", "defmt", "low-power", "memory-x"] }
embassy-time = "0.5.0"
semihosting = "0.1.20"
# TODO(4) enter your HAL here
# some-hal = "1.2.3"
embedded-hal = "1.0.0"
embassy-executor = { version = "0.9.1", features = ["arch-cortex-m", "executor-thread"] }
[dev-dependencies]
defmt-test = "0.3"

27
hal_rng/src/bin/main.rs Normal file
View File

@@ -0,0 +1,27 @@
// src/bin/main.rs
#![no_std]
#![no_main]
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::rng::Rng;
use embassy_stm32::{bind_interrupts, peripherals, rng};
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
RNG => rng::InterruptHandler<peripherals::RNG>;
});
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default());
info!("Hello World!");
let mut rng = Rng::new(p.RNG, Irqs);
let mut buf = [0u8; 16];
unwrap!(rng.async_fill_bytes(&mut buf).await);
info!("random bytes: {:02x}", buf);
}

View File

@@ -1,27 +0,0 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# TODO(2) replace `$CHIP` with your chip's name (see `probe-rs chip list` output)
runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format=oneline"]
# If you have an nRF52, you might also want to add "--allow-erase-all" to the list
rustflags = [
"-C", "linker=flip-link",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
"-C", "link-arg=--nmagic",
]
[build]
# TODO(3) Adjust the compilation target.
# Select the correct target for your processor:
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
# target = "thumbv7m-none-eabi" # Cortex-M3
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
[alias]
# `cargo rb foo` will expand to `cargo run --bin foo`
rb = "run --bin"
# `cargo rrb foo` will expand to `cargo run --release --bin foo`
rrb = "run --release --bin"

View File

@@ -1,9 +0,0 @@
{
// override the default setting (`cargo check --all-targets`) which produces the following error
// "can't find crate for `test`" when the default compilation target is a no_std target
// with these changes RA will call `cargo check --bins` on save
"rust-analyzer.check.allTargets": false,
"rust-analyzer.check.extraArgs": [
"--bins"
]
}

View File

@@ -1,13 +0,0 @@
#![no_main]
#![no_std]
use stm32u5_blinky as _; // global logger + panicking-behavior + memory layout
#[cortex_m_rt::entry]
fn main() -> ! {
// value of the FREQUENCY register (nRF52840 device; RADIO peripheral)
let frequency: u32 = 276;
defmt::println!("FREQUENCY: {0=0..7}, MAP: {0=8..9}", frequency);
stm32u5_blinky::exit()
}

View File

@@ -1,29 +0,0 @@
#![no_main]
#![no_std]
use stm32u5_blinky as _; // global logger + panicking-behavior + memory layout
use defmt::Format; // <- derive attribute
#[derive(Format)]
struct S1<T> {
x: u8,
y: T,
}
#[derive(Format)]
struct S2 {
z: u8,
}
#[cortex_m_rt::entry]
fn main() -> ! {
let s = S1 {
x: 42,
y: S2 { z: 43 },
};
defmt::println!("s={:?}", s);
let x = 42;
defmt::println!("x={=u8}", x);
stm32u5_blinky::exit()
}

View File

@@ -1,11 +0,0 @@
#![no_main]
#![no_std]
use stm32u5_blinky as _; // global logger + panicking-behavior + memory layout
#[cortex_m_rt::entry]
fn main() -> ! {
defmt::println!("Hello, world!");
stm32u5_blinky::exit()
}

View File

@@ -1,17 +0,0 @@
#![no_main]
#![no_std]
use stm32u5_blinky as _; // global logger + panicking-behavior + memory layout
#[cortex_m_rt::entry]
fn main() -> ! {
// try setting the DEFMT_LOG environment variable
// e.g. `export DEFMT_LOG=info` or `DEFMT_LOG=trace cargo rb levels`
defmt::info!("info");
defmt::trace!("trace");
defmt::warn!("warn");
defmt::debug!("debug");
defmt::error!("error");
stm32u5_blinky::exit()
}

View File

@@ -1,28 +0,0 @@
#![no_main]
#![no_std]
use stm32u5_blinky as _; // global logger + panicking-behavior + memory layout
#[cortex_m_rt::entry]
fn main() -> ! {
ack(10, 10);
stm32u5_blinky::exit()
}
fn ack(m: u32, n: u32) -> u32 {
// waste stack space to trigger a stack overflow
let mut buffer = [0u8; 16 * 1024];
// estimate of the Stack Pointer register
let sp = buffer.as_mut_ptr();
defmt::println!("ack(m={=u32}, n={=u32}, SP={:x})", m, n, sp);
if m == 0 {
n + 1
} else {
if n == 0 {
ack(m - 1, 1)
} else {
ack(m - 1, ack(m, n - 1))
}
}
}

View File

@@ -1,11 +0,0 @@
#![no_main]
#![no_std]
use stm32u5_blinky as _; // global logger + panicking-behavior + memory layout
#[cortex_m_rt::entry]
fn main() -> ! {
defmt::println!("main");
defmt::panic!()
}

View File

@@ -1,27 +0,0 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# TODO(2) replace `$CHIP` with your chip's name (see `probe-rs chip list` output)
runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format=oneline"]
# If you have an nRF52, you might also want to add "--allow-erase-all" to the list
rustflags = [
"-C", "linker=flip-link",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
"-C", "link-arg=--nmagic",
]
[build]
# TODO(3) Adjust the compilation target.
# Select the correct target for your processor:
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
# target = "thumbv7m-none-eabi" # Cortex-M3
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
[alias]
# `cargo rb foo` will expand to `cargo run --bin foo`
rb = "run --bin"
# `cargo rrb foo` will expand to `cargo run --release --bin foo`
rrb = "run --release --bin"

View File

@@ -1,70 +0,0 @@
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use panic_halt as _;
use stm32u5::stm32u575 as pac;
use pac::interrupt; // Import the interrupt enum
// Timer frequency constants
const PRESCALER: u16 = 0;
const PULSE1_VALUE: u32 = 50000; // For 800 Hz toggle
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
dp.RCC.apb1enr1().modify(|_, w| w.tim2en().set_bit());
// Enable GPIOA clock for TIM2_CH4 (PA3)
dp.RCC.ahb2enr1().modify(|_, w| w.gpioaen().set_bit());
// Configure PA3 as AF1 (TIM2_CH4)
dp.GPIOA.moder().modify(|_, w| w.mode3().alternate());
dp.GPIOA.afrl().modify(|_, w| w.afrel3().af1());
// Configure TIM2
dp.TIM2.psc().write(|w| unsafe { w.bits(PRESCALER as u32) });
dp.TIM2.arr().write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // Max for 32-bit timer
// Configure CH4 for output compare toggle mode
dp.TIM2.ccmr2_output().modify(|_, w| unsafe {
w.cc4s().bits(0b00) // CH4 as output
.oc4m().bits(0b011) // Toggle mode
});
// Set initial compare value
dp.TIM2.ccr4().write(|w| unsafe { w.bits(PULSE1_VALUE) });
// Enable CH4 output
dp.TIM2.ccer().modify(|_, w| w.cc4e().set_bit());
// Enable CH4 interrupt
dp.TIM2.dier().modify(|_, w| w.cc4ie().set_bit());
// Enable TIM2 interrupt in NVIC
unsafe {
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::TIM2);
}
// Start timer
dp.TIM2.cr1().modify(|_, w| w.cen().set_bit());
loop {
cortex_m::asm::wfi(); // Wait for interrupt
}
}
#[interrupt]
fn TIM2() {
unsafe {
let tim2 = &(*pac::TIM2::ptr());
if tim2.sr().read().cc4if().bit_is_set() {
tim2.sr().modify(|_, w| w.cc4if().clear_bit());
// Use wrapping arithmetic
let current = tim2.ccr4().read().bits();
let next = current.wrapping_add(PULSE1_VALUE);
tim2.ccr4().write(|w| w.bits(next));
}
}
}