Rotating blinky

This commit is contained in:
2025-10-19 18:59:32 +02:00
parent 53c97dcb32
commit 9a76ebdbeb
2 changed files with 139 additions and 18 deletions

View File

@@ -13,6 +13,7 @@ panic-halt = "1.0.0"
panic-semihosting = "0.6" panic-semihosting = "0.6"
stm32f3 = { version = "0.16.0", features = ["stm32f303"] } stm32f3 = { version = "0.16.0", features = ["stm32f303"] }
stm32f3xx-hal = { version = "0.10.0", features = ["stm32f303xc"] } stm32f3xx-hal = { version = "0.10.0", features = ["stm32f303xc"] }
switch-hal = "0.4.0"
# Uncomment for the panic example. # Uncomment for the panic example.
# panic-itm = "0.4.1" # panic-itm = "0.4.1"

View File

@@ -2,6 +2,7 @@
#![no_main] #![no_main]
use core::fmt::Write; use core::fmt::Write;
use core::slice::Iter;
use cortex_m_semihosting::hprintln; use cortex_m_semihosting::hprintln;
// pick a panicking behavior // pick a panicking behavior
@@ -13,8 +14,120 @@ use panic_semihosting as _; // logs messages to the host stderr; requires a debu
use cortex_m::peripheral::{syst, Peripherals}; use cortex_m::peripheral::{syst, Peripherals};
use cortex_m_rt::entry; use cortex_m_rt::entry;
use stm32f3xx_hal::delay;
use stm32f3xx_hal::serial::Serial; use stm32f3xx_hal::serial::Serial;
use stm32f3xx_hal::{self as hal, pac, prelude::*}; use stm32f3xx_hal::{
gpio::{self, gpioe},
pac,
prelude::*,
};
use switch_hal::{ActiveHigh, IntoSwitch, OutputSwitch, Switch};
enum Direction {
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest,
}
impl Direction {
pub fn iter() -> Iter<'static, Direction> {
static DIRECTIONS: [Direction; 8] = [
Direction::North,
Direction::NorthEast,
Direction::East,
Direction::SouthEast,
Direction::South,
Direction::SouthWest,
Direction::West,
Direction::NorthWest,
];
DIRECTIONS.iter()
}
}
type Led = Switch<gpioe::PEx<gpio::Output<gpio::PushPull>>, ActiveHigh>;
struct Leds {
ld3: Led,
ld4: Led,
ld5: Led,
ld6: Led,
ld7: Led,
ld8: Led,
ld9: Led,
ld10: Led,
}
impl Leds {
fn new<PE8Mode, PE9Mode, PE10Mode, PE11Mode, PE12Mode, PE13Mode, PE14Mode, PE15Mode>(
pe8: gpioe::PE8<PE8Mode>,
pe9: gpioe::PE9<PE9Mode>,
pe10: gpioe::PE10<PE10Mode>,
pe11: gpioe::PE11<PE11Mode>,
pe12: gpioe::PE12<PE12Mode>,
pe13: gpioe::PE13<PE13Mode>,
pe14: gpioe::PE14<PE14Mode>,
pe15: gpioe::PE15<PE15Mode>,
moder: &mut gpioe::MODER,
otyper: &mut gpioe::OTYPER,
) -> Self {
let mut leds = Self {
ld3: pe9
.into_push_pull_output(moder, otyper)
.downgrade()
.into_active_high_switch(),
ld4: pe8
.into_push_pull_output(moder, otyper)
.downgrade()
.into_active_high_switch(),
ld5: pe10
.into_push_pull_output(moder, otyper)
.downgrade()
.into_active_high_switch(),
ld6: pe15
.into_push_pull_output(moder, otyper)
.downgrade()
.into_active_high_switch(),
ld7: pe11
.into_push_pull_output(moder, otyper)
.downgrade()
.into_active_high_switch(),
ld8: pe14
.into_push_pull_output(moder, otyper)
.downgrade()
.into_active_high_switch(),
ld9: pe12
.into_push_pull_output(moder, otyper)
.downgrade()
.into_active_high_switch(),
ld10: pe13
.into_push_pull_output(moder, otyper)
.downgrade()
.into_active_high_switch(),
};
for dir in Direction::iter() {
leds.for_direction(dir).off().ok();
}
leds
}
pub fn for_direction(&mut self, direction: &Direction) -> &mut Led {
match direction {
Direction::North => &mut self.ld3,
Direction::NorthEast => &mut self.ld5,
Direction::East => &mut self.ld7,
Direction::SouthEast => &mut self.ld9,
Direction::South => &mut self.ld10,
Direction::SouthWest => &mut self.ld8,
Direction::West => &mut self.ld6,
Direction::NorthWest => &mut self.ld4,
}
}
}
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
@@ -32,19 +145,19 @@ fn main() -> ! {
systick.set_reload(8_000_000); // 1s systick.set_reload(8_000_000); // 1s
systick.clear_current(); systick.clear_current();
// PE9: LD3 (red)
// PE8: LD4 (blue)
// PE10: LD5 (orange)
let mut gpioe = dp.GPIOE.split(&mut rcc.ahb); let mut gpioe = dp.GPIOE.split(&mut rcc.ahb);
let mut ld3 = gpioe let mut leds = Leds::new(
.pe9 gpioe.pe8,
.into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper); gpioe.pe9,
let mut ld4 = gpioe gpioe.pe10,
.pe8 gpioe.pe11,
.into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper); gpioe.pe12,
let mut ld5 = gpioe gpioe.pe13,
.pe10 gpioe.pe14,
.into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper); gpioe.pe15,
&mut gpioe.moder,
&mut gpioe.otyper,
);
let mut gpioc = dp.GPIOC.split(&mut rcc.ahb); let mut gpioc = dp.GPIOC.split(&mut rcc.ahb);
let pins = ( let pins = (
@@ -59,14 +172,21 @@ fn main() -> ! {
); );
let mut uart = Serial::new(dp.USART1, pins, 115200.Bd(), clocks, &mut rcc.apb2); let mut uart = Serial::new(dp.USART1, pins, 115200.Bd(), clocks, &mut rcc.apb2);
systick.enable_counter();
let mut delay = delay::Delay::new(systick, clocks);
let mut enabled = true; let mut enabled = true;
loop { loop {
while !systick.has_wrapped() {}
enabled = !enabled; enabled = !enabled;
ld3.toggle().unwrap(); for dir in Direction::iter() {
ld4.toggle().unwrap(); let led = leds.for_direction(dir);
ld5.toggle().unwrap(); if enabled {
led.on().ok();
} else {
led.off().ok();
}
delay.delay_ms(50u16);
}
uart.write_str("Loop\r\n").unwrap(); uart.write_str("Loop\r\n").unwrap();
hprintln!("Loop"); hprintln!("Loop");
} }