1#[cfg(feature = "async")]
4use core::future::Future;
5#[cfg(feature = "sync")]
6use embedded_hal::delay::DelayNs;
7#[cfg(feature = "sync")]
8use embedded_hal::spi::SpiDevice;
9#[cfg(feature = "async")]
10use embedded_hal_async::delay::DelayNs as AsyncDelayNs;
11#[cfg(feature = "async")]
12use embedded_hal_async::spi::SpiDevice as AsyncSpiDevice;
13
14#[cfg(feature = "async")]
15use super::{AsyncBME280Common, AsyncInterface};
16#[cfg(feature = "sync")]
17use super::{BME280Common, Interface};
18use super::{
19 Configuration, Error, IIRFilter, Measurements, Oversampling, BME280_H_CALIB_DATA_LEN,
20 BME280_P_T_CALIB_DATA_LEN, BME280_P_T_H_DATA_LEN,
21};
22
23#[maybe_async_cfg::maybe(
25 sync(
26 feature = "sync",
27 self = "BME280",
28 idents(
29 AsyncBME280Common(sync = "BME280Common"),
30 AsyncSPIInterface(sync = "SPIInterface"),
31 )
32 ),
33 async(feature = "async", keep_self)
34)]
35#[derive(Debug, Default)]
36pub struct AsyncBME280<SPI> {
37 common: AsyncBME280Common<AsyncSPIInterface<SPI>>,
38}
39
40#[maybe_async_cfg::maybe(
41 sync(
42 feature = "sync",
43 self = "BME280",
44 idents(
45 AsyncSpiDevice(sync = "SpiDevice"),
46 AsyncSpiBus(sync = "SpiBus"),
47 AsyncSPIInterface(sync = "SPIInterface"),
48 AsyncDelayNs(sync = "DelayNs"),
49 AsyncBME280Common(sync = "BME280Common"),
50 )
51 ),
52 async(feature = "async", keep_self)
53)]
54impl<SPI, SPIE> AsyncBME280<SPI>
55where
56 SPI: AsyncSpiDevice<Error = SPIE>,
57 {
59 pub fn new(spi: SPI) -> Result<Self, Error<SPIError<SPIE>>> {
61 Ok(Self {
62 common: AsyncBME280Common {
63 interface: AsyncSPIInterface { spi },
64 calibration: None,
65 },
66 })
67 }
68
69 pub async fn init<D: AsyncDelayNs>(
73 &mut self,
74 delay: &mut D,
75 ) -> Result<(), Error<SPIError<SPIE>>> {
76 self.common
77 .init(
78 delay,
79 Configuration::default()
80 .with_humidity_oversampling(Oversampling::Oversampling1X)
81 .with_pressure_oversampling(Oversampling::Oversampling16X)
82 .with_temperature_oversampling(Oversampling::Oversampling2X)
83 .with_iir_filter(IIRFilter::Coefficient16),
84 )
85 .await
86 }
87
88 pub async fn init_with_config<D: AsyncDelayNs>(
90 &mut self,
91 delay: &mut D,
92 config: Configuration,
93 ) -> Result<(), Error<SPIError<SPIE>>> {
94 self.common.init(delay, config).await
95 }
96
97 pub async fn measure<D: AsyncDelayNs>(
99 &mut self,
100 delay: &mut D,
101 ) -> Result<Measurements<SPIError<SPIE>>, Error<SPIError<SPIE>>> {
102 self.common.measure(delay).await
103 }
104}
105
106#[maybe_async_cfg::maybe(
108 sync(feature = "sync", self = "SPIInterface",),
109 async(feature = "async", keep_self)
110)]
111#[derive(Debug, Default)]
112struct AsyncSPIInterface<SPI> {
113 spi: SPI,
115}
116
117#[cfg(feature = "sync")]
118impl<SPI> Interface for SPIInterface<SPI>
119where
120 SPI: SpiDevice,
121 {
123 type Error = SPIError<SPI::Error>;
124
125 fn read_register(&mut self, register: u8) -> Result<u8, Error<Self::Error>> {
126 let mut result = [0u8];
127 self.read_any_register(register, &mut result)?;
128 Ok(result[0])
129 }
130
131 fn read_data(
132 &mut self,
133 register: u8,
134 ) -> Result<[u8; BME280_P_T_H_DATA_LEN], Error<Self::Error>> {
135 let mut data = [0; BME280_P_T_H_DATA_LEN];
136 self.read_any_register(register, &mut data)?;
137 Ok(data)
138 }
139
140 fn read_pt_calib_data(
141 &mut self,
142 register: u8,
143 ) -> Result<[u8; BME280_P_T_CALIB_DATA_LEN], Error<Self::Error>> {
144 let mut data = [0; BME280_P_T_CALIB_DATA_LEN];
145 self.read_any_register(register, &mut data)?;
146 Ok(data)
147 }
148
149 fn read_h_calib_data(
150 &mut self,
151 register: u8,
152 ) -> Result<[u8; BME280_H_CALIB_DATA_LEN], Error<Self::Error>> {
153 let mut data = [0; BME280_H_CALIB_DATA_LEN];
154 self.read_any_register(register, &mut data)?;
155 Ok(data)
156 }
157
158 fn write_register(&mut self, register: u8, payload: u8) -> Result<(), Error<Self::Error>> {
159 let transfer = [register & 0x7f, payload];
161 self.spi
162 .transfer(&mut [], &transfer)
163 .map_err(|e| Error::Bus(SPIError::SPI(e)))?;
164 Ok(())
165 }
166}
167
168#[cfg(feature = "async")]
169impl<SPI> AsyncInterface for AsyncSPIInterface<SPI>
170where
171 SPI: AsyncSpiDevice,
172 {
174 type Error = SPIError<SPI::Error>;
175
176 type ReadRegisterFuture<'a> = impl Future<Output = Result<u8, Error<Self::Error>>>
177 where
178 SPI: 'a;
179 fn read_register(&mut self, register: u8) -> Self::ReadRegisterFuture<'_> {
180 async move {
181 let mut result = [0u8];
182 self.read_any_register(register, &mut result).await?;
183 Ok(result[0])
184 }
185 }
186
187 type ReadDataFuture<'a> = impl Future<Output = Result<[u8; BME280_P_T_H_DATA_LEN], Error<Self::Error>>>
188 where
189 SPI: 'a;
190 fn read_data(&mut self, register: u8) -> Self::ReadDataFuture<'_> {
191 async move {
192 let mut data = [0; BME280_P_T_H_DATA_LEN];
193 self.read_any_register(register, &mut data).await?;
194 Ok(data)
195 }
196 }
197
198 type ReadPtCalibDataFuture<'a> = impl Future<Output = Result<[u8; BME280_P_T_CALIB_DATA_LEN], Error<Self::Error>>>
199 where
200 SPI: 'a;
201 fn read_pt_calib_data(&mut self, register: u8) -> Self::ReadPtCalibDataFuture<'_> {
202 async move {
203 let mut data = [0; BME280_P_T_CALIB_DATA_LEN];
204 self.read_any_register(register, &mut data).await?;
205 Ok(data)
206 }
207 }
208
209 type ReadHCalibDataFuture<'a> = impl Future<Output = Result<[u8; BME280_H_CALIB_DATA_LEN], Error<Self::Error>>>
210 where
211 SPI: 'a;
212 fn read_h_calib_data(&mut self, register: u8) -> Self::ReadHCalibDataFuture<'_> {
213 async move {
214 let mut data = [0; BME280_H_CALIB_DATA_LEN];
215 self.read_any_register(register, &mut data).await?;
216 Ok(data)
217 }
218 }
219
220 type WriteRegisterFuture<'a> = impl Future<Output = Result<(), Error<Self::Error>>>
221 where
222 SPI: 'a;
223 fn write_register(&mut self, register: u8, payload: u8) -> Self::WriteRegisterFuture<'_> {
224 async move {
225 let transfer = [register & 0x7f, payload];
227 self.spi
228 .transfer(&mut [], &transfer)
229 .await
230 .map_err(|e| Error::Bus(SPIError::SPI(e)))?;
231 Ok(())
232 }
233 }
234}
235
236#[maybe_async_cfg::maybe(
237 sync(
238 feature = "sync",
239 self = "SPIInterface",
240 idents(AsyncSpiDevice(sync = "SpiDevice"), AsyncSpiBus(sync = "SpiBus"),)
241 ),
242 async(feature = "async", keep_self)
243)]
244impl<SPI> AsyncSPIInterface<SPI>
245where
246 SPI: AsyncSpiDevice,
247 {
249 async fn read_any_register(
250 &mut self,
251 register: u8,
252 data: &mut [u8],
253 ) -> Result<(), Error<SPIError<SPI::Error>>> {
254 self.spi
255 .transfer(data, &[register])
256 .await
257 .map_err(|e| Error::Bus(SPIError::SPI(e)))?;
258 Ok(())
259 }
260}
261
262#[derive(Clone, Copy, Debug)]
264pub enum SPIError<SPIE> {
265 SPI(SPIE),
267}