inky_frame/frame/
shift.rs1#![no_implicit_prelude]
21
22extern crate core;
23extern crate rpsp;
24
25use core::clone::Clone;
26use core::convert::From;
27
28use rpsp::Board;
29use rpsp::clock::Timer;
30use rpsp::pin::gpio::{Input, Output};
31use rpsp::pin::{Pin, PinID};
32
33use crate::hw::WakeReason;
34
35pub struct ShiftRegister {
36 lat: Pin<Output>,
37 data: Pin<Input>,
38 clock: Pin<Output>,
39 timer: Timer,
40}
41
42impl ShiftRegister {
43 #[inline]
44 pub fn new(p: &Board, clock: PinID, lat: PinID, data: PinID) -> ShiftRegister {
45 ShiftRegister {
46 lat: p.pin(lat).output_high(),
47 clock: p.pin(clock).output_high(),
48 data: p.pin(data).into_input(),
49 timer: p.timer().clone(),
50 }
51 }
52
53 pub fn read(&self) -> u8 {
54 self.lat.low();
55 self.timer.sleep_us(2);
56 self.lat.high();
57 self.timer.sleep_us(2);
58 let (mut r, mut b) = (0u8, 8u8);
59 while b > 0 {
60 b -= 1;
61 r <<= 1;
62 if self.data.is_high() {
63 r |= 1
64 } else {
65 r |= 0
66 }
67 self.clock.low();
68 self.timer.sleep_us(2);
69 self.clock.high();
70 self.timer.sleep_us(2);
71 }
72 r
73 }
74 #[inline(always)]
75 pub fn is_set(&self, v: u8) -> bool {
76 self.read() & (1 << v) != 0
77 }
78 #[inline(always)]
79 pub fn read_wake(&self) -> WakeReason {
80 WakeReason::from(self.read())
81 }
82}
83
84impl Clone for ShiftRegister {
85 #[inline(always)]
86 fn clone(&self) -> ShiftRegister {
87 ShiftRegister {
88 lat: self.lat.clone(),
89 data: self.data.clone(),
90 clock: self.clock.clone(),
91 timer: self.timer.clone(),
92 }
93 }
94}