use arbitrary_int::{u4, u6};
#[cfg(feature = "read")]
use embedded_flex_pin::FlexPin;
use embedded_hal::delay::DelayNs;
use embedded_hal::digital::OutputPin;
pub(crate) trait Ht1621bBusWrite {
fn write_bit(&mut self, b: bool);
fn cs_low(&mut self);
fn cs_high(&mut self);
fn frame_end(&mut self);
#[inline]
fn begin_frame(&mut self) {}
#[inline]
fn write_addr_bits(&mut self, addr: u6) {
let mut mask: u8 = 0x20;
for _ in 0..6 {
self.write_bit((addr.value() & mask) != 0);
mask >>= 1;
}
}
#[inline]
fn write_id_101_addr(&mut self, addr: u6) {
self.write_bit(true);
self.write_bit(false);
self.write_bit(true);
self.write_addr_bits(addr);
}
#[inline]
fn write_id_100(&mut self) {
self.write_bit(true);
self.write_bit(false);
self.write_bit(false);
}
fn write_command(&mut self, cmd: u8) {
self.cs_low();
self.begin_frame();
self.write_id_100();
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.frame_end();
}
fn write_words(&mut self, addr: u6, words: &[u4]) {
self.cs_low();
self.begin_frame();
self.write_id_101_addr(addr);
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.frame_end();
}
#[inline]
fn write_word(&mut self, addr: u6, word: u4) {
self.write_words(addr, &[word]);
}
fn write_bytes(&mut self, addr: u6, data: &[u8]) {
self.cs_low();
self.begin_frame();
self.write_id_101_addr(addr);
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.frame_end();
}
#[inline]
fn write_byte(&mut self, addr: u6, data: u8) {
self.write_bytes(addr, &[data]);
}
}
#[cfg(feature = "read")]
pub(crate) trait Ht1621bBusRead: Ht1621bBusWrite {
fn read_bit(&mut self) -> bool;
fn da_to_input(&mut self);
fn da_to_output(&mut self);
#[inline]
fn write_id_110(&mut self) {
self.write_bit(true);
self.write_bit(true);
self.write_bit(false);
}
#[inline]
fn write_id_110_addr(&mut self, addr: u6) {
self.write_id_110();
self.write_addr_bits(addr);
}
fn read_words(&mut self, addr: u6, buf: &mut [u4]) {
self.cs_low();
self.da_to_output();
self.write_id_110_addr(addr);
self.da_to_input();
for slot in buf.iter_mut() {
let mut value: u8 = 0;
let mut mask: u8 = 0x01;
for _ in 0..4 {
if self.read_bit() {
value |= mask;
}
mask <<= 1;
}
*slot = u4::new(value);
}
self.cs_high();
self.frame_end();
}
#[inline]
fn read_word(&mut self, addr: u6) -> u4 {
let mut buf = [u4::new(0)];
self.read_words(addr, &mut buf);
buf[0]
}
fn read_modify_write_word(&mut self, addr: u6, f: impl FnOnce(u4) -> u4) {
self.cs_low();
self.da_to_output();
self.write_id_101_addr(addr);
self.da_to_input();
let mut value: u8 = 0;
let mut mask: u8 = 0x01;
for _ in 0..4 {
if self.read_bit() {
value |= mask;
}
mask <<= 1;
}
let current = u4::new(value);
let modified = f(current);
self.da_to_output();
let mod_val = modified.value();
let mut mask: u8 = 0x01;
for _ in 0..4 {
self.write_bit((mod_val & mask) != 0);
mask <<= 1;
}
self.cs_high();
self.frame_end();
}
fn read_bytes(&mut self, addr: u6, buf: &mut [u8]) {
self.cs_low();
self.da_to_output();
self.write_id_110_addr(addr);
self.da_to_input();
for slot in buf.iter_mut() {
let mut lo: u8 = 0;
let mut mask: u8 = 0x01;
for _ in 0..4 {
if self.read_bit() {
lo |= mask;
}
mask <<= 1;
}
let mut hi: u8 = 0;
let mut mask: u8 = 0x01;
for _ in 0..4 {
if self.read_bit() {
hi |= mask;
}
mask <<= 1;
}
*slot = lo | (hi << 4);
}
self.cs_high();
self.frame_end();
}
#[inline]
fn read_byte(&mut self, addr: u6) -> u8 {
let mut buf = [0u8];
self.read_bytes(addr, &mut buf);
buf[0]
}
fn read_modify_write_words(
&mut self,
addr: u6,
len: usize,
mut f: impl FnMut(u4, usize) -> u4,
) {
self.cs_low();
self.da_to_output();
self.write_id_101_addr(addr);
for i in 0..len {
self.da_to_input();
let mut value: u8 = 0;
let mut mask: u8 = 0x01;
for _ in 0..4 {
if self.read_bit() {
value |= mask;
}
mask <<= 1;
}
let modified = f(u4::new(value), i);
self.da_to_output();
let v = modified.value();
let mut mask: u8 = 0x01;
for _ in 0..4 {
self.write_bit((v & mask) != 0);
mask <<= 1;
}
}
self.cs_high();
self.frame_end();
}
}
pub struct Ht1621bBus<CS, WR, DA, D> {
cs: CS,
wr: WR,
da: DA,
delay: D,
}
impl<CS, WR, DA, D> Ht1621bBus<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 }
}
}
impl<CS, WR, DA, D> Ht1621bBusWrite for Ht1621bBus<CS, WR, DA, D>
where
CS: OutputPin,
WR: OutputPin,
DA: OutputPin,
D: DelayNs,
{
#[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();
}
#[inline]
fn frame_end(&mut self) {
self.delay.delay_us(10);
}
}
#[cfg(feature = "read")]
pub struct Ht1621bBusRW<CS, WR, RD, DA, D> {
cs: CS,
wr: WR,
rd: RD,
da: DA,
delay: D,
}
#[cfg(feature = "read")]
impl<CS, WR, RD, DA, D> Ht1621bBusRW<CS, WR, RD, DA, D>
where
CS: OutputPin,
WR: OutputPin,
RD: OutputPin,
DA: FlexPin,
D: DelayNs,
{
pub fn new(mut cs: CS, mut wr: WR, mut rd: RD, mut da: DA, delay: D) -> Self {
let _ = cs.set_high();
let _ = wr.set_high();
let _ = rd.set_high();
let _ = da.set_high();
Self {
cs,
wr,
rd,
da,
delay,
}
}
}
#[cfg(feature = "read")]
impl<CS, WR, RD, DA, D> Ht1621bBusWrite for Ht1621bBusRW<CS, WR, RD, DA, D>
where
CS: OutputPin,
WR: OutputPin,
RD: OutputPin,
DA: FlexPin,
D: DelayNs,
{
#[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();
}
#[inline]
fn frame_end(&mut self) {
self.delay.delay_us(10);
}
#[inline]
fn begin_frame(&mut self) {
self.da_to_output();
}
}
#[cfg(feature = "read")]
impl<CS, WR, RD, DA, D> Ht1621bBusRead for Ht1621bBusRW<CS, WR, RD, DA, D>
where
CS: OutputPin,
WR: OutputPin,
RD: OutputPin,
DA: FlexPin,
D: DelayNs,
{
#[inline]
fn read_bit(&mut self) -> bool {
let _ = self.rd.set_low();
self.delay.delay_us(5);
let bit = self.da.is_high().unwrap_or(true);
let _ = self.rd.set_high();
self.delay.delay_us(5);
bit
}
#[inline]
fn da_to_input(&mut self) {
self.da.set_as_input_no_pull();
}
#[inline]
fn da_to_output(&mut self) {
self.da.set_as_output_default_speed();
let _ = self.da.set_high();
}
}