use core::mem::offset_of;
use crate::hwcore::addr::MmioAddr;
use crate::hwcore::regs::access::{Ro, Rw};
#[repr(C)]
pub struct LtdcLayerRegs {
pub cr: Rw<u32>,
pub whpcr: Rw<u32>,
pub wvpcr: Rw<u32>,
pub ckcr: Rw<u32>,
pub pfcr: Rw<u32>,
pub cacr: Rw<u32>,
pub dccr: Rw<u32>,
pub bfcr: Rw<u32>,
_reserved_020: [u32; 2],
pub cfbar: Rw<u32>,
pub cfblr: Rw<u32>,
pub cfblnr: Rw<u32>,
_reserved_034: [u32; 19],
}
const _: () = assert!(offset_of!(LtdcLayerRegs, cr) == 0x00);
const _: () = assert!(offset_of!(LtdcLayerRegs, whpcr) == 0x04);
const _: () = assert!(offset_of!(LtdcLayerRegs, wvpcr) == 0x08);
const _: () = assert!(offset_of!(LtdcLayerRegs, ckcr) == 0x0C);
const _: () = assert!(offset_of!(LtdcLayerRegs, pfcr) == 0x10);
const _: () = assert!(offset_of!(LtdcLayerRegs, cacr) == 0x14);
const _: () = assert!(offset_of!(LtdcLayerRegs, dccr) == 0x18);
const _: () = assert!(offset_of!(LtdcLayerRegs, bfcr) == 0x1C);
const _: () = assert!(offset_of!(LtdcLayerRegs, cfbar) == 0x28);
const _: () = assert!(offset_of!(LtdcLayerRegs, cfblr) == 0x2C);
const _: () = assert!(offset_of!(LtdcLayerRegs, cfblnr) == 0x30);
const _: () = assert!(core::mem::size_of::<LtdcLayerRegs>() == 0x80);
#[repr(C)]
pub struct LtdcRegs {
pub idr: Ro<u32>,
pub lcr: Ro<u32>,
pub sscr: Rw<u32>,
pub bpcr: Rw<u32>,
pub awcr: Rw<u32>,
pub twcr: Rw<u32>,
pub gcr: Rw<u32>,
_reserved_01c: [u32; 2],
pub srcr: Rw<u32>,
_reserved_028: u32,
pub bccr: Rw<u32>,
_reserved_030: u32,
pub ier: Rw<u32>,
pub isr: Ro<u32>,
pub icr: Rw<u32>,
pub lipcr: Rw<u32>,
pub cpsr: Ro<u32>,
pub cdsr: Ro<u32>,
_reserved_04c: [u32; 14],
pub layers: [LtdcLayerRegs; 2],
}
const _: () = assert!(offset_of!(LtdcRegs, idr) == 0x000);
const _: () = assert!(offset_of!(LtdcRegs, lcr) == 0x004);
const _: () = assert!(offset_of!(LtdcRegs, sscr) == 0x008);
const _: () = assert!(offset_of!(LtdcRegs, bpcr) == 0x00C);
const _: () = assert!(offset_of!(LtdcRegs, awcr) == 0x010);
const _: () = assert!(offset_of!(LtdcRegs, twcr) == 0x014);
const _: () = assert!(offset_of!(LtdcRegs, gcr) == 0x018);
const _: () = assert!(offset_of!(LtdcRegs, srcr) == 0x024);
const _: () = assert!(offset_of!(LtdcRegs, bccr) == 0x02C);
const _: () = assert!(offset_of!(LtdcRegs, ier) == 0x034);
const _: () = assert!(offset_of!(LtdcRegs, isr) == 0x038);
const _: () = assert!(offset_of!(LtdcRegs, icr) == 0x03C);
const _: () = assert!(offset_of!(LtdcRegs, lipcr) == 0x040);
const _: () = assert!(offset_of!(LtdcRegs, cpsr) == 0x044);
const _: () = assert!(offset_of!(LtdcRegs, cdsr) == 0x048);
const _: () = assert!(offset_of!(LtdcRegs, layers) == 0x084);
pub const LTDC_LAYER2_OFFSET_IS_0X104: () =
assert!(offset_of!(LtdcRegs, layers) + core::mem::size_of::<LtdcLayerRegs>() == 0x104);
pub const LTDC_BASE: usize = 0x5000_1000;
pub struct Ltdc {
base: MmioAddr<LtdcRegs>,
}
impl Ltdc {
pub const unsafe fn new() -> Self {
Self {
base: unsafe { MmioAddr::new(LTDC_BASE) },
}
}
#[inline]
pub fn regs(&self) -> &LtdcRegs {
unsafe { &*self.base.as_ptr() }
}
#[inline]
pub fn layer1(&self) -> &LtdcLayerRegs {
&self.regs().layers[0]
}
#[inline]
pub fn layer2(&self) -> &LtdcLayerRegs {
&self.regs().layers[1]
}
}
#[cfg(test)]
mod tests {
use super::*;
use core::mem::size_of;
#[test]
fn layer_block_is_exactly_0x80_bytes() {
assert_eq!(size_of::<LtdcLayerRegs>(), 0x80);
}
#[test]
fn layer1_offset_is_0x84() {
assert_eq!(offset_of!(LtdcRegs, layers), 0x084);
}
#[test]
fn layer2_offset_is_0x104() {
let _: () = LTDC_LAYER2_OFFSET_IS_0X104;
let layer1 = offset_of!(LtdcRegs, layers);
assert_eq!(layer1 + size_of::<LtdcLayerRegs>(), 0x104);
}
#[test]
fn cfbar_at_layer_offset_0x28() {
assert_eq!(offset_of!(LtdcLayerRegs, cfbar), 0x28);
assert_eq!(offset_of!(LtdcRegs, layers) + 0x28, 0x0AC);
}
}