Skip to main content

display_driver/bus/
simple.rs

1use super::*;
2
3#[allow(async_fn_in_trait)]
4/// A simplified interface for display buses that don't need atomic command with params, complex
5/// frame control, ROI information, etc. (e.g., standard SPI, I2C).
6///
7/// This trait abstracts over simple serial interfaces where commands and data are just streams of
8/// bytes. It provides a convenient way to implement the full [`DisplayBus`] trait without worrying
9/// about frame metadata or pixel-specific handling, as those are handled by the blanket 
10/// implementation.
11///
12/// Implementors only need to define how to send raw command bytes and raw data bytes.
13pub trait SimpleDisplayBus: ErrorType {
14    /// Writes a sequence of commands to the bus.
15    ///
16    /// This is typically used for sending register addresses or command opcodes.
17    async fn write_cmds(&mut self, cmd: &[u8]) -> Result<(), Self::Error>;
18
19    /// Writes a sequence of data bytes to the bus.
20    ///
21    /// This is used for sending command parameters or pixel data.
22    async fn write_data(&mut self, data: &[u8]) -> Result<(), Self::Error>;
23
24    /// Writes a command followed immediately by its parameters.
25    async fn write_cmd_with_params(
26        &mut self,
27        cmd: &[u8],
28        params: &[u8],
29    ) -> Result<(), Self::Error> {
30        self.write_cmds(cmd).await?;
31        self.write_data(params).await
32    }
33
34    /// Reset the screen via the bus (optional).
35    ///
36    /// Note: This method should only be implemented if the hardware has a physical Reset pin.
37    /// Avoid adding a Pin field to your `DisplayBus` wrapper for this purpose; use `LCDResetOption` 
38    /// instead.
39    fn set_reset(&mut self, reset: bool) -> Result<(), DisplayError<Self::Error>> {
40        let _ = reset;
41        Err(DisplayError::Unsupported)
42    }
43}
44
45impl<T: SimpleDisplayBus> BusBytesIo for T {
46    async fn write_cmd_bytes(&mut self, cmd: &[u8]) -> Result<(), Self::Error> {
47        T::write_cmd(self, cmd).await
48    }
49
50    async fn write_data_bytes(&mut self, data: &[u8]) -> Result<(), Self::Error> {
51        T::write_data(self, data).await
52    }
53}
54
55impl<T: SimpleDisplayBus> DisplayBus for T {
56    async fn write_cmd(&mut self, cmd: &[u8]) -> Result<(), Self::Error> {
57        T::write_cmds(self, cmd).await
58    }
59
60    async fn write_cmd_with_params(
61        &mut self,
62        cmd: &[u8],
63        params: &[u8],
64    ) -> Result<(), Self::Error> {
65        T::write_cmd_with_params(self, cmd, params).await
66    }
67
68    async fn write_pixels(
69        &mut self,
70        cmd: &[u8],
71        data: &[u8],
72        _metadata: Metadata,
73    ) -> Result<(), DisplayError<Self::Error>> {
74        T::write_cmd_with_params(self, cmd, data)
75            .await
76            .map_err(DisplayError::BusError)
77    }
78
79    fn set_reset(&mut self, reset: bool) -> Result<(), DisplayError<Self::Error>> {
80        T::set_reset(self, reset)
81    }
82}