@@ -2,32 +2,59 @@ pub mod adafruit_lcd_backpack;
22pub mod dual_hd44780;
33pub mod generic_pcf8574t;
44
5+ use core:: fmt:: Display ;
6+
57use crate :: LcdDisplayType ;
68use embedded_hal:: i2c;
79
810#[ derive( Debug , PartialEq , Copy , Clone ) ]
9- pub enum AdapterError {
11+ pub enum AdapterError < I2C >
12+ where
13+ I2C : i2c:: I2c ,
14+ {
1015 /// The device ID was not recognized
1116 BadDeviceId ,
17+ /// An I2C error occurred
18+ I2CError ( I2C :: Error ) ,
1219}
1320
1421#[ cfg( feature = "defmt" ) ]
15- impl defmt:: Format for AdapterError {
22+ impl < I2C > defmt:: Format for AdapterError < I2C >
23+ where
24+ I2C : i2c:: I2c ,
25+ {
1626 fn format ( & self , fmt : defmt:: Formatter ) {
1727 match self {
1828 AdapterError :: BadDeviceId => defmt:: write!( fmt, "BadDeviceId" ) ,
29+ AdapterError :: I2CError ( _) => defmt:: write!( fmt, "I2CError" ) ,
1930 }
2031 }
2132}
2233
2334#[ cfg( feature = "ufmt" ) ]
24- impl ufmt:: uDisplay for AdapterError {
35+ impl < I2C > ufmt:: uDisplay for AdapterError < I2C >
36+ where
37+ I2C : i2c:: I2c ,
38+ {
2539 fn fmt < W > ( & self , w : & mut ufmt:: Formatter < ' _ , W > ) -> Result < ( ) , W :: Error >
2640 where
2741 W : ufmt:: uWrite + ?Sized ,
2842 {
2943 match self {
3044 AdapterError :: BadDeviceId => ufmt:: uwrite!( w, "BadDeviceId" ) ,
45+ AdapterError :: I2CError ( _) => ufmt:: uwrite!( w, "I2CError" ) ,
46+ }
47+ }
48+ }
49+
50+ impl < I2C > Display for AdapterError < I2C >
51+ where
52+ I2C : i2c:: I2c ,
53+ {
54+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
55+ match self {
56+ AdapterError :: BadDeviceId => write ! ( f, "BadDeviceId" ) ,
57+ AdapterError :: I2CError ( _) => write ! ( f, "I2CError" ) ,
3158 }
3259 }
3360}
@@ -36,28 +63,111 @@ pub trait AdapterConfigTrait<I2C>: Default
3663where
3764 I2C : i2c:: I2c ,
3865{
66+ /// Returns the bitfield value for the adapter
3967 fn bits ( & self ) -> u8 ;
68+
69+ /// Returns the default I2C address for the adapter
4070 fn default_i2c_address ( ) -> u8 ;
4171
72+ /// Determines if reading from device is supported by this adapter
73+ fn supports_reads ( ) -> bool {
74+ false
75+ }
76+
77+ /// Sets the RS pin for the display. A value of `false` indicates an instruction is being sent, while
78+ /// a value of `true` indicates data is being sent.
4279 fn set_rs ( & mut self , value : bool ) ;
80+
81+ /// Sets the RW pin for the display. A value of `false` indicates a write operation, while a value of
82+ /// `true` indicates a read operation. Not all displays support reading, so this method may not be
83+ /// implemented fully.
4384 fn set_rw ( & mut self , value : bool ) ;
85+
4486 /// Sets the enable pin for the given device. Most displays only have one enable pin, so the device
4587 /// parameter is ignored. For displays with two enable pins, the device parameter is used to determine
4688 /// which enable pin to set.
47- fn set_enable ( & mut self , value : bool , device : usize ) -> Result < ( ) , AdapterError > ;
89+ fn set_enable ( & mut self , value : bool , device : usize ) -> Result < ( ) , AdapterError < I2C > > ;
90+
91+ /// Sets the backlight pin for the display. A value of `true` indicates the backlight is on, while a value
92+ /// of `false` indicates the backlight is off.
4893 fn set_backlight ( & mut self , value : bool ) ;
94+
4995 fn set_data ( & mut self , value : u8 ) ;
5096
5197 fn init ( & self , _i2c : & mut I2C , _i2c_address : u8 ) -> Result < ( ) , I2C :: Error > {
5298 Ok ( ( ) )
5399 }
54100
55- fn write_bits_to_gpio ( & self , i2c : & mut I2C , i2c_address : u8 ) -> Result < ( ) , I2C :: Error > {
101+ fn write_bits_to_gpio ( & self , i2c : & mut I2C , i2c_address : u8 ) -> Result < ( ) , AdapterError < I2C > > {
56102 let data = [ self . bits ( ) ] ;
57- i2c. write ( i2c_address, & data) ?;
103+ i2c. write ( i2c_address, & data)
104+ . map_err ( AdapterError :: I2CError ) ?;
105+ Ok ( ( ) )
106+ }
107+
108+ /// writes a full byte to the indicated device. If `rs_setting` is `true`, the data is written to the data register,
109+ /// either the CGRAM or DDRAM, depending on prior command sent. If `rs_setting` is `false`, the data is written to
110+ /// command register.
111+ fn write_byte_to_device (
112+ & mut self ,
113+ i2c : & mut I2C ,
114+ i2c_address : u8 ,
115+ device : usize ,
116+ rs_setting : bool ,
117+ value : u8 ,
118+ ) -> Result < ( ) , AdapterError < I2C > > {
119+ self . write_nibble_to_device ( i2c, i2c_address, device, rs_setting, value >> 4 )
120+ . and_then ( |_| {
121+ self . write_nibble_to_device ( i2c, i2c_address, device, rs_setting, value & 0x0F )
122+ } )
123+ }
124+
125+ /// writes the lower nibble of a `value` byte to the indicated device. Typically only used for device initialization in 4 bit mode.
126+ /// If `rs_setting` is `true`, the data is written to the data register,
127+ /// either the CGRAM or DDRAM, depending on prior command sent. If `rs_setting` is `false`, the data is written to
128+ /// command register.
129+ fn write_nibble_to_device (
130+ & mut self ,
131+ i2c : & mut I2C ,
132+ i2c_address : u8 ,
133+ device : usize ,
134+ rs_setting : bool ,
135+ value : u8 ,
136+ ) -> Result < ( ) , AdapterError < I2C > > {
137+ self . set_rs ( rs_setting) ;
138+ self . set_rw ( false ) ;
139+
140+ // now write the low nibble
141+ self . set_data ( value & 0x0F ) ;
142+ self . set_enable ( true , device) ?;
143+ self . write_bits_to_gpio ( i2c, i2c_address) ?;
144+ self . set_enable ( false , device) ?;
145+ self . write_bits_to_gpio ( i2c, i2c_address) ?;
146+
58147 Ok ( ( ) )
59148 }
60149
150+ /// read bytes from the indicated device. The size of the buffer is the number of bytes to read.
151+ /// What is read depends on the `rs_setting` parameter. If `rs_setting` is `true`, the data is read
152+ /// from the data register, either the CGRAM or DDRAM, depending on prior command sent. If `rs_setting`
153+ /// is `false`, the data is read from the busy flag and address register.
154+ /// Note that while nothing "breaks" passing a buffer size greater than one when `rs_setting` is `false`,
155+ /// the data returned will be the same for each byte read.
156+ fn read_bytes_from_device (
157+ & self ,
158+ _i2c : & mut I2C ,
159+ _i2c_address : u8 ,
160+ _device : usize ,
161+ _rs_setting : bool ,
162+ _buffer : & mut [ u8 ] ,
163+ ) -> Result < ( ) , AdapterError < I2C > > {
164+ unimplemented ! ( "Reads are not supported for device" ) ;
165+ }
166+
167+ fn is_busy ( & self , _i2c : & mut I2C , _i2c_address : u8 ) -> Result < bool , AdapterError < I2C > > {
168+ Ok ( false )
169+ }
170+
61171 fn device_count ( & self ) -> usize {
62172 1
63173 }
0 commit comments