1use crate::regs::*;
2use crate::traits::AS5600Interface;
3use crate::types::*;
4use crate::error::AS56Error;
5use embedded_hal::i2c::{I2c, SevenBitAddress};
6
7pub struct AS5600Driver<I2C> {
9 i2c: I2C,
10 address: u8,
11}
12
13impl<I2C: I2c<SevenBitAddress>> AS5600Driver<I2C> {
14 pub fn new(i2c: I2C) -> Self {
16 Self {
17 i2c,
18 address: DEFAULT_ADDR,
19 }
20 }
21
22 pub fn with_address(i2c: I2C, address: u8) -> Self {
24 Self { i2c, address }
25 }
26
27 fn read_u8(&mut self, reg: u8) -> Result<u8, AS56Error<I2C::Error>> {
29 let mut buf = [0u8; 1];
30 self.i2c
31 .write_read(self.address, &[reg], &mut buf)
32 .map_err(AS56Error::I2c)?;
33 Ok(buf[0])
34 }
35
36 fn write_u8(&mut self, reg: u8, value: u8) -> Result<(), AS56Error<I2C::Error>> {
38 self.i2c
39 .write(self.address, &[reg, value])
40 .map_err(AS56Error::I2c)?;
41 Ok(())
42 }
43
44 fn read_u16(&mut self, reg_hi: u8) -> Result<u16, AS56Error<I2C::Error>> {
46 let mut buf = [0u8; 2];
47 self.i2c
48 .write_read(self.address, &[reg_hi], &mut buf)
49 .map_err(AS56Error::I2c)?;
50 Ok(u16::from_be_bytes(buf) & 0x0FFF)
51 }
52
53 fn write_u16(&mut self, reg_hi: u8, value: u16) -> Result<(), AS56Error<I2C::Error>> {
55 let bytes = value.to_be_bytes();
56 self.i2c
57 .write(self.address, &[reg_hi, bytes[0], bytes[1]])
58 .map_err(AS56Error::I2c)?;
59 Ok(())
60 }
61
62 pub unsafe fn danger_permanent_burn_settings(&mut self) -> Result<(), AS56Error<I2C::Error>> {
64 self.i2c
65 .write(self.address, &[regs::BURN, 0x80])
66 .map_err(AS56Error::I2c)?;
67 Ok(())
68 }
69
70 pub unsafe fn danger_permanent_burn_config(&mut self) -> Result<(), AS56Error<I2C::Error>> {
72 self.i2c
73 .write(self.address, &[regs::BURN, 0x40])
74 .map_err(AS56Error::I2c)?;
75 Ok(())
76 }
77}
78
79impl<I2C: I2c<SevenBitAddress>> AS5600Interface for AS5600Driver<I2C> {
80 type Error = I2C::Error;
81
82 fn read_raw_angle(&mut self) -> Result<u16, AS56Error<Self::Error>> {
83 self.read_u16(regs::RAW_ANGLE_HI)
84 }
85
86 fn read_angle(&mut self) -> Result<u16, AS56Error<Self::Error>> {
87 self.read_u16(regs::ANGLE_HI)
88 }
89
90 fn get_burn_count(&mut self) -> Result<u8, AS56Error<Self::Error>> {
91 Ok(self.read_u8(regs::ZMCO)? & 0x03)
92 }
93
94 fn get_status_raw(&mut self) -> Result<u8, AS56Error<Self::Error>> {
95 self.read_u8(regs::STATUS)
96 }
97
98 fn get_magnet_status(&mut self) -> Result<MagnetStatus, AS56Error<Self::Error>> {
99 let val = self.read_u8(regs::STATUS)?;
100 Ok(MagnetStatus {
101 detected: (val & 0x20) != 0,
102 too_weak: (val & 0x10) != 0,
103 too_strong: (val & 0x08) != 0,
104 })
105 }
106
107 fn get_magnitude(&mut self) -> Result<u16, AS56Error<Self::Error>> {
108 self.read_u16(regs::MAGNITUDE_HI)
109 }
110
111 fn get_agc(&mut self) -> Result<u8, AS56Error<Self::Error>> {
112 self.read_u8(regs::AGC)
113 }
114
115 fn get_config(&mut self) -> Result<Configuration, AS56Error<Self::Error>> {
116 let hi = self.read_u8(regs::CONF_HI)?;
117 let lo = self.read_u8(regs::CONF_LO)?;
118
119 Ok(Configuration {
120 power_mode: match lo & 0x03 {
121 0b01 => PowerMode::LPM1,
122 0b10 => PowerMode::LPM2,
123 0b11 => PowerMode::LPM3,
124 _ => PowerMode::Nominal,
125 },
126 hysteresis: match (lo >> 2) & 0x03 {
127 0b01 => Hysteresis::Lsb1,
128 0b10 => Hysteresis::Lsb2,
129 0b11 => Hysteresis::Lsb3,
130 _ => Hysteresis::Off,
131 },
132 output_stage: match (lo >> 4) & 0x03 {
133 0b01 => OutputStage::AnalogReduced,
134 0b10 => OutputStage::PWM,
135 _ => OutputStage::AnalogFull,
136 },
137 pwm_frequency: match (lo >> 6) & 0x03 {
138 0b01 => PwmFrequency::Hz230,
139 0b10 => PwmFrequency::Hz460,
140 0b11 => PwmFrequency::Hz920,
141 _ => PwmFrequency::Hz115,
142 },
143 slow_filter: match hi & 0x03 {
144 0b01 => SlowFilter::X8,
145 0b10 => SlowFilter::X4,
146 0b11 => SlowFilter::X2,
147 _ => SlowFilter::X16,
148 },
149 fast_filter_threshold: match (hi >> 2) & 0x07 {
150 0b001 => FastFilterThreshold::Lsb6,
151 0b010 => FastFilterThreshold::Lsb7,
152 0b011 => FastFilterThreshold::Lsb9,
153 0b100 => FastFilterThreshold::Lsb18,
154 0b101 => FastFilterThreshold::Lsb21,
155 0b110 => FastFilterThreshold::Lsb24,
156 0b111 => FastFilterThreshold::Lsb10,
157 _ => FastFilterThreshold::SlowOnly,
158 },
159 watchdog: (hi & 0x20) != 0,
160 })
161 }
162
163 fn set_config(&mut self, config: Configuration) -> Result<(), AS56Error<Self::Error>> {
164 let hi = ((config.watchdog as u8) << 5)
165 | ((config.fast_filter_threshold as u8) << 2)
166 | (config.slow_filter as u8);
167
168 let lo = ((config.pwm_frequency as u8) << 6)
169 | ((config.output_stage as u8) << 4)
170 | ((config.hysteresis as u8) << 2)
171 | (config.power_mode as u8);
172
173 self.write_u8(regs::CONF_HI, hi)?;
174 self.write_u8(regs::CONF_LO, lo)?;
175 Ok(())
176 }
177
178 fn get_zero_position(&mut self) -> Result<u16, AS56Error<Self::Error>> {
179 self.read_u16(regs::ZPOS_HI)
180 }
181
182 fn set_zero_position(&mut self, angle: u16) -> Result<(), AS56Error<Self::Error>> {
183 self.write_u16(regs::ZPOS_HI, angle & 0x0FFF)
184 }
185
186 fn get_max_position(&mut self) -> Result<u16, AS56Error<Self::Error>> {
187 self.read_u16(regs::MPOS_HI)
188 }
189
190 fn set_max_position(&mut self, angle: u16) -> Result<(), AS56Error<Self::Error>> {
191 self.write_u16(regs::MPOS_HI, angle & 0x0FFF)
192 }
193
194 fn get_max_angle(&mut self) -> Result<u16, AS56Error<Self::Error>> {
195 self.read_u16(regs::MANG_HI)
196 }
197
198 fn set_max_angle(&mut self, angle: u16) -> Result<(), AS56Error<Self::Error>> {
199 self.write_u16(regs::MANG_HI, angle & 0x0FFF)
200 }
201}