aw9523b/
lib.rs

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,     // Open-Drain Mode
72    PP = 1,     // Push-Pull Mode
73}
74
75#[derive(Debug, Copy, Clone, PartialEq, Eq)]
76#[repr(usize)]
77pub enum DimmingRange {
78    IMAX = 0,           // Imax
79    IMAX_3_4 = 1,       // Imax * 3/4
80    IMAX_2_4 = 2,       // Imax * 2/4
81    IMAX_1_4 = 3,       // Imax * 1/4
82}
83
84/// All possible errors in this crate
85#[derive(Debug)]
86pub enum Error<E> {
87    /// iic communication error
88    I2C(E),
89    /// invalid input data provided
90    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    /// Create new instance of the device
104    pub fn new(i2c: I2C, addr: u8) -> Self {
105        Aw9523b {
106            i2c,
107            addr,
108        }
109    }
110
111    /// Write Register 8bit Data
112    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, &reg_val).map_err(Error::I2C)
115    }
116
117    /// Read Register 8bit Data
118    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    /// Read Chip ID
126    pub fn id(&mut self) -> Result<u8, Error<E>> {
127        self.read_register(Register::ID )
128    }
129
130    /// Set IO Direction
131    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    /// Set Pin Output High
156    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    /// Set Pin Output Low
177    pub fn set_pin_low(&mut self, pin: Pin) -> Result<(), Error<E>> {
178        let pin = pin as usize;
179        let mut port = false;   //P0
180        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;   // P0
199        if pin & 8 != 0 {
200            port = true;    // P1
201        }
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;   // P0
221        if pin & 8 != 0 {
222            port = true;    // P1
223        }
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;   // P0
244        if pin & 8 != 0 {
245            port = true;    // P1
246        }
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;   // P0
268        if pin & 8 != 0 {
269            port = true;    // P1
270        }
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;   // P0
287        if pin & 8 != 0 {
288            port = true;    // P1
289        }
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