1use embedded_hal_async::spi::SpiDevice;
6
7use crate::{
8 ActuatorStatus, CntCfg, CntCount, CntSetup, DeviceStatus, ErrorStatus, FullDeviceStatus,
9 PinStatus, WarningStatus,
10 dd::{Device, DeviceError, DeviceInterfaceAsync},
11};
12
13#[derive(Debug)]
20pub struct IcMdAsync<Spi> {
21 pub device: Device<DeviceInterfaceAsync<Spi>>,
23 counter_config: CntCfg,
25 device_status: DeviceStatus,
28 actuator_status: ActuatorStatus,
29}
30
31impl<Spi: SpiDevice> IcMdAsync<Spi> {
32 pub fn new(spi: Spi) -> Self {
35 Self {
36 device: Device::new(DeviceInterfaceAsync::new(spi)),
37 counter_config: CntCfg::Cnt1Bit48(CntSetup::default()),
38 actuator_status: ActuatorStatus::default(),
39 device_status: DeviceStatus::default(),
40 }
41 }
42
43 pub async fn init(&mut self) -> Result<(), DeviceError<Spi::Error>> {
45 self.device
46 .counter_configuration()
47 .write_async(|reg| reg.set_value(self.counter_config.into()))
48 .await?;
49
50 Ok(())
51 }
52
53 pub async fn configure_actuator_pins(
62 &mut self,
63 act0: &PinStatus,
64 act1: &PinStatus,
65 ) -> Result<(), DeviceError<Spi::Error>> {
66 self.device
67 .instruction_byte()
68 .write_async(|reg| {
69 reg.set_act_0(act0.into());
70 reg.set_act_1(act1.into());
71 })
72 .await?;
73 self.actuator_status.act0 = *act0;
74 self.actuator_status.act1 = *act1;
75 Ok(())
76 }
77
78 pub fn get_device_status(&self) -> DeviceStatus {
82 self.device_status
83 }
84
85 pub async fn get_full_device_status(
89 &mut self,
90 ) -> Result<FullDeviceStatus, DeviceError<Spi::Error>> {
91 let status0 = self.device.status_0().read_async().await?;
92 let status1 = self.device.status_1().read_async().await?;
93 let status2 = self.device.status_2().read_async().await?;
94
95 Ok(FullDeviceStatus {
96 cnt0_overflow: status0.ovf_0().into(),
97 cnt0_aberr: status0.ab_err_0().into(),
98 cnt0_zero: status0.zero_0().into(),
99 cnt1_overflow: status1.ovf_1().into(),
100 cnt1_aberr: status1.ab_err_1().into(),
101 cnt1_zero: status1.zero_1().into(),
102 cnt2_overflow: status2.ovf_2().into(),
103 cnt2_aberr: status2.ab_err_2().into(),
104 cnt2_zero: status2.zero_2().into(),
105 power_status: status0.p_dwn().into(),
106 ref_reg_status: status0.r_val().into(),
107 upd_reg_status: status0.upd_val().into(),
108 ref_cnt_status: status0.ovf_ref().into(),
109 ext_err_status: status1.ext_err().into(),
110 ext_warn_status: status1.ext_warn().into(),
111 comm_status: status1.com_col().into(),
112 tp_status: status0.tp_val().into(),
113 tpi_status: status1.tps().into(),
114 ssi_enabled: status2.en_ssi().into(),
115 })
116 }
117
118 pub async fn read_counter(&mut self) -> Result<CntCount, DeviceError<Spi::Error>> {
120 match self.counter_config {
121 CntCfg::Cnt1Bit24(_) => {
122 let res = self.device.read_cnt_cfg_0().read_async().await?;
123 self.set_device_status(res.nwarn(), res.nerr());
124 Ok(CntCount::Cnt1Bit24(res.cnt_0()))
125 }
126 CntCfg::Cnt2Bit24(_, _) => {
127 let res = self.device.read_cnt_cfg_1().read_async().await?;
128 self.set_device_status(res.nwarn(), res.nerr());
129 Ok(CntCount::Cnt2Bit24(res.cnt_0(), res.cnt_1()))
130 }
131 CntCfg::Cnt1Bit48(_) => {
132 let res = self.device.read_cnt_cfg_2().read_async().await?;
133 self.set_device_status(res.nwarn(), res.nerr());
134 Ok(CntCount::Cnt1Bit48(res.cnt_0()))
135 }
136 CntCfg::Cnt1Bit16(_) => {
137 let res = self.device.read_cnt_cfg_3().read_async().await?;
138 self.set_device_status(res.nwarn(), res.nerr());
139 Ok(CntCount::Cnt1Bit16(res.cnt_0()))
140 }
141 CntCfg::Cnt1Bit32(_) => {
142 let res = self.device.read_cnt_cfg_4().read_async().await?;
143 self.set_device_status(res.nwarn(), res.nerr());
144 Ok(CntCount::Cnt1Bit32(res.cnt_0()))
145 }
146 CntCfg::Cnt2Bit32Bit16(_, _) => {
147 let res = self.device.read_cnt_cfg_5().read_async().await?;
148 self.set_device_status(res.nwarn(), res.nerr());
149 Ok(CntCount::Cnt2Bit32Bit16(res.cnt_0(), res.cnt_1()))
150 }
151 CntCfg::Cnt2Bit16(_, _) => {
152 let res = self.device.read_cnt_cfg_6().read_async().await?;
153 self.set_device_status(res.nwarn(), res.nerr());
154 Ok(CntCount::Cnt2Bit16(res.cnt_0(), res.cnt_1()))
155 }
156 CntCfg::Cnt3Bit16(_, _, _) => {
157 let res = self.device.read_cnt_cfg_7().read_async().await?;
158 self.set_device_status(res.nwarn(), res.nerr());
159 Ok(CntCount::Cnt3Bit16(res.cnt_0(), res.cnt_1(), res.cnt_2()))
160 }
161 }
162 }
163
164 pub async fn reset_counters(
172 &mut self,
173 cnt0: bool,
174 cnt1: bool,
175 cnt2: bool,
176 ) -> Result<(), DeviceError<Spi::Error>> {
177 let act0 = &self.actuator_status.act0;
178 let act1 = &self.actuator_status.act1;
179 self.device
180 .instruction_byte()
181 .write_async(|reg| {
182 reg.set_ab_res_0(cnt0);
183 reg.set_ab_res_1(cnt1);
184 reg.set_ab_res_2(cnt2);
185 reg.set_act_0(act0.into());
186 reg.set_act_1(act1.into());
187 })
188 .await?;
189 Ok(())
190 }
191
192 pub async fn reset_all_counters(&mut self) -> Result<(), DeviceError<Spi::Error>> {
195 self.reset_counters(true, true, true).await?;
196 Ok(())
197 }
198
199 pub async fn touch_probe_instruction(&mut self) -> Result<(), DeviceError<Spi::Error>> {
202 let act0 = &self.actuator_status.act0;
203 let act1 = &self.actuator_status.act1;
204 self.device
205 .instruction_byte()
206 .write_async(|reg| {
207 reg.set_tp(true);
208 reg.set_act_0(act0.into());
209 reg.set_act_1(act1.into());
210 })
211 .await?;
212 Ok(())
213 }
214
215 pub fn set_counter_config(&mut self, config: CntCfg) {
218 self.counter_config = config;
219 }
220
221 fn set_device_status(&mut self, nwarn: bool, nerr: bool) {
224 self.device_status.warning = match nwarn {
225 true => WarningStatus::Ok,
226 false => WarningStatus::Warning,
227 };
228 self.device_status.error = match nerr {
229 true => ErrorStatus::Ok,
230 false => ErrorStatus::Error,
231 };
232 }
233}