use bitfield::bitfield;
pub mod frame;
pub mod row;
pub use frame::DmaFrameBuffer;
pub(crate) use crate::pinmap::{
LATCHED_COLOR0_MASK, LATCHED_COLOR1_MASK, LATCHED_LATCH_BIT, LATCHED_OE_BIT, LATCHED_PINMAP,
};
pub(crate) use crate::{INTER_ROW_BLANK, LEAD_BLANK_DELAY, TRAIL_BLANK_DELAY};
#[cfg(not(feature = "invert-oe"))]
pub(crate) const OE_ACTIVE: u8 = LATCHED_OE_BIT;
#[cfg(not(feature = "invert-oe"))]
pub(crate) const OE_BLANK: u8 = 0;
#[cfg(feature = "invert-oe")]
pub(crate) const OE_ACTIVE: u8 = 0;
#[cfg(feature = "invert-oe")]
pub(crate) const OE_BLANK: u8 = LATCHED_OE_BIT;
bitfield! {
#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub(crate) struct Address(u8);
impl Debug;
pub(crate) output_enable, set_output_enable: LATCHED_PINMAP.oe;
pub(crate) latch, set_latch: LATCHED_PINMAP.latch;
pub(crate) addr, set_addr: LATCHED_PINMAP.addr_msb(), LATCHED_PINMAP.addr_lsb;
}
impl Address {
pub const fn new() -> Self {
Self(0)
}
}
bitfield! {
#[derive(Clone, Copy, Default, PartialEq)]
#[repr(transparent)]
pub(crate) struct Entry(u8);
impl Debug;
pub(crate) output_enable, set_output_enable: LATCHED_PINMAP.oe;
pub(crate) latch, set_latch: LATCHED_PINMAP.latch;
pub(crate) blu2, set_blu2: LATCHED_PINMAP.blu1;
pub(crate) grn2, set_grn2: LATCHED_PINMAP.grn1;
pub(crate) red2, set_red2: LATCHED_PINMAP.red1;
pub(crate) blu1, set_blu1: LATCHED_PINMAP.blu0;
pub(crate) grn1, set_grn1: LATCHED_PINMAP.grn0;
pub(crate) red1, set_red1: LATCHED_PINMAP.red0;
}
impl Entry {
pub const fn new() -> Self {
Self(0)
}
#[inline]
fn set_color0_bits(&mut self, bits: u8) {
self.0 = (self.0 & !LATCHED_COLOR0_MASK) | (bits & LATCHED_COLOR0_MASK);
}
#[inline]
fn set_color1_bits(&mut self, bits: u8) {
self.0 = (self.0 & !LATCHED_COLOR1_MASK) | ((bits << 3) & LATCHED_COLOR1_MASK);
}
}
#[inline]
pub(crate) const fn map_index(index: usize) -> usize {
#[cfg(feature = "esp32-ordering")]
{
index ^ 2
}
#[cfg(not(feature = "esp32-ordering"))]
{
index
}
}
pub(crate) const fn make_addr_table() -> [[Address; 4]; 32] {
let mut tbl = [[Address::new(); 4]; 32];
let mut addr = 0;
while addr < 32 {
tbl[addr][map_index(0)].0 = OE_BLANK | LATCHED_LATCH_BIT | addr as u8;
tbl[addr][map_index(1)].0 = OE_BLANK | LATCHED_LATCH_BIT | addr as u8;
tbl[addr][map_index(2)].0 = OE_BLANK | addr as u8;
tbl[addr][map_index(3)].0 = OE_BLANK;
addr += 1;
}
tbl
}
pub(crate) const ADDR_TABLE: [[Address; 4]; 32] = make_addr_table();
#[allow(clippy::absurd_extreme_comparisons)]
pub(crate) const fn make_data_template<const COLS: usize>() -> [Entry; COLS] {
let mut data = [Entry::new(); COLS];
let mut i = 0;
while i < COLS {
let mapped_i = map_index(i);
data[mapped_i].0 =
if i >= TRAIL_BLANK_DELAY && i < COLS.saturating_sub(LEAD_BLANK_DELAY + 1) {
OE_ACTIVE
} else {
OE_BLANK
};
i += 1;
}
data
}