use arbitrary_int::{u4, u6};
use embedded_hal::delay::DelayNs;
use embedded_hal::digital::OutputPin;
pub struct Ht1621Bus<CS, WR, DA, D> {
cs: CS,
wr: WR,
da: DA,
delay: D,
}
impl<CS, WR, DA, D> Ht1621Bus<CS, WR, DA, D>
where
CS: OutputPin,
WR: OutputPin,
DA: OutputPin,
D: DelayNs,
{
pub fn new(mut cs: CS, mut wr: WR, mut da: DA, delay: D) -> Self {
let _ = cs.set_high();
let _ = wr.set_high();
let _ = da.set_high();
Self { cs, wr, da, delay }
}
pub fn write_command(&mut self, cmd: u8) {
self.cs_low();
self.write_bit(true);
self.write_bit(false);
self.write_bit(false);
let mut mask: u8 = 0x80;
for _ in 0..8 {
self.write_bit((cmd & mask) != 0);
mask >>= 1;
}
self.write_bit(false);
self.cs_high();
self.delay.delay_us(10);
}
pub fn write_words(&mut self, addr: u6, words: &[u4]) {
self.cs_low();
self.write_bit(true);
self.write_bit(false);
self.write_bit(true);
let mut mask: u8 = 0x20;
for _ in 0..6 {
self.write_bit((addr.value() & mask) != 0);
mask >>= 1;
}
for &word in words {
let value = word.value();
let mut mask: u8 = 0x01;
for _ in 0..4 {
self.write_bit((value & mask) != 0);
mask <<= 1;
}
}
self.cs_high();
self.delay.delay_us(10);
}
#[inline]
pub fn write_word(&mut self, addr: u6, word: u4) {
self.write_words(addr, &[word]);
}
pub fn write_bytes(&mut self, addr: u6, data: &[u8]) {
self.cs_low();
self.write_bit(true);
self.write_bit(false);
self.write_bit(true);
let mut mask: u8 = 0x20;
for _ in 0..6 {
self.write_bit((addr.value() & mask) != 0);
mask >>= 1;
}
for &byte in data {
let mut mask: u8 = 0x01;
for _ in 0..8 {
self.write_bit((byte & mask) != 0);
mask <<= 1;
}
}
self.cs_high();
self.delay.delay_us(10);
}
#[inline]
pub fn write_byte(&mut self, addr: u6, data: u8) {
self.write_bytes(addr, &[data]);
}
#[inline]
fn write_bit(&mut self, b: bool) {
if b {
let _ = self.da.set_high();
} else {
let _ = self.da.set_low();
}
let _ = self.wr.set_low();
self.delay.delay_us(5);
let _ = self.wr.set_high();
self.delay.delay_us(5);
}
#[inline]
fn cs_low(&mut self) {
let _ = self.cs.set_low();
}
#[inline]
fn cs_high(&mut self) {
let _ = self.cs.set_high();
}
}