1use embedded_hal::spi::SpiDevice;
6
7use crate::{
8 ActuatorStatus, CntCfg, CntCount, CntSetup, DeviceStatus, ErrorStatus, FullDeviceStatus,
9 PinStatus, WarningStatus,
10 dd::{Device, DeviceError, DeviceInterface},
11};
12
13#[derive(Debug)]
19pub struct IcMd<Spi> {
20 pub device: Device<DeviceInterface<Spi>>,
22 counter_config: CntCfg,
24 device_status: DeviceStatus,
27 actuator_status: ActuatorStatus,
28}
29
30impl<Spi: SpiDevice> IcMd<Spi> {
31 pub fn new(spi: Spi) -> Self {
34 Self {
35 device: Device::new(DeviceInterface::new(spi)),
36 counter_config: CntCfg::Cnt1Bit48(CntSetup::default()),
37 actuator_status: ActuatorStatus::default(),
38 device_status: DeviceStatus::default(),
39 }
40 }
41
42 pub fn init(&mut self) -> Result<(), DeviceError<Spi::Error>> {
44 self.device
45 .counter_configuration()
46 .write(|reg| reg.set_value(self.counter_config.into()))?;
47
48 Ok(())
49 }
50
51 pub fn configure_actuator_pins(
60 &mut self,
61 act0: &PinStatus,
62 act1: &PinStatus,
63 ) -> Result<(), DeviceError<Spi::Error>> {
64 self.device.instruction_byte().write(|reg| {
65 reg.set_act_0(act0.into());
66 reg.set_act_1(act1.into());
67 })?;
68 self.actuator_status.act0 = *act0;
69 self.actuator_status.act1 = *act1;
70 Ok(())
71 }
72
73 pub fn get_device_status(&self) -> DeviceStatus {
77 self.device_status
78 }
79
80 pub fn get_full_device_status(&mut self) -> Result<FullDeviceStatus, DeviceError<Spi::Error>> {
84 let status0 = self.device.status_0().read()?;
85 let status1 = self.device.status_1().read()?;
86 let status2 = self.device.status_2().read()?;
87
88 Ok(FullDeviceStatus {
89 cnt0_overflow: status0.ovf_0().into(),
90 cnt0_aberr: status0.ab_err_0().into(),
91 cnt0_zero: status0.zero_0().into(),
92 cnt1_overflow: status1.ovf_1().into(),
93 cnt1_aberr: status1.ab_err_1().into(),
94 cnt1_zero: status1.zero_1().into(),
95 cnt2_overflow: status2.ovf_2().into(),
96 cnt2_aberr: status2.ab_err_2().into(),
97 cnt2_zero: status2.zero_2().into(),
98 power_status: status0.p_dwn().into(),
99 ref_reg_status: status0.r_val().into(),
100 upd_reg_status: status0.upd_val().into(),
101 ref_cnt_status: status0.ovf_ref().into(),
102 ext_err_status: status1.ext_err().into(),
103 ext_warn_status: status1.ext_warn().into(),
104 comm_status: status1.com_col().into(),
105 tp_status: status0.tp_val().into(),
106 tpi_status: status1.tps().into(),
107 ssi_enabled: status2.en_ssi().into(),
108 })
109 }
110
111 pub fn read_counter(&mut self) -> Result<CntCount, DeviceError<Spi::Error>> {
113 match self.counter_config {
114 CntCfg::Cnt1Bit24(_) => {
115 let res = self.device.read_cnt_cfg_0().read()?;
116 self.set_device_status(res.nwarn(), res.nerr());
117 Ok(CntCount::Cnt1Bit24(res.cnt_0()))
118 }
119 CntCfg::Cnt2Bit24(_, _) => {
120 let res = self.device.read_cnt_cfg_1().read()?;
121 self.set_device_status(res.nwarn(), res.nerr());
122 Ok(CntCount::Cnt2Bit24(res.cnt_0(), res.cnt_1()))
123 }
124 CntCfg::Cnt1Bit48(_) => {
125 let res = self.device.read_cnt_cfg_2().read()?;
126 self.set_device_status(res.nwarn(), res.nerr());
127 Ok(CntCount::Cnt1Bit48(res.cnt_0()))
128 }
129 CntCfg::Cnt1Bit16(_) => {
130 let res = self.device.read_cnt_cfg_3().read()?;
131 self.set_device_status(res.nwarn(), res.nerr());
132 Ok(CntCount::Cnt1Bit16(res.cnt_0()))
133 }
134 CntCfg::Cnt1Bit32(_) => {
135 let res = self.device.read_cnt_cfg_4().read()?;
136 self.set_device_status(res.nwarn(), res.nerr());
137 Ok(CntCount::Cnt1Bit32(res.cnt_0()))
138 }
139 CntCfg::Cnt2Bit32Bit16(_, _) => {
140 let res = self.device.read_cnt_cfg_5().read()?;
141 self.set_device_status(res.nwarn(), res.nerr());
142 Ok(CntCount::Cnt2Bit32Bit16(res.cnt_0(), res.cnt_1()))
143 }
144 CntCfg::Cnt2Bit16(_, _) => {
145 let res = self.device.read_cnt_cfg_6().read()?;
146 self.set_device_status(res.nwarn(), res.nerr());
147 Ok(CntCount::Cnt2Bit16(res.cnt_0(), res.cnt_1()))
148 }
149 CntCfg::Cnt3Bit16(_, _, _) => {
150 let res = self.device.read_cnt_cfg_7().read()?;
151 self.set_device_status(res.nwarn(), res.nerr());
152 Ok(CntCount::Cnt3Bit16(res.cnt_0(), res.cnt_1(), res.cnt_2()))
153 }
154 }
155 }
156
157 pub fn reset_counters(
165 &mut self,
166 cnt0: bool,
167 cnt1: bool,
168 cnt2: bool,
169 ) -> Result<(), DeviceError<Spi::Error>> {
170 let act0 = &self.actuator_status.act0;
171 let act1 = &self.actuator_status.act1;
172 self.device.instruction_byte().write(|reg| {
173 reg.set_ab_res_0(cnt0);
174 reg.set_ab_res_1(cnt1);
175 reg.set_ab_res_2(cnt2);
176 reg.set_act_0(act0.into());
177 reg.set_act_1(act1.into());
178 })?;
179 Ok(())
180 }
181
182 pub fn reset_all_counters(&mut self) -> Result<(), DeviceError<Spi::Error>> {
185 self.reset_counters(true, true, true)?;
186 Ok(())
187 }
188
189 pub fn touch_probe_instruction(&mut self) -> Result<(), DeviceError<Spi::Error>> {
192 let act0 = &self.actuator_status.act0;
193 let act1 = &self.actuator_status.act1;
194 self.device.instruction_byte().write(|reg| {
195 reg.set_tp(true);
196 reg.set_act_0(act0.into());
197 reg.set_act_1(act1.into());
198 })?;
199 Ok(())
200 }
201
202 pub fn set_counter_config(&mut self, config: CntCfg) {
205 self.counter_config = config;
206 }
207
208 fn set_device_status(&mut self, nwarn: bool, nerr: bool) {
211 self.device_status.warning = match nwarn {
212 true => WarningStatus::Ok,
213 false => WarningStatus::Warning,
214 };
215 self.device_status.error = match nerr {
216 true => ErrorStatus::Ok,
217 false => ErrorStatus::Error,
218 };
219 }
220}