use core::convert::Infallible; use alloc::boxed::Box; use embedded_hal::PwmPin; use fugit::MicrosDurationU32; use stm32f1xx_hal::timer; use crate::count_down::CountDown; type OutputPin = dyn embedded_hal::digital::v2::OutputPin + Send; // How long to turn on a digit to show a number // (every digit will be turned on for this time, so this number shouldn't bee to large - so it's not flickering, // and it shouldn't be too small to allow the transistor and LED operate) const DIGIT_ON_TIME: MicrosDurationU32 = MicrosDurationU32::micros(1490); // How long to turn off the digits when moving from one digit to another // This is important to close off the previous transistor before next digit // is lit up. const DIGITS_OFF_TIME: MicrosDurationU32 = MicrosDurationU32::micros(500); struct DisplayState { digit_index: usize, next_show: bool, // if 1, next timer step is to show, if 0, next timer step is to hide } impl DisplayState { fn empty() -> Self { Self { digit_index: 0, next_show: true, } } fn step(&mut self) { self.next_show = !self.next_show; if self.next_show { self.digit_index = (self.digit_index + 1) % DIGITS; } } } pub struct Display { segments: [Box; 8], digits: [Box + Send>; DIGITS], timer: Box + Send>, data: [u8; DIGITS], brightness: [u16; DIGITS], state: DisplayState, } impl Display { pub fn new( segments: [Box; 8], mut digits: [Box + Send>; DIGITS], timer: Box + Send>, ) -> Self { for digit in digits.iter_mut() { digit.enable(); } Self { segments, digits, timer, data: [0; DIGITS], brightness: [0xFFFF; DIGITS], state: DisplayState::::empty(), } } pub fn data(&self) -> [u8; DIGITS] { self.data } pub fn set_data(&mut self, digits: [u8; DIGITS]) { self.data = digits; } pub fn set_digit(&mut self, digit: usize, set: u8) { self.data[digit] = set; } pub fn brightness(&self) -> [u16; DIGITS] { self.brightness } pub fn ref_brightness(&self) -> &[u16] { &self.brightness } pub fn set_brightness(&mut self, brightness: [u16; DIGITS]) { self.brightness = brightness; } pub fn set_digit_brightness(&mut self, digit: usize, brightness: u16) { self.brightness[digit] = brightness; } pub fn update(&mut self) -> nb::Result<(), timer::Error> { self.timer.wait()?; let now_show = self.state.next_show; let digit_index = self.state.digit_index; // turn every digit off for digit in self.digits.iter_mut() { digit.set_duty(0xFFFF); } if now_show { let digit = &mut self.digits[digit_index]; let data = self.data[digit_index]; let brightness = self.brightness[digit_index]; for (i, segment) in self.segments.iter_mut().enumerate() { segment .set_state((!(data & (1 << (7 - i)) > 0)).into()) .unwrap(); } digit.set_duty(0xFFFF - brightness); } self.timer.start(if now_show { DIGIT_ON_TIME } else { DIGITS_OFF_TIME }); self.state.step(); Ok(()) } }