mod color;
use crate::hub75::Hub75Pins;
use embedded_hal::digital::OutputPin;
pub use color::Rgb565;
const ROW_DISPLAY_CYCLES: u32 = 20_000;
pub fn display_frame<const W: usize, const H: usize, P: OutputPin>(pins: &mut Hub75Pins<P>, fb: &PixelMap<W, H>) {
let scan_pairs = H / 2;
for row in 0..scan_pairs {
pins.oe_off();
pins.set_row(row as u8);
for col in 0..W {
let (r1, g1, b1) = fb.read(col, row).to_1bit();
let (r2, g2, b2) = fb.read(col, row + scan_pairs).to_1bit();
pins.shift_pixel(r1, g1, b1, r2, g2, b2);
}
pins.latch();
pins.oe_on();
for _ in 0..ROW_DISPLAY_CYCLES {
core::hint::spin_loop();
}
}
pins.oe_off();
}
pub struct PixelMap<const W: usize, const H: usize> {
pixels: [[Rgb565; W]; H],
}
impl<const W: usize, const H: usize> PixelMap<W, H> {
pub const fn new() -> Self {
Self {
pixels: [[Rgb565::black(); W]; H],
}
}
pub fn write_color_at(&mut self, x: usize, y: usize, color: Rgb565) {
if x < W && y < H {
self.pixels[y][x] = color;
}
}
pub fn read(&self, x: usize, y: usize) -> Rgb565 {
if x < W && y < H {
self.pixels[y][x]
} else {
Rgb565::black()
}
}
pub fn fill(&mut self, color: Rgb565) {
for row in self.pixels.iter_mut() {
for pixel in row.iter_mut() {
*pixel = color;
}
}
}
pub fn clear(&mut self) {
self.fill(Rgb565::black());
}
pub fn pixels(&self) -> &[[Rgb565; W]; H] {
&self.pixels
}
}
impl<const W: usize, const H: usize> Default for PixelMap<W, H> {
fn default() -> Self {
Self::new()
}
}