1use super::{RegisterInterface, SpiDevice, bisync, only_async, only_sync};
2use crate::{DrvError, DrvInterface, DrvLowLevel, FaultStatus};
3use crate::{GateCurrent, OcAdjSet, OcpMode, OctwMode, ShuntAmplifierGain};
4
5#[bisync]
6impl<SpiBus, E> RegisterInterface for DrvInterface<SpiBus>
7where
8 SpiBus: SpiDevice<Error = E>,
9 E: core::fmt::Debug,
10{
11 type AddressType = u8;
12 type Error = DrvError<E>;
13
14 async fn read_register(
15 &mut self,
16 address: u8,
17 _size_bits: u32,
18 data: &mut [u8],
19 ) -> Result<(), Self::Error> {
20 let cmd: u16 = 0x8000 | ((address as u16 & 0x0F) << 11);
22 let cmd_bytes = cmd.to_be_bytes();
23
24 let mut response_bytes = [0u8; 2];
26 self.spi_bus
27 .transfer(&mut response_bytes, &cmd_bytes)
28 .await
29 .map_err(DrvError::Spi)?;
30
31 let mut read_response = [0u8; 2];
33 self.spi_bus
34 .transfer(&mut read_response, &cmd_bytes)
35 .await
36 .map_err(DrvError::Spi)?;
37
38 let response = u16::from_be_bytes(read_response);
39
40 if (response & 0x8000) != 0 {
42 return Err(DrvError::FrameError);
43 }
44
45 let reg_data = response & 0x07FF;
47 if data.len() >= 2 {
48 data[0] = (reg_data >> 8) as u8;
49 data[1] = reg_data as u8;
50 }
51
52 Ok(())
53 }
54
55 async fn write_register(
56 &mut self,
57 address: u8,
58 _size_bits: u32,
59 data: &[u8],
60 ) -> Result<(), Self::Error> {
61 let reg_data = if data.len() >= 2 {
63 ((data[0] as u16) << 8) | (data[1] as u16)
64 } else if data.len() == 1 {
65 data[0] as u16
66 } else {
67 0
68 };
69
70 let cmd: u16 = ((address as u16 & 0x0F) << 11) | (reg_data & 0x07FF);
72 let cmd_bytes = cmd.to_be_bytes();
73
74 let mut response_bytes = [0u8; 2];
76 self.spi_bus
77 .transfer(&mut response_bytes, &cmd_bytes)
78 .await
79 .map_err(DrvError::Spi)?;
80
81 Ok(())
82 }
83}
84
85pub struct Drv8301<
86 SpiImpl: RegisterInterface<AddressType = u8, Error = DrvError<SpiBusErr>>,
87 SpiBusErr: core::fmt::Debug = <SpiImpl as RegisterInterface>::Error,
88> {
89 pub ll: DrvLowLevel<SpiImpl>,
90 _marker: core::marker::PhantomData<SpiBusErr>,
91}
92
93impl<SpiBus, E> Drv8301<DrvInterface<SpiBus>, E>
94where
95 SpiBus: SpiDevice<Error = E>,
96 E: core::fmt::Debug,
97{
98 pub fn new(spi: SpiBus) -> Self {
99 Self {
100 ll: DrvLowLevel::new(DrvInterface::new(spi)),
101 _marker: core::marker::PhantomData,
102 }
103 }
104}
105
106pub trait CurrentDrvDriverInterface<E>:
107 RegisterInterface<AddressType = u8, Error = DrvError<E>>
108{
109}
110
111impl<T, E> CurrentDrvDriverInterface<E> for T
112where
113 T: RegisterInterface<AddressType = u8, Error = DrvError<E>>,
114 E: core::fmt::Debug,
115{
116}
117
118include!("bisync_helpers.rs");
119
120impl<SpiImpl, SpiBusErr> Drv8301<SpiImpl, SpiBusErr>
121where
122 SpiImpl: CurrentDrvDriverInterface<SpiBusErr>,
123 SpiBusErr: core::fmt::Debug,
124{
125 #[bisync]
127 pub async fn has_fault(&mut self) -> Result<bool, DrvError<SpiBusErr>> {
128 let mut op = self.ll.status_register_1();
129 let status = read_internal(&mut op).await?;
130 Ok(status.fault())
131 }
132
133 #[bisync]
135 pub async fn get_device_id(&mut self) -> Result<u8, DrvError<SpiBusErr>> {
136 let mut op = self.ll.status_register_2();
137 let status = read_internal(&mut op).await?;
138 Ok(status.device_id())
139 }
140
141 #[bisync]
161 pub async fn get_fault_status(&mut self) -> Result<FaultStatus, DrvError<SpiBusErr>> {
162 let mut op1 = self.ll.status_register_1();
163 let status1 = read_internal(&mut op1).await?;
164
165 let mut op2 = self.ll.status_register_2();
166 let status2 = read_internal(&mut op2).await?;
167
168 Ok(FaultStatus {
169 fault: status1.fault(),
170 gvdd_uv: status1.gvdd_uv(),
171 gvdd_ov: status2.gvdd_ov(),
172 pvdd_uv: status1.pvdd_uv(),
173 otsd: status1.otsd(),
174 otw: status1.otw(),
175 fetha_oc: status1.fetha_oc(),
176 fetla_oc: status1.fetla_oc(),
177 fethb_oc: status1.fethb_oc(),
178 fetlb_oc: status1.fetlb_oc(),
179 fethc_oc: status1.fethc_oc(),
180 fetlc_oc: status1.fetlc_oc(),
181 })
182 }
183
184 #[bisync]
186 pub async fn set_oc_threshold(
187 &mut self,
188 threshold: OcAdjSet,
189 ) -> Result<(), DrvError<SpiBusErr>> {
190 let mut op = self.ll.control_register_1();
191 modify_internal(&mut op, |r| r.set_oc_adj_set(threshold)).await
192 }
193
194 #[bisync]
196 pub async fn set_ocp_mode(&mut self, mode: OcpMode) -> Result<(), DrvError<SpiBusErr>> {
197 let mut op = self.ll.control_register_1();
198 modify_internal(&mut op, |r| r.set_ocp_mode(mode)).await
199 }
200
201 #[bisync]
203 pub async fn set_pwm_mode(&mut self, three_pwm: bool) -> Result<(), DrvError<SpiBusErr>> {
204 let mut op = self.ll.control_register_1();
205 modify_internal(&mut op, |r| r.set_pwm_mode(three_pwm)).await
206 }
207
208 #[bisync]
210 pub async fn reset_gate_faults(&mut self) -> Result<(), DrvError<SpiBusErr>> {
211 let mut op = self.ll.control_register_1();
212 modify_internal(&mut op, |r| r.set_gate_reset(true)).await
213 }
214
215 #[bisync]
217 pub async fn set_gate_current(
218 &mut self,
219 current: GateCurrent,
220 ) -> Result<(), DrvError<SpiBusErr>> {
221 let mut op = self.ll.control_register_1();
222 modify_internal(&mut op, |r| r.set_gate_current(current)).await
223 }
224
225 #[bisync]
227 pub async fn set_shunt_amplifier_gain(
228 &mut self,
229 gain: ShuntAmplifierGain,
230 ) -> Result<(), DrvError<SpiBusErr>> {
231 let mut op = self.ll.control_register_2();
232 modify_internal(&mut op, |r| r.set_gain(gain)).await
233 }
234
235 #[bisync]
237 pub async fn set_octw_mode(&mut self, mode: OctwMode) -> Result<(), DrvError<SpiBusErr>> {
238 let mut op = self.ll.control_register_2();
239 modify_internal(&mut op, |r| r.set_octw_mode(mode)).await
240 }
241
242 #[bisync]
244 pub async fn set_dc_cal_ch1(&mut self, enable: bool) -> Result<(), DrvError<SpiBusErr>> {
245 let mut op = self.ll.control_register_2();
246 modify_internal(&mut op, |r| r.set_dc_cal_ch1(enable)).await
247 }
248
249 #[bisync]
251 pub async fn set_dc_cal_ch2(&mut self, enable: bool) -> Result<(), DrvError<SpiBusErr>> {
252 let mut op = self.ll.control_register_2();
253 modify_internal(&mut op, |r| r.set_dc_cal_ch2(enable)).await
254 }
255
256 #[bisync]
258 pub async fn set_oc_toff(&mut self, off_time_control: bool) -> Result<(), DrvError<SpiBusErr>> {
259 let mut op = self.ll.control_register_2();
260 modify_internal(&mut op, |r| r.set_oc_toff(off_time_control)).await
261 }
262}