inky_frame/frame/
shift.rs

1// Permission is hereby granted, free of charge, to any person obtaining a copy
2// of this software and associated documentation files (the "Software"), to deal
3// in the Software without restriction, including without limitation the rights
4// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5// copies of the Software, and to permit persons to whom the Software is
6// furnished to do so, subject to the following conditions:
7//
8// The above copyright notice and this permission notice shall be included in
9// all copies or substantial portions of the Software.
10//
11// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17// SOFTWARE.
18//
19
20#![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}