1#![no_std]
2
3use embedded_hal::i2c;
4
5#[allow(clippy::upper_case_acronyms)]
6#[derive(Debug, Copy, Clone, PartialEq, Eq)]
7#[repr(u8)]
8pub enum Register{
9 INPUT_P0 = 0x00,
10 INPUT_P1 = 0x01,
11 OUTPUT_P0 = 0x02,
12 OUTPUT_P1 = 0x03,
13 CONFIG_P0 = 0x04,
14 CONFIG_P1 = 0x05,
15 INT_P0 = 0x06,
16 INT_P1 = 0x07,
17 ID = 0x10,
18 CTL = 0x11,
19 LEDMS_P0 = 0x12,
20 LEDMS_P1 = 0x13,
21 DIM0_P10 = 0x20,
22 DIM1_P11 = 0x21,
23 DIM2_P12 = 0x22,
24 DIM3_P13 = 0x23,
25 DIM4_P00 = 0x24,
26 DIM5_P01 = 0x25,
27 DIM6_P02 = 0x26,
28 DIM7_P03 = 0x27,
29 DIM8_P04 = 0x28,
30 DIM9_P05 = 0x29,
31 DIM10_P06 = 0x2A,
32 DIM11_P07 = 0x2B,
33 DIM12_P14 = 0x2C,
34 DIM13_P15 = 0x2D,
35 DIM14_P16 = 0x2E,
36 DIM15_P17 = 0x2F,
37 SW_RSTN = 0x7F,
38}
39
40#[derive(Debug, Copy, Clone, PartialEq, Eq)]
41#[repr(usize)]
42pub enum Pin {
43 P00 = 0,
44 P01 = 1,
45 P02 = 2,
46 P03 = 3,
47 P04 = 4,
48 P05 = 5,
49 P06 = 6,
50 P07 = 7,
51 P10 = 8,
52 P11 = 9,
53 P12 = 10,
54 P13 = 11,
55 P14 = 12,
56 P15 = 13,
57 P16 = 14,
58 P17 = 15,
59}
60
61#[derive(Debug, Copy, Clone, PartialEq, Eq)]
62#[repr(usize)]
63pub enum Dir {
64 INPUT = 1,
65 OUTPUT = 0,
66}
67
68#[derive(Debug, Copy, Clone, PartialEq, Eq)]
69#[repr(usize)]
70pub enum OutputMode {
71 OD = 0, PP = 1, }
74
75#[derive(Debug, Copy, Clone, PartialEq, Eq)]
76#[repr(usize)]
77pub enum DimmingRange {
78 IMAX = 0, IMAX_3_4 = 1, IMAX_2_4 = 2, IMAX_1_4 = 3, }
83
84#[derive(Debug)]
86pub enum Error<E> {
87 I2C(E),
89 InvalidInputData,
91}
92
93#[derive(Debug)]
94pub struct Aw9523b<I2C> {
95 i2c: I2C,
96 addr: u8,
97}
98
99impl<I2C, E> Aw9523b<I2C>
100where
101 I2C: i2c::I2c<Error = E>
102{
103 pub fn new(i2c: I2C, addr: u8) -> Self {
105 Aw9523b {
106 i2c,
107 addr,
108 }
109 }
110
111 pub fn write_register(&mut self, register: Register, value: u8) -> Result<(), Error<E>> {
113 let reg_val: [u8; 2] = [register as u8, value];
114 self.i2c.write(self.addr, ®_val).map_err(Error::I2C)
115 }
116
117 pub fn read_register(&mut self, register: Register) -> Result<u8, Error<E>> {
119 let mut val = [0u8; 1];
120 self.i2c.write_read(self.addr, &[register as u8], &mut val)
121 .map_err(Error::I2C)
122 .and(Ok(val[0]))
123 }
124
125 pub fn id(&mut self) -> Result<u8, Error<E>> {
127 self.read_register(Register::ID )
128 }
129
130 pub fn set_io_direction(&mut self, pin: Pin, dir: Dir) -> Result<(), Error<E>> {
132 let pin = pin as usize;
133 let mut port = false;
134 if pin & 8 != 0 {
135 port = true;
136 }
137
138 let bit = pin & 0x7;
139
140 let reg_config = if port {
141 Register::CONFIG_P1
142 } else {
143 Register::CONFIG_P0
144 };
145
146 if dir == Dir::INPUT {
147 let value = self.read_register(reg_config)?;
148 self.write_register(reg_config, value | (0x1 << bit))
149 } else {
150 let value = self.read_register(reg_config)?;
151 self.write_register(reg_config, value & !(0x1 << bit))
152 }
153 }
154
155 pub fn set_pin_high(&mut self, pin: Pin) -> Result<(), Error<E>> {
157 let pin = pin as usize;
158 let mut port = false;
159 if pin & 8 != 0 {
160 port = true;
161 }
162
163 let bit = pin & 0x7;
164
165 let (reg_config, reg_output) = match port {
166 false => (Register::CONFIG_P0, Register::OUTPUT_P0),
167 true => (Register::CONFIG_P1, Register::OUTPUT_P1),
168 };
169
170 let value = self.read_register(reg_config)?;
171 self.write_register(reg_config, value & !(0x1 << bit))?;
172 let value = self.read_register(reg_output)?;
173 self.write_register(reg_output, value | (0x1 << bit))
174 }
175
176 pub fn set_pin_low(&mut self, pin: Pin) -> Result<(), Error<E>> {
178 let pin = pin as usize;
179 let mut port = false; if pin & 0x08 != 0 {
181 port = true;
182 }
183
184 let bit = pin & 0x7;
185 let (reg_config, reg_output) = match port {
186 false => (Register::CONFIG_P0, Register::OUTPUT_P0),
187 true => (Register::CONFIG_P1, Register::OUTPUT_P1),
188 };
189
190 let value = self.read_register(reg_config)?;
191 self.write_register(reg_config, value & !(0x1 << bit))?;
192 let value = self.read_register(reg_output)?;
193 self.write_register(reg_output, value & !(0x1 << bit))
194 }
195
196 pub fn pin_is_high(&mut self, pin: Pin) -> Result<bool, Error<E>> {
197 let pin = pin as usize;
198 let mut port = false; if pin & 8 != 0 {
200 port = true; }
202
203 let bit = pin & 0x7;
204
205 let reg_input = if port {
206 Register::INPUT_P1
207 } else {
208 Register::INPUT_P0
209 };
210
211 let value = self.read_register(reg_input)?;
212 match (value >> bit) & 1 {
213 1 => Ok(true),
214 _ => Ok(false),
215 }
216 }
217
218 pub fn pin_is_low(&mut self, pin: Pin) -> Result<bool, Error<E>> {
219 let pin = pin as usize;
220 let mut port = false; if pin & 8 != 0 {
222 port = true; }
224
225 let bit = pin & 0x7;
226
227 let reg_input = if port {
228 Register::INPUT_P1
229 } else {
230 Register::INPUT_P0
231 };
232
233 let value = self.read_register(reg_input)?;
234 match (value >> bit) & 1 {
235 1 => Ok(false),
236 _ => Ok(true),
237 }
238 }
239
240 pub fn pin_enable_interrupt(&mut self, pin: Pin, en: bool) -> Result<(), Error<E>> {
241
242 let pin = pin as usize;
243 let mut port = false; if pin & 8 != 0 {
245 port = true; }
247
248 let bit = pin & 0x7;
249
250 let reg = if port {
251 Register::INT_P1
252 } else {
253 Register::INT_P0
254 };
255
256 if en {
257 let value = self.read_register(reg)?;
258 self.write_register(reg, value & !(0x1 << bit))
259 } else {
260 let value = self.read_register(reg)?;
261 self.write_register(reg, value | (0x1 << bit))
262 }
263 }
264
265 pub fn pin_gpio_mode(&mut self, pin: Pin) -> Result<(), Error<E>> {
266 let pin = pin as usize;
267 let mut port = false; if pin & 8 != 0 {
269 port = true; }
271
272 let bit = pin & 0x7;
273
274 let reg = if port {
275 Register::LEDMS_P1
276 } else {
277 Register::LEDMS_P0
278 };
279
280 let value = self.read_register(reg)?;
281 self.write_register(reg, value | (0x1 << bit))
282 }
283
284 pub fn pin_led_mode(&mut self, pin: Pin) -> Result<(), Error<E>> {
285 let pin = pin as usize;
286 let mut port = false; if pin & 8 != 0 {
288 port = true; }
290
291 let bit = pin & 0x7;
292
293 let reg = if port {
294 Register::LEDMS_P1
295 } else {
296 Register::LEDMS_P0
297 };
298
299 let value = self.read_register(reg)?;
300 self.write_register(reg, value & !(0x1 << bit))
301 }
302
303 pub fn port0_output_mode(&mut self, mode: OutputMode) -> Result<(), Error<E>> {
304
305 let value = self.read_register(Register::CTL)?;
306 let value = match mode {
307 OutputMode::OD => value & !(0x1 << 4),
308 OutputMode::PP => value | (0x1 << 4),
309 };
310 self.write_register(Register::CTL, value)
311 }
312
313 pub fn led_dimming_range(&mut self, range: DimmingRange) -> Result<(), Error<E>> {
314 let value = self.read_register(Register::CTL)?;
315 let value = match range {
316 DimmingRange::IMAX => value & !(0x3),
317 DimmingRange::IMAX_3_4 => (value & !(0x3)) | 0x1,
318 DimmingRange::IMAX_2_4 => (value & !(0x3)) | 0x2,
319 DimmingRange::IMAX_1_4 => value | 0x3,
320 };
321
322 self.write_register(Register::CTL, value)
323 }
324
325 pub fn led_set_dimming(&mut self, pin: Pin, dimming: u8) -> Result<(), Error<E>> {
326 let reg = match pin {
327 Pin::P00 => Register::DIM4_P00,
328 Pin::P01 => Register::DIM5_P01,
329 Pin::P02 => Register::DIM6_P02,
330 Pin::P03 => Register::DIM7_P03,
331 Pin::P04 => Register::DIM8_P04,
332 Pin::P05 => Register::DIM9_P05,
333 Pin::P06 => Register::DIM10_P06,
334 Pin::P07 => Register::DIM11_P07,
335 Pin::P10 => Register::DIM0_P10,
336 Pin::P11 => Register::DIM1_P11,
337 Pin::P12 => Register::DIM2_P12,
338 Pin::P13 => Register::DIM3_P13,
339 Pin::P14 => Register::DIM12_P14,
340 Pin::P15 => Register::DIM13_P15,
341 Pin::P16 => Register::DIM14_P16,
342 Pin::P17 => Register::DIM15_P17,
343 };
344
345 self.write_register(reg, dimming)
346 }
347
348 pub fn software_reset(&mut self) -> Result<(), Error<E>> {
349 self.write_register(Register::SW_RSTN, 0x00)
350 }
351}
352