@@ 36,15 36,17 @@ use embedded_alloc::Heap;
use embedded_hal::digital::v2::OutputPin;
use fugit::MicrosDurationU32;
use stm32f1xx_hal::{
+ gpio::{Cr, Floating, Input, Pin},
pac,
pac::interrupt,
prelude::*,
+ rcc::Clocks,
rtc::{
RestoredOrNewRtc::{New, Restored},
Rtc,
},
time::MonoTimer,
- timer::{Event, Tim1NoRemap, Tim2NoRemap, Tim3NoRemap, TimerExt},
+ timer::{Event, Tim1NoRemap, Tim2NoRemap, Tim3NoRemap, TimerExt, SysDelay}, afio::MAPR,
};
use defmt_rtt as _;
@@ 74,94 76,67 @@ fn TIM4() {
});
}
-#[entry]
-fn main() -> ! {
- {
- use core::mem::MaybeUninit;
- const HEAP_SIZE: usize = 512;
- static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
- unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
- }
-
- // Get access to the core peripherals from the cortex-m crate
- let cp = cortex_m::Peripherals::take().unwrap();
- // Get access to the device specific peripherals from the peripheral access crate
- let dp = pac::Peripherals::take().unwrap();
-
- // Take ownership over the raw flash and rcc devices and convert them into the corresponding
- // HAL structs
- let mut pwr = dp.PWR;
- let mut flash = dp.FLASH.constrain();
- let rcc = dp.RCC.constrain();
- let mut backup_domain = rcc.bkp.constrain(dp.BKP, &mut pwr);
-
- // Freeze the configuration of all the clocks in the system and store the frozen frequencies in
- // `clocks`
- let clocks = rcc
- .cfgr
- .use_hse(8.MHz())
- .sysclk(24.MHz())
- .pclk1(24.MHz())
- .pclk2(24.MHz())
- .freeze(&mut flash.acr);
-
- let mut gpiob = dp.GPIOB.split();
- let mut gpioa = dp.GPIOA.split();
- let mut gpioc = dp.GPIOC.split();
- let mut afio = dp.AFIO.constrain();
-
- let (_, pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4);
-
- let mut led1 = gpiob.pb12.into_open_drain_output(&mut gpiob.crh);
- let mut led2 = gpiob.pb11.into_open_drain_output(&mut gpiob.crh);
- let mut led3 = gpiob.pb1.into_open_drain_output(&mut gpiob.crl);
- let mut led4 = gpiob.pb0.into_open_drain_output(&mut gpiob.crl);
-
- let leds: [&mut dyn OutputPin<Error = Infallible>; 4] =
- [&mut led1, &mut led2, &mut led3, &mut led4];
-
- let btn1 = Button::<ActiveHigh>::new(Box::new(gpiob.pb15.into_pull_down_input(&mut gpiob.crh)));
- let btn2 = Button::<ActiveHigh>::new(Box::new(gpiob.pb14.into_pull_down_input(&mut gpiob.crh)));
- let btn3 = Button::<ActiveHigh>::new(Box::new(gpiob.pb13.into_pull_down_input(&mut gpiob.crh)));
- let btn4 = Button::<ActiveHigh>::new(Box::new(gpioc.pc13.into_pull_down_input(&mut gpioc.crh)));
-
- let mut btns: [Button<ActiveHigh>; 4] = [btn1, btn2, btn3, btn4];
-
- let a = gpiob.pb10.into_open_drain_output(&mut gpiob.crh);
- let b = gpiob.pb2.into_open_drain_output(&mut gpiob.crl);
- let c = gpiob.pb8.into_open_drain_output(&mut gpiob.crh);
- let d = gpiob.pb6.into_open_drain_output(&mut gpiob.crl);
- let e = gpiob.pb9.into_open_drain_output(&mut gpiob.crh);
- let f = pb3.into_open_drain_output(&mut gpiob.crl);
- let g = pb4.into_open_drain_output(&mut gpiob.crl);
- let dpp = gpiob.pb7.into_open_drain_output(&mut gpiob.crl);
-
- let dig1 = gpioa.pa6.into_alternate_open_drain(&mut gpioa.crl);
- let dig2 = gpioa.pa3.into_alternate_open_drain(&mut gpioa.crl);
- let dig3 = gpioa.pa7.into_alternate_open_drain(&mut gpioa.crl);
- let dig4 = gpioa.pa8.into_alternate_open_drain(&mut gpioa.crh);
- let dig5 = gpioa.pa9.into_alternate_open_drain(&mut gpioa.crh);
- let dig6 = gpioa.pa2.into_alternate_open_drain(&mut gpioa.crl);
- let dig7 = gpioa.pa10.into_alternate_open_drain(&mut gpioa.crh);
- let dig8 = gpioa.pa1.into_alternate_open_drain(&mut gpioa.crl);
+/// Puts given pins into open drain,
+/// then makes PWM out of digit pins,
+/// lastly, timer 4 is constructed for refreshing the display,
+/// and ClockDisplayViewer is created.
+fn init_segment_display(
+ pb10: Pin<'B', 10, Input<Floating>>,
+ pb2: Pin<'B', 2, Input<Floating>>,
+ pb8: Pin<'B', 8, Input<Floating>>,
+ pb6: Pin<'B', 6, Input<Floating>>,
+ pb9: Pin<'B', 9, Input<Floating>>,
+ pb3: Pin<'B', 3, Input<Floating>>,
+ pb4: Pin<'B', 4, Input<Floating>>,
+ pb7: Pin<'B', 7, Input<Floating>>,
+ pa6: Pin<'A', 6, Input<Floating>>,
+ pa3: Pin<'A', 3, Input<Floating>>,
+ pa7: Pin<'A', 7, Input<Floating>>,
+ pa8: Pin<'A', 8, Input<Floating>>,
+ pa9: Pin<'A', 9, Input<Floating>>,
+ pa2: Pin<'A', 2, Input<Floating>>,
+ pa10: Pin<'A', 10, Input<Floating>>,
+ pa1: Pin<'A', 1, Input<Floating>>,
+ tim1: pac::TIM1,
+ tim2: pac::TIM2,
+ tim3: pac::TIM3,
+ tim4: pac::TIM4,
+ gpioa_crl: &mut Cr<'A', false>,
+ gpioa_crh: &mut Cr<'A', true>,
+ gpiob_crl: &mut Cr<'B', false>,
+ gpiob_crh: &mut Cr<'B', true>,
+ afio_mapr: &mut MAPR,
+ clocks: &Clocks,
+) -> ClockDisplayViewer {
+ let a = pb10.into_open_drain_output(gpiob_crh);
+ let b = pb2.into_open_drain_output(gpiob_crl);
+ let c = pb8.into_open_drain_output(gpiob_crh);
+ let d = pb6.into_open_drain_output(gpiob_crl);
+ let e = pb9.into_open_drain_output(gpiob_crh);
+ let f = pb3.into_open_drain_output(gpiob_crl);
+ let g = pb4.into_open_drain_output(gpiob_crl);
+ let dpp = pb7.into_open_drain_output(gpiob_crl);
+
+ let dig1 = pa6.into_alternate_open_drain(gpioa_crl);
+ let dig2 = pa3.into_alternate_open_drain(gpioa_crl);
+ let dig3 = pa7.into_alternate_open_drain(gpioa_crl);
+ let dig4 = pa8.into_alternate_open_drain(gpioa_crh);
+ let dig5 = pa9.into_alternate_open_drain(gpioa_crh);
+ let dig6 = pa2.into_alternate_open_drain(gpioa_crl);
+ let dig7 = pa10.into_alternate_open_drain(gpioa_crh);
+ let dig8 = pa1.into_alternate_open_drain(gpioa_crl);
let pwm_freq = 2.kHz();
let pins1 = (dig4, dig5, dig7);
- let pwm1 = dp
- .TIM1
- .pwm_hz::<Tim1NoRemap, _, _>(pins1, &mut afio.mapr, pwm_freq, &clocks);
+ let pwm1 = tim1.pwm_hz::<Tim1NoRemap, _, _>(pins1, afio_mapr, pwm_freq, &clocks);
let pins2 = (dig8, dig6, dig2);
- let pwm2 = dp
- .TIM2
- .pwm_hz::<Tim2NoRemap, _, _>(pins2, &mut afio.mapr, pwm_freq, &clocks);
+ let pwm2 = tim2.pwm_hz::<Tim2NoRemap, _, _>(pins2, afio_mapr, pwm_freq, &clocks);
let pins3 = (dig1, dig3);
- let pwm3 = dp
- .TIM3
- .pwm_hz::<Tim3NoRemap, _, _>(pins3, &mut afio.mapr, pwm_freq, &clocks);
+ let pwm3 = tim3.pwm_hz::<Tim3NoRemap, _, _>(pins3, afio_mapr, pwm_freq, &clocks);
- let mut tim4 = dp.TIM4.counter_us(&clocks);
+ let mut tim4 = tim4.counter_us(&clocks);
tim4.listen(Event::Update);
tim4.start(10.micros()).unwrap();
@@ 197,14 172,111 @@ fn main() -> ! {
);
let display = ClockDisplay::new(display);
- let mut display = ClockDisplayViewer::new(display);
+ ClockDisplayViewer::new(display)
+}
+
+fn init_buttons(
+ pb15: Pin<'B', 15, Input<Floating>>,
+ pb14: Pin<'B', 14, Input<Floating>>,
+ pb13: Pin<'B', 13, Input<Floating>>,
+ pc13: Pin<'C', 13, Input<Floating>>,
+ gpiob_crh: &mut Cr<'B', true>,
+ gpioc_crh: &mut Cr<'C', true>,
+) -> [Button<ActiveHigh>; 4] {
+ let btn1 = Button::<ActiveHigh>::new(Box::new(pb15.into_pull_down_input(gpiob_crh)));
+ let btn2 = Button::<ActiveHigh>::new(Box::new(pb14.into_pull_down_input(gpiob_crh)));
+ let btn3 = Button::<ActiveHigh>::new(Box::new(pb13.into_pull_down_input(gpiob_crh)));
+ let btn4 = Button::<ActiveHigh>::new(Box::new(pc13.into_pull_down_input(gpioc_crh)));
+
+ [btn1, btn2, btn3, btn4]
+}
+
+fn init_leds<'a>(
+ pb12: Pin<'B', 12, Input<Floating>>,
+ pb11: Pin<'B', 11, Input<Floating>>,
+ pb1: Pin<'B', 1, Input<Floating>>,
+ pb0: Pin<'B', 0, Input<Floating>>,
+ gpiob_crl: &mut Cr<'B', false>,
+ gpiob_crh: &mut Cr<'B', true>,
+) -> [Box<dyn OutputPin<Error = Infallible> + Send>; 4] {
+ let led1 = pb12.into_open_drain_output(gpiob_crh);
+ let led2 = pb11.into_open_drain_output(gpiob_crh);
+ let led3 = pb1.into_open_drain_output(gpiob_crl);
+ let led4 = pb0.into_open_drain_output(gpiob_crl);
+
+ [Box::new(led1), Box::new(led2), Box::new(led3), Box::new(led4)]
+}
+
+fn init_heap() {
+ use core::mem::MaybeUninit;
+ const HEAP_SIZE: usize = 512;
+ static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
+ unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
+}
+
+#[entry]
+fn main() -> ! {
+ init_heap();
+
+ let cp = cortex_m::Peripherals::take().unwrap();
+ let dp = pac::Peripherals::take().unwrap();
+
+ let mut pwr = dp.PWR;
+ let mut flash = dp.FLASH.constrain();
+ let rcc = dp.RCC.constrain();
+ let mut backup_domain = rcc.bkp.constrain(dp.BKP, &mut pwr);
+
+ let clocks = rcc
+ .cfgr
+ .use_hse(8.MHz())
+ .sysclk(24.MHz())
+ .pclk1(24.MHz())
+ .pclk2(24.MHz())
+ .freeze(&mut flash.acr);
+
+ let mut gpiob = dp.GPIOB.split();
+ let mut gpioa = dp.GPIOA.split();
+ let mut gpioc = dp.GPIOC.split();
+ let mut afio = dp.AFIO.constrain();
+ let (_, pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4);
+
+ let leds = init_leds(gpiob.pb12, gpiob.pb11, gpiob.pb1, gpiob.pb0, &mut gpiob.crl, &mut gpiob.crh);
+ let btns = init_buttons(gpiob.pb15, gpiob.pb14, gpiob.pb13, gpioc.pc13, &mut gpiob.crh, &mut gpioc.crh);
+
+ let mut display = init_segment_display(
+ gpiob.pb10,
+ gpiob.pb2,
+ gpiob.pb8,
+ gpiob.pb6,
+ gpiob.pb9,
+ pb3,
+ pb4,
+ gpiob.pb7,
+ gpioa.pa6,
+ gpioa.pa3,
+ gpioa.pa7,
+ gpioa.pa8,
+ gpioa.pa9,
+ gpioa.pa2,
+ gpioa.pa10,
+ gpioa.pa1,
+ dp.TIM1,
+ dp.TIM2,
+ dp.TIM3,
+ dp.TIM4,
+ &mut gpioa.crl,
+ &mut gpioa.crh,
+ &mut gpiob.crl,
+ &mut gpiob.crh,
+ &mut afio.mapr,
+ &clocks
+ );
display.set_current_view(DisplayViews::ClockSecondsView);
let mut rtc = match Rtc::restore_or_new(dp.RTC, &mut backup_domain) {
Restored(rtc) => rtc,
New(rtc) => rtc,
};
-
rtc.listen_seconds();
// Initialize the state inside of a critical section,
@@ 219,7 291,7 @@ fn main() -> ! {
}
let state = ClockState::new(
- Calendar::from_seconds(Calendar::new(0, 0, 0, 1, 7, 2023), current_time),
+ Calendar::from_seconds(Calendar::new(0, 0, 0, 1, 8, 2023), current_time),
MonoTimer::new(cp.DWT, cp.DCB, clocks),
);
@@ 231,8 303,11 @@ fn main() -> ! {
cortex_m::peripheral::NVIC::unmask(interrupt::TIM4);
}
- let mut delay = cp.SYST.delay(&clocks);
+ let delay = cp.SYST.delay(&clocks);
+ main_loop(delay, btns, leds)
+}
+fn main_loop(mut delay: SysDelay, mut btns: [Button<ActiveHigh>; 4], mut leds: [Box<dyn OutputPin<Error = Infallible> + Send>; 4]) -> ! {
loop {
for (i, btn) in btns.iter_mut().enumerate() {
btn.update();