ph_qmi8658/interface/
spi.rs1use embedded_hal_async::spi::{Operation, SpiDevice};
6
7use super::{Interface, InterfaceSettings, sealed};
8use crate::error::Error;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12#[cfg_attr(feature = "defmt", derive(defmt::Format))]
13pub struct SpiConfig {
14 pub(crate) auto_increment: bool,
15 pub(crate) big_endian: bool,
16 pub(crate) three_wire: bool,
17}
18
19impl SpiConfig {
20 pub const fn new() -> Self {
22 Self {
23 auto_increment: true,
24 big_endian: true,
25 three_wire: false,
26 }
27 }
28
29 #[must_use]
31 pub const fn with_auto_increment(mut self, enable: bool) -> Self {
32 self.auto_increment = enable;
33 self
34 }
35
36 #[must_use]
38 pub const fn with_big_endian(mut self, enable: bool) -> Self {
39 self.big_endian = enable;
40 self
41 }
42
43 #[must_use]
45 pub const fn with_three_wire(mut self, enable: bool) -> Self {
46 self.three_wire = enable;
47 self
48 }
49
50 pub(crate) const fn interface_settings(self) -> InterfaceSettings {
51 InterfaceSettings::new(self.auto_increment, self.big_endian, self.three_wire)
52 }
53}
54
55impl Default for SpiConfig {
56 fn default() -> Self {
57 Self::new()
58 }
59}
60
61pub struct SpiInterface<SPI> {
63 spi: SPI,
64}
65
66impl<SPI> SpiInterface<SPI> {
67 pub const fn new(spi: SPI) -> Self {
69 Self { spi }
70 }
71
72 pub fn release(self) -> SPI {
74 self.spi
75 }
76}
77
78const SPI_READ_MASK: u8 = 0x80;
79
80const fn spi_addr_read(reg: u8) -> u8 {
81 (reg & 0x7F) | SPI_READ_MASK
82}
83
84const fn spi_addr_write(reg: u8) -> u8 {
85 reg & 0x7F
86}
87
88impl<SPI> Interface for SpiInterface<SPI>
89where
90 SPI: SpiDevice,
91{
92 async fn read_reg(&mut self, reg: u8) -> Result<u8, Error> {
93 let mut buffer = [0u8];
94 self.read_regs(reg, &mut buffer).await?;
95 Ok(buffer[0])
96 }
97
98 async fn read_regs(&mut self, reg: u8, buffer: &mut [u8]) -> Result<(), Error> {
99 if buffer.is_empty() {
100 return Ok(());
101 }
102 let addr = spi_addr_read(reg);
103 let addr_buf = [addr];
104 let mut ops = [Operation::Write(&addr_buf), Operation::Read(buffer)];
105 self.spi.transaction(&mut ops).await.map_err(|_| Error::Bus)
106 }
107
108 async fn write_reg(&mut self, reg: u8, value: u8) -> Result<(), Error> {
109 let addr = spi_addr_write(reg);
110 let buffer = [addr, value];
111 self.spi.write(&buffer).await.map_err(|_| Error::Bus)
112 }
113
114 async fn write_regs(&mut self, reg: u8, data: &[u8]) -> Result<(), Error> {
115 if data.is_empty() {
116 return Ok(());
117 }
118 let addr = spi_addr_write(reg);
119 let addr_buf = [addr];
120 let mut ops = [Operation::Write(&addr_buf), Operation::Write(data)];
121 self.spi.transaction(&mut ops).await.map_err(|_| Error::Bus)
122 }
123}
124
125impl<SPI> sealed::Sealed for SpiInterface<SPI> {}