1#![warn(rust_2018_idioms)]
25#![no_std]
26
27use embedded_hal::i2c;
28
29const AXP192_ADDRESS: u8 = 0x34;
30
31pub struct Axp192<I2C> {
33 i2c: I2C,
34}
35
36pub enum GpioMode0 {
40 NmosOpenDrainOutput = 0b000,
42 UniversalInput = 0b001,
44 LowNoiseLdo = 0b010,
46 Keep = 0b011,
48 AdcEnter = 0b100,
50 LowOutput = 0b101,
52 Floating = 0b110,
54}
55
56pub enum GpioMode12 {
60 NmosOpenDrainOutput = 0b000,
62 UniversalInput = 0b001,
64 PWMOutput = 0b010,
66 Keep = 0b011,
68 AdcEnter = 0b100,
70 LowOutput = 0b101,
72 Floating = 0b110,
74}
75
76pub enum GpioMode34 {
80 ExternalChargeControl = 0b00,
82 NmosOpenDrainOutput = 0b01,
84 UniversalInput = 0b10,
86 AdcEnter = 0b11,
89}
90
91pub enum BootTime {
95 Boot128ms = 0b00,
96 Boot512ms = 0b01,
97 Boot1s = 0b10,
98 Boot2s = 0b11,
99}
100
101pub enum LongPress {
105 Lp1000ms = 0b00,
106 Lp1500ms = 0b01,
107 Lp2000ms = 0b10,
108 Lp2500ms = 0b11,
109}
110
111pub enum PowerOkDelay {
115 Delay32ms = 0b0,
116 Delay64ms = 0b1,
117}
118
119pub enum ShutdownDuration {
123 Sd4s = 0b00,
124 Sd6s = 0b01,
125 Sd8s = 0b10,
126 Sd10s = 0b11,
127}
128
129impl<I2C, E> Axp192<I2C>
130where
131 I2C: i2c::I2c<Error = E>,
132{
133 pub fn new(i2c: I2C) -> Self {
137 Self { i2c }
138 }
139
140 fn get(&mut self, reg_addr: u8, buff: &mut [u8]) -> Result<(), E> {
142 self.i2c.write_read(AXP192_ADDRESS, &[reg_addr], buff)
143 }
144
145 fn get_8(&mut self, reg_addr: u8) -> Result<u8, E> {
146 let mut buff = [0u8];
147 self.get(reg_addr, &mut buff)?;
148 Ok(buff[0])
149 }
150
151 fn get_12(&mut self, reg_addr: u8) -> Result<u16, E> {
152 let mut buff = [0; 2];
153 self.get(reg_addr, &mut buff)?;
154 Ok(((buff[0] as u16) << 4) + (buff[1] as u16))
155 }
156
157 fn get_13(&mut self, reg_addr: u8) -> Result<u16, E> {
158 let mut buff = [0; 2];
159 self.get(reg_addr, &mut buff)?;
160 Ok(((buff[0] as u16) << 5) + (buff[1] as u16))
161 }
162
163 fn get_flag(&mut self, reg_addr: u8, flag: u8) -> Result<bool, E> {
164 Ok(self.get_8(reg_addr)? & flag != 0)
165 }
166
167 fn set_8(&mut self, addr: u8, v: u8) -> Result<(), E> {
168 self.i2c.write(AXP192_ADDRESS, &[addr, v])
169 }
170
171 fn set_flag(&mut self, addr: u8, bit: u8, state: bool) -> Result<(), E> {
172 let mut v = self.get_8(addr)?;
173 if state {
174 v |= bit;
175 } else {
176 v &= !bit;
177 }
178
179 self.set_8(addr, v)
180 }
181
182 fn voltage_value(value: u16, min: u16, max: u16, step: u16) -> u8 {
183 let value = value.clamp(min, max);
184 ((value - min) / step) as u8
185 }
186
187 pub fn get_power_status(&mut self) -> Result<u8, E> {
191 self.get_8(0x00)
192 }
193
194 pub fn get_charging(&mut self) -> Result<bool, E> {
196 self.get_flag(0x00, 0b0000_0100)
197 }
198
199 pub fn get_vbus_usable(&mut self) -> Result<bool, E> {
201 self.get_flag(0x00, 0b0001_0000)
202 }
203
204 pub fn get_vbus_present(&mut self) -> Result<bool, E> {
206 self.get_flag(0x00, 0b0010_0000)
207 }
208
209 pub fn get_acin_usable(&mut self) -> Result<bool, E> {
211 self.get_flag(0x00, 0b0100_0000)
212 }
213
214 pub fn get_acin_present(&mut self) -> Result<bool, E> {
216 self.get_flag(0x00, 0b1000_0000)
217 }
218
219 pub fn get_exten_on(&mut self) -> Result<bool, E> {
221 self.get_flag(0x10, 0b0000_0100)
222 }
223
224 pub fn set_exten_on(&mut self, state: bool) -> Result<(), E> {
226 self.set_flag(0x10, 0b0000_0100, state)
227 }
228
229 pub fn get_dcdc1_on(&mut self) -> Result<bool, E> {
231 self.get_flag(0x12, 0b0000_0001)
232 }
233
234 pub fn set_dcdc1_on(&mut self, state: bool) -> Result<(), E> {
239 self.set_flag(0x12, 0b0000_0001, state)
240 }
241
242 pub fn get_dcdc3_on(&mut self) -> Result<bool, E> {
244 self.get_flag(0x12, 0b0000_0010)
245 }
246
247 pub fn set_dcdc3_on(&mut self, state: bool) -> Result<(), E> {
249 self.set_flag(0x12, 0b0000_0010, state)
250 }
251
252 pub fn get_ldo2_on(&mut self) -> Result<bool, E> {
254 self.get_flag(0x12, 0b0000_0100)
255 }
256
257 pub fn set_ldo2_on(&mut self, state: bool) -> Result<(), E> {
259 self.set_flag(0x12, 0b0000_0100, state)
260 }
261
262 pub fn get_ldo3_on(&mut self) -> Result<bool, E> {
264 self.get_flag(0x12, 0b0000_1000)
265 }
266
267 pub fn set_ldo3_on(&mut self, state: bool) -> Result<(), E> {
269 self.set_flag(0x12, 0b0000_1000, state)
270 }
271
272 pub fn get_dcdc2_on(&mut self) -> Result<bool, E> {
274 self.get_flag(0x12, 0b0001_0000)
275 }
276
277 pub fn set_dcdc2_on(&mut self, state: bool) -> Result<(), E> {
279 self.set_flag(0x12, 0b0001_0000, state)
280 }
281
282 pub fn set_dcdc1_voltage(&mut self, voltage: u16) -> Result<(), E> {
289 let v = Self::voltage_value(voltage, 700, 3500, 25) & 0x7f;
290 self.set_8(0x26, v)
291 }
292
293 pub fn set_dcdc3_voltage(&mut self, voltage: u16) -> Result<(), E> {
297 let v = Self::voltage_value(voltage, 700, 3500, 25) & 0x7f;
298 self.set_8(0x27, v)
299 }
300
301 pub fn set_ldo3_voltage(&mut self, voltage: u16) -> Result<(), E> {
305 let v = Self::voltage_value(voltage, 1800, 3300, 100) & 0x0f;
306 let existing = self.get_8(0x28)?;
307 self.set_8(0x28, (existing & 0xf0) | v)
308 }
309
310 pub fn set_ldo2_voltage(&mut self, voltage: u16) -> Result<(), E> {
314 let v = Self::voltage_value(voltage, 1800, 3300, 100) & 0x0f;
315 let existing = self.get_8(0x28)?;
316 self.set_8(0x28, (existing & 0x0f) | (v << 4))
317 }
318
319 pub fn set_ipsout_always(&mut self, state: bool) -> Result<(), E> {
324 self.set_flag(0x30, 0b1000_0000, state)
325 }
326
327 pub fn set_key_mode(
329 &mut self,
330 shutdown_duration: ShutdownDuration,
331 powerok_delay: PowerOkDelay,
332 automatic_shutdown: bool,
333 longpress_duration: LongPress,
334 boot_time: BootTime,
335 ) -> Result<(), E> {
336 let v = (shutdown_duration as u8)
337 | ((powerok_delay as u8) << 2)
338 | ((automatic_shutdown as u8) << 3)
339 | ((longpress_duration as u8) << 4)
340 | ((boot_time as u8) << 6);
341 self.set_8(0x36, v)
342 }
343
344 pub fn get_acin_voltage(&mut self) -> Result<f32, E> {
348 let v = self.get_12(0x56)?;
349 Ok(v as f32 * 0.0017)
350 }
351
352 pub fn get_acin_current(&mut self) -> Result<f32, E> {
356 let v = self.get_12(0x58)?;
357 Ok(v as f32 * 0.000625)
358 }
359
360 pub fn get_vbus_voltage(&mut self) -> Result<f32, E> {
364 let v = self.get_12(0x5a)?;
365 Ok(v as f32 * 0.0017)
366 }
367
368 pub fn get_vbus_current(&mut self) -> Result<f32, E> {
372 let v = self.get_12(0x5c)?;
373 Ok(v as f32 * 0.000375)
374 }
375
376 pub fn get_internal_temperature(&mut self) -> Result<f32, E> {
380 let v = self.get_12(0x5e)?;
381 Ok((v as f32 * 0.1) - 144.7)
382 }
383
384 pub fn get_battery_voltage(&mut self) -> Result<f32, E> {
388 let v = self.get_12(0x78)?;
389 Ok(v as f32 * 0.0011)
390 }
391
392 pub fn get_battery_charge_current(&mut self) -> Result<f32, E> {
396 let v = self.get_13(0x7a)?;
397 Ok(v as f32 * 0.0005)
398 }
399
400 pub fn get_battery_discharge_current(&mut self) -> Result<f32, E> {
404 let v = self.get_13(0x7c)?;
405 Ok(v as f32 * 0.0005)
406 }
407
408 pub fn set_ts_adc_enable(&mut self, state: bool) -> Result<(), E> {
410 self.set_flag(0x82, 0b0000_0001, state)
411 }
412
413 pub fn set_aps_voltage_adc_enable(&mut self, state: bool) -> Result<(), E> {
415 self.set_flag(0x82, 0b0000_0010, state)
416 }
417
418 pub fn set_vbus_current_adc_enable(&mut self, state: bool) -> Result<(), E> {
420 self.set_flag(0x82, 0b0000_0100, state)
421 }
422
423 pub fn set_vbus_voltage_adc_enable(&mut self, state: bool) -> Result<(), E> {
425 self.set_flag(0x82, 0b0000_1000, state)
426 }
427
428 pub fn set_acin_current_adc_enable(&mut self, state: bool) -> Result<(), E> {
430 self.set_flag(0x82, 0b0001_0000, state)
431 }
432
433 pub fn set_acin_voltage_adc_enable(&mut self, state: bool) -> Result<(), E> {
435 self.set_flag(0x82, 0b0010_0000, state)
436 }
437
438 pub fn set_battery_current_adc_enable(&mut self, state: bool) -> Result<(), E> {
440 self.set_flag(0x82, 0b0100_0000, state)
441 }
442
443 pub fn set_battery_voltage_adc_enable(&mut self, state: bool) -> Result<(), E> {
445 self.set_flag(0x82, 0b1000_0000, state)
446 }
447
448 pub fn set_gpio0_mode(&mut self, mode: GpioMode0) -> Result<(), E> {
450 self.set_8(0x90, mode as u8)
451 }
452
453 pub fn set_gpio0_ldo_voltage(&mut self, voltage: u16) -> Result<(), E> {
457 let v = Self::voltage_value(voltage, 1800, 3300, 100) << 4;
458 self.set_8(0x91, v)
459 }
460
461 pub fn set_gpio1_mode(&mut self, mode: GpioMode12) -> Result<(), E> {
463 self.set_8(0x92, mode as u8)
464 }
465
466 pub fn set_gpio2_mode(&mut self, mode: GpioMode12) -> Result<(), E> {
468 self.set_8(0x93, mode as u8)
469 }
470
471 pub fn set_gpio0_output(&mut self, state: bool) -> Result<(), E> {
476 self.set_flag(0x94, 0b0000_0001, state)
477 }
478
479 pub fn set_gpio1_output(&mut self, state: bool) -> Result<(), E> {
484 self.set_flag(0x94, 0b0000_0010, state)
485 }
486
487 pub fn set_gpio2_output(&mut self, state: bool) -> Result<(), E> {
492 self.set_flag(0x94, 0b0000_0100, state)
493 }
494
495 pub fn set_gpio3_mode(&mut self, mode: GpioMode34) -> Result<(), E> {
497 let existing = self.get_8(0x95)?;
498 self.set_8(0x95, (existing & 0b1111_1100) | 0x80 | (mode as u8))
499 }
500
501 pub fn set_gpio4_mode(&mut self, mode: GpioMode34) -> Result<(), E> {
503 let existing = self.get_8(0x95)?;
504 self.set_8(0x95, (existing & 0b1111_0011) | 0x80 | ((mode as u8) << 2))
505 }
506
507 pub fn set_gpio3_output(&mut self, state: bool) -> Result<(), E> {
512 self.set_flag(0x96, 0b0000_0001, state)
513 }
514
515 pub fn set_gpio4_output(&mut self, state: bool) -> Result<(), E> {
520 self.set_flag(0x96, 0b0000_0010, state)
521 }
522}