1use core::cell::Cell;
12
13use kernel::hil::gpio::Pin;
14use kernel::hil::led::Led;
15
16pub struct Sk68xx<'a, P: Pin, const T0H: usize> {
22 pin: &'a P,
23 nop: fn(),
24 red: Cell<bool>,
25 green: Cell<bool>,
26 blue: Cell<bool>,
27}
28
29impl<'a, P: Pin, const T0H: usize> Sk68xx<'a, P, T0H> {
30 pub fn new(pin: &'a P, nop: fn()) -> Self {
31 Self {
32 pin,
33 nop,
34 red: Cell::new(false),
35 green: Cell::new(false),
36 blue: Cell::new(false),
37 }
38 }
39
40 pub fn init(&self) {
41 self.pin.make_output();
42 self.pin.clear();
43 for _ in 0..(286 * T0H) {
45 (self.nop)();
46 }
47 }
48
49 fn write(&self) {
50 let red = self.red.get();
51 let green = self.green.get();
52 let blue = self.blue.get();
53
54 for i in 0..24 {
55 let high = if i < 8 {
56 green
58 } else if i < 16 {
59 red
61 } else {
62 blue
64 };
65 if high {
66 self.pin.set();
68 for _ in 0..(T0H * 3) {
69 (self.nop)();
70 }
71
72 self.pin.clear();
74 for _ in 0..(T0H * 2) {
75 (self.nop)();
76 }
77 } else {
78 self.pin.set();
80 for _ in 0..T0H {
81 (self.nop)();
82 }
83
84 self.pin.clear();
86 for _ in 0..(T0H * 4) {
87 (self.nop)();
88 }
89 }
90 }
91
92 for _ in 0..(286 * T0H) {
95 (self.nop)();
96 }
97 }
98
99 fn update_red(&self, on: bool) {
100 self.red.set(on);
101 self.write();
102 }
103
104 fn update_green(&self, on: bool) {
105 self.green.set(on);
106 self.write();
107 }
108
109 fn update_blue(&self, on: bool) {
110 self.blue.set(on);
111 self.write();
112 }
113
114 fn toggle_red(&self) {
115 self.red.set(!self.red.get());
116 self.write();
117 }
118
119 fn toggle_green(&self) {
120 self.green.set(!self.green.get());
121 self.write();
122 }
123
124 fn toggle_blue(&self) {
125 self.blue.set(!self.blue.get());
126 self.write();
127 }
128
129 fn get_red(&self) -> bool {
130 self.red.get()
131 }
132
133 fn get_green(&self) -> bool {
134 self.green.get()
135 }
136
137 fn get_blue(&self) -> bool {
138 self.blue.get()
139 }
140}
141
142pub struct Sk68xxLed<'a, P: Pin, const T0H: usize> {
148 sk68xx: &'a Sk68xx<'a, P, T0H>,
149 index: usize,
150}
151
152impl<'a, P: Pin, const T0H: usize> Sk68xxLed<'a, P, T0H> {
153 pub fn new(sk68xx: &'a Sk68xx<'a, P, T0H>, index: usize) -> Self {
154 Self { sk68xx, index }
155 }
156}
157
158impl<P: Pin, const T0H: usize> Led for Sk68xxLed<'_, P, T0H> {
159 fn init(&self) {}
160
161 fn on(&self) {
162 match self.index {
163 0 => self.sk68xx.update_red(true),
164 1 => self.sk68xx.update_green(true),
165 2 => self.sk68xx.update_blue(true),
166 _ => {}
167 }
168 }
169
170 fn off(&self) {
171 match self.index {
172 0 => self.sk68xx.update_red(false),
173 1 => self.sk68xx.update_green(false),
174 2 => self.sk68xx.update_blue(false),
175 _ => {}
176 }
177 }
178
179 fn toggle(&self) {
180 match self.index {
181 0 => self.sk68xx.toggle_red(),
182 1 => self.sk68xx.toggle_green(),
183 2 => self.sk68xx.toggle_blue(),
184 _ => {}
185 }
186 }
187
188 fn read(&self) -> bool {
189 match self.index {
190 0 => self.sk68xx.get_red(),
191 1 => self.sk68xx.get_green(),
192 2 => self.sk68xx.get_blue(),
193 _ => false,
194 }
195 }
196}