#[inline]
pub const fn rd(reg_offset: u16) -> u16 {
0x1800 + reg_offset
}
#[inline]
pub const fn wr(reg_offset: u16) -> u16 {
0x2800 + reg_offset
}
#[inline]
pub const fn and(bit: u16) -> u16 {
0x3000 + bit
}
#[inline]
pub const fn or(bit: u16) -> u16 {
0x4000 + bit
}
#[inline]
pub const fn wait(us: u16) -> u16 {
0x5000 + us
}
pub const RD_FULCAL: u16 = 0x6000;
pub const RD_DCCAL1: u16 = 0x7000;
pub const RD_DCCAL2: u16 = 0x8000;
pub const END: u16 = 0xF000;
const MAX_CMDS: usize = 128;
pub struct CmdBuilder {
buf: [u16; MAX_CMDS],
len: usize,
}
impl Default for CmdBuilder {
fn default() -> Self {
Self::new()
}
}
impl CmdBuilder {
pub const fn new() -> Self {
Self {
buf: [0; MAX_CMDS],
len: 0,
}
}
#[inline]
pub fn push(&mut self, cmd: u16) {
self.buf[self.len] = cmd;
self.len += 1;
}
pub fn pad_even(&mut self) {
if !self.len.is_multiple_of(2) {
self.push(END);
}
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn packed_word_count(&self) -> usize {
(self.len + 1) / 2
}
#[inline]
pub fn byte_len(&self) -> usize {
self.packed_word_count() * 4
}
#[inline]
pub fn packed_word(&self, index: usize) -> u32 {
assert!(index < self.packed_word_count());
let lo = self.buf[index * 2] as u32;
let hi = self.buf[index * 2 + 1] as u32;
lo | (hi << 16)
}
#[deprecated(note = "use packed_word() + MemRegion for bounds-checked writes")]
pub unsafe fn write_to_sram(&self, base: u32, offset: u32) -> u32 {
let mut addr = offset;
for i in (0..self.len).step_by(2) {
let lo = self.buf[i] as u32;
let hi = self.buf[i + 1] as u32;
let word = lo | (hi << 16);
core::ptr::write_volatile((base + addr) as *mut u32, word);
addr += 4;
}
addr
}
}