1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#![no_std]
use embedded_hal::blocking::i2c::{WriteRead, Write};
const MAX17048_ADDR: u8 = 0x6C;
const DEFAULT_RCOMP: u8 = 0x97;
pub struct Max17048<I> {
i2c: I,
recv_buffer: [u8; 2]
}
impl<I, E> Max17048<I>
where I: WriteRead<Error = E> + Write<Error = E>,
E: core::fmt::Debug
{
pub fn new(i2c: I) -> Self {
let mut max = Max17048 {
i2c: i2c,
recv_buffer: [0u8; 2]
};
max.compensation(DEFAULT_RCOMP).unwrap();
max
}
pub fn version(&mut self) -> Result<u16, E> {
self.read(0x08)
}
pub fn soc(&mut self) -> Result<u16, E> {
match self.read(0x04) {
Ok(val) => Ok(val / 256),
Err(e) => Err(e)
}
}
pub fn charge_rate(&mut self) -> Result<f32, E> {
match self.read(0x16) {
Ok(val) => {
Ok(val as f32 * 0.208)
},
Err(e) => Err(e)
}
}
pub fn vcell(&mut self) -> Result<f32, E> {
match self.read(0x02) {
Ok(val) => Ok(val as f32 * 0.000078125),
Err(e) => Err(e)
}
}
pub fn temp_compensation(&mut self, temp: f32) -> Result<(), E>{
let rcomp = if temp > 20.0 {
DEFAULT_RCOMP as f32 + (temp - 20.0) * -0.5
} else {
DEFAULT_RCOMP as f32 + (temp - 20.0) * -5.0
};
self.compensation(rcomp as u8)
}
fn compensation(&mut self, rcomp: u8) -> Result<(), E>{
match self.read(0x0C) {
Ok(mut value) => {
value &= 0x00FF;
value |= (rcomp as u16) << 8;
self.write(0x0C, value)?;
Ok(())
},
Err(e) => Err(e)
}
}
fn read(&mut self, reg: u8) -> Result<u16, E> {
match self.i2c.write_read(MAX17048_ADDR, &[reg], &mut self.recv_buffer) {
Ok(_) => Ok((self.recv_buffer[0] as u16) << 8 | self.recv_buffer[1] as u16),
Err(e) => Err(e)
}
}
fn write(&mut self, reg: u8, value: u16) -> Result<(), E> {
self.i2c.write(MAX17048_ADDR, &[reg])?;
let msb = ((value & 0xFF00) >> 8) as u8;
let lsb = ((value & 0x00FF) >> 0) as u8;
self.i2c.write(MAX17048_ADDR, &[msb, lsb])?;
Ok(())
}
}