#![cfg_attr(feature = "v1", doc = " hal::{self, gpio::p0::Parts as P0Parts},")]
#![cfg_attr(
feature = "v2",
doc = " hal::{self, gpio::{p0::Parts as P0Parts, p1::Parts as P1Parts}},"
)]
#![cfg_attr(feature = "v1", doc = " let p0parts = P0Parts::new(p.GPIO);")]
#![cfg_attr(feature = "v1", doc = " display_pins!(p0parts)")]
#![cfg_attr(feature = "v2", doc = " let p0parts = P0Parts::new(p.P0);")]
#![cfg_attr(feature = "v2", doc = " let p1parts = P1Parts::new(p.P1);")]
#![cfg_attr(feature = "v2", doc = " display_pins!(p0parts, p1parts)")]
use crate::hal::{
gpio::{Output, Pin, PushPull},
prelude::*,
};
use crate::gpio::{DisplayPins, NUM_COLS, NUM_ROWS};
use embedded_hal::blocking::delay::DelayUs;
#[allow(clippy::upper_case_acronyms)]
pub(crate) type LED = Pin<Output<PushPull>>;
const DEFAULT_DELAY_MS: u32 = 2;
#[cfg(feature = "v1")]
const LED_LAYOUT: [[(usize, usize); 5]; 5] = [
[(0, 0), (1, 3), (0, 1), (1, 4), (0, 2)],
[(2, 3), (2, 4), (2, 5), (2, 6), (2, 7)],
[(1, 1), (0, 8), (1, 2), (2, 8), (1, 0)],
[(0, 7), (0, 6), (0, 5), (0, 4), (0, 3)],
[(2, 2), (1, 6), (2, 0), (1, 5), (2, 1)],
];
pub struct Display {
delay_ms: u32,
rows: [LED; NUM_ROWS],
cols: [LED; NUM_COLS],
}
impl Display {
pub fn new(pins: DisplayPins) -> Self {
let (cols, rows) = pins.degrade();
let mut retval = Display {
delay_ms: DEFAULT_DELAY_MS,
rows,
cols,
};
retval.clear();
retval
}
pub fn clear(&mut self) {
for row in &mut self.rows {
row.set_low().ok();
}
for col in &mut self.cols {
col.set_high().ok();
}
}
pub fn set_delay_ms(&mut self, delay_ms: u32) {
self.delay_ms = delay_ms;
}
pub fn set_refresh_rate(&mut self, freq_hz: u32) {
self.delay_ms = 1000 / freq_hz / 3;
}
#[cfg(feature = "v1")]
pub fn display2matrix(led_display: [[u8; 5]; 5]) -> [[u8; 9]; 3] {
let mut led_matrix: [[u8; 9]; 3] = [[0; 9]; 3];
for (led_display_row, layout_row) in led_display.iter().zip(LED_LAYOUT.iter()) {
for (led_display_val, layout_loc) in led_display_row.iter().zip(layout_row) {
led_matrix[layout_loc.0][layout_loc.1] = *led_display_val;
}
}
led_matrix
}
pub fn display<D: DelayUs<u32>>(
&mut self,
delay: &mut D,
led_display: [[u8; 5]; 5],
duration_ms: u32,
) {
#[cfg(feature = "v1")]
{
let led_matrix = Display::display2matrix(led_display);
self.display_pre(delay, led_matrix, duration_ms);
}
#[cfg(feature = "v2")]
self.display_pre(delay, led_display, duration_ms);
}
pub fn display_pre<D: DelayUs<u32>>(
&mut self,
delay: &mut D,
led_matrix: [[u8; NUM_COLS]; NUM_ROWS],
duration_ms: u32,
) {
let loops = duration_ms / (self.rows.len() as u32 * self.delay_ms);
for _ in 0..loops {
for (row_line, led_matrix_row) in self.rows.iter_mut().zip(led_matrix.iter()) {
row_line.set_high().ok();
for (col_line, led_matrix_val) in self.cols.iter_mut().zip(led_matrix_row.iter()) {
if *led_matrix_val > 0 {
col_line.set_low().ok();
}
}
delay.delay_us(self.delay_ms * 1000);
for col_line in &mut self.cols {
col_line.set_high().ok();
}
row_line.set_low().ok();
}
}
}
}