#![no_std]
#![deny(missing_docs)]
mod address;
pub use address::DeviceAddr;
mod protocol;
mod types;
pub use types::{Async, Blocking, ClientType};
use protocol::Packet;
pub use types::{DeviceType, FS3000_1005, FS3000_1015};
pub mod prelude {
pub use crate::types::{FS3000_1005, FS3000_1015};
pub use crate::{Async, Blocking, DeviceAddr, FS3000};
}
#[derive(Debug, thiserror::Error)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error<I2CError> {
#[error("Checksum validation failed")]
ChecksumFailed,
#[error("I2C Error: {0:?}")]
I2C(I2CError),
}
pub struct FS3000<Device: DeviceType, Client: ClientType, I2C> {
address: DeviceAddr,
i2c: I2C,
_client: core::marker::PhantomData<Client>,
_state: core::marker::PhantomData<Device>,
}
impl<Device: DeviceType, I2C> FS3000<Device, Blocking, I2C>
where
I2C: embedded_hal::i2c::I2c,
{
pub fn new(address: DeviceAddr, i2c: I2C) -> Self {
Self {
i2c,
address,
_client: core::marker::PhantomData,
_state: core::marker::PhantomData,
}
}
pub fn read_meters_per_second(&mut self) -> Result<f32, Error<I2C::Error>> {
let measurement = self.read_raw()?;
Ok(protocol::raw_to_meters_per_second::<Device>(measurement))
}
pub fn read_raw(&mut self) -> Result<u16, Error<I2C::Error>> {
let mut packet = Packet([0; 5]);
self.i2c
.read(self.address.into(), &mut packet.0)
.map_err(Error::<I2C::Error>::I2C)?;
if !packet.valid() {
return Err(Error::ChecksumFailed);
}
Ok(packet.measurement())
}
}
impl<Device: DeviceType, I2C> FS3000<Device, Async, I2C>
where
I2C: embedded_hal_async::i2c::I2c,
{
pub fn new(address: DeviceAddr, i2c: I2C) -> Self {
Self {
i2c,
address,
_client: core::marker::PhantomData,
_state: core::marker::PhantomData,
}
}
pub async fn read_meters_per_second(&mut self) -> Result<f32, Error<I2C::Error>> {
let measurement = self.read_raw().await?;
Ok(protocol::raw_to_meters_per_second::<Device>(measurement))
}
pub async fn read_raw(&mut self) -> Result<u16, Error<I2C::Error>> {
let mut packet = Packet([0; 5]);
self.i2c
.read(self.address.into(), &mut packet.0)
.await
.map_err(Error::<I2C::Error>::I2C)?;
if !packet.valid() {
return Err(Error::ChecksumFailed);
}
Ok(packet.measurement())
}
}