#![no_implicit_prelude]
extern crate core;
extern crate rpsp;
use core::clone::Clone;
use core::cmp::Ord;
use core::convert::From;
use rpsp::Board;
use rpsp::clock::Timer;
use rpsp::pin::gpio::{Input, Output};
use rpsp::pin::{Pin, PinID};
use crate::hw::WakeReason;
pub struct ShiftRegister {
lat: Pin<Output>,
data: Pin<Input>,
clock: Pin<Output>,
timer: Timer,
}
impl ShiftRegister {
#[inline]
pub fn new(p: &Board, clock: PinID, lat: PinID, data: PinID) -> ShiftRegister {
ShiftRegister {
lat: p.pin(lat).output_high(),
clock: p.pin(clock).output_high(),
data: p.pin(data).into_input(),
timer: p.timer().clone(),
}
}
pub fn read(&self) -> u8 {
self.lat.low();
self.timer.sleep_us(2);
self.lat.high();
self.timer.sleep_us(2);
let (mut r, mut b) = (0u8, 8u8);
while b > 0 {
b -= 1;
r = unsafe { r.unchecked_shl(1) };
if self.data.is_high() {
r |= 1
} else {
r |= 0
}
self.clock.low();
self.timer.sleep_us(2);
self.clock.high();
self.timer.sleep_us(2);
}
r
}
#[inline]
pub fn is_set(&self, v: u8) -> bool {
unsafe { self.read() & 1u8.unchecked_shl((v as u32).min(7)) != 0 }
}
#[inline]
pub fn read_wake(&self) -> WakeReason {
WakeReason::from(self.read())
}
}
impl Clone for ShiftRegister {
#[inline]
fn clone(&self) -> ShiftRegister {
ShiftRegister {
lat: self.lat.clone(),
data: self.data.clone(),
clock: self.clock.clone(),
timer: self.timer.clone(),
}
}
}