embedded_nrf24l01_async/
device.rs

1use crate::command::Command;
2use crate::registers::{Config, Register, Status};
3
4/// Trait that hides all the GPIO/SPI type parameters for use by the
5/// operation modes
6pub trait Device {
7    /// Error from the SPI implementation
8    type Error;
9
10    /// Set CE pin high
11    fn ce_enable(&mut self);
12    /// Set CE pin low
13    fn ce_disable(&mut self);
14    /// Helper; the receiving during RX and sending during TX require `CE`
15    /// to be low.
16    fn with_ce_disabled<F, R>(&mut self, f: F) -> R
17    where
18        F: FnOnce(&mut Self) -> R,
19    {
20        self.ce_disable();
21        let r = f(self);
22        self.ce_enable();
23        r
24    }
25
26    /// Send a command via SPI
27    async fn send_command<C: Command>(&mut self, command: &C) -> Result<(Status, C::Response), Self::Error>;
28    /// Send `W_REGISTER` command
29    async fn write_register<R: Register>(&mut self, register: R) -> Result<Status, Self::Error>;
30    /// Send `R_REGISTER` command
31    async fn read_register<R: Register>(&mut self) -> Result<(Status, R), Self::Error>;
32
33    /// Read, and modify a register, and write it back if it has been changed.
34    async fn update_register<Reg, F, R>(&mut self, f: F) -> Result<R, Self::Error>
35    where
36        Reg: Register + PartialEq + Clone,
37        F: FnOnce(&mut Reg) -> R,
38    {
39        // Use `update_config()` for `registers::Config`
40        assert_ne!(Reg::addr(), 0x00);
41
42        let (_, old_register) = self.read_register::<Reg>().await?;
43        let mut register = old_register.clone();
44        let result = f(&mut register);
45
46        if register != old_register {
47            self.write_register(register).await?;
48        }
49        Ok(result)
50    }
51
52    /// Modify the (cached) `CONFIG` register and write if it has changed.
53    async fn update_config<F, R>(&mut self, f: F) -> Result<R, Self::Error>
54    where
55        F: FnOnce(&mut Config) -> R;
56}