1+ use embedded_hal:: i2c:: { NoAcknowledgeSource , Operation } ;
2+
13use crate :: time:: Hertz ;
24use crate :: traits:: wg:: blocking:: i2c:: { Read , Write , WriteRead } ;
5+ use crate :: traits:: wg1:: i2c:: { Error as ErrorTrait , ErrorType , I2c as I2cTrait } ;
36use crate :: typestates:: pin:: {
47 flexcomm:: {
58 // Trait marking I2C peripherals and pins
@@ -33,6 +36,29 @@ pub enum Error {
3336 StartStop ,
3437}
3538
39+ impl ErrorTrait for Error {
40+ fn kind ( & self ) -> embedded_hal:: i2c:: ErrorKind {
41+ use embedded_hal:: i2c:: ErrorKind ;
42+ match self {
43+ Self :: Bus => ErrorKind :: Bus ,
44+ Self :: ArbitrationLoss => ErrorKind :: ArbitrationLoss ,
45+ Self :: NackAddress => ErrorKind :: NoAcknowledge ( NoAcknowledgeSource :: Address ) ,
46+ Self :: NackData => ErrorKind :: NoAcknowledge ( NoAcknowledgeSource :: Data ) ,
47+ Self :: StartStop => ErrorKind :: Other ,
48+ }
49+ }
50+ }
51+
52+ impl < PIO1 , PIO2 , I2C , PINS > ErrorType for I2cMaster < PIO1 , PIO2 , I2C , PINS >
53+ where
54+ PIO1 : PinId ,
55+ PIO2 : PinId ,
56+ I2C : I2c ,
57+ PINS : I2cPins < PIO1 , PIO2 , I2C > ,
58+ {
59+ type Error = Error ;
60+ }
61+
3662pub type Result < T > = core:: result:: Result < T , Error > ;
3763
3864// TODO: Parametrize with Master/Slave MODE
@@ -153,27 +179,7 @@ where
153179 Ok ( ( ) )
154180 }
155181
156- fn write_without_stop ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) > {
157- self . return_on_error ( ) ?;
158-
159- // Write the slave address with the RW bit set to 0 to the master data register MSTDAT.
160- self . i2c
161- . mstdat
162- . modify ( |_, w| unsafe { w. data ( ) . bits ( addr << 1 ) } ) ;
163- // Start the transmission by setting the MSTSTART bit to 1 in the master control register.
164- self . i2c . mstctl . write ( |w| w. mststart ( ) . start ( ) ) ;
165- // Wait for the pending status to be set (MSTPENDING = 1) by polling the STAT register
166- // TODO: Consider implementing a timeout (loop at most N times...) :TODO
167- while self . i2c . stat . read ( ) . mstpending ( ) . is_in_progress ( ) {
168- continue ;
169- }
170-
171- self . return_on_error ( ) ?;
172- if !self . i2c . stat . read ( ) . mststate ( ) . is_transmit_ready ( ) {
173- // dbg!(Error::Bus);
174- return Err ( Error :: Bus ) ;
175- }
176-
182+ fn write_inner_bytes ( & mut self , bytes : & [ u8 ] ) -> Result < ( ) > {
177183 // Send bytes
178184 for byte in bytes {
179185 // write a byte
@@ -194,6 +200,35 @@ where
194200 return Err ( Error :: Bus ) ;
195201 }
196202 }
203+ Ok ( ( ) )
204+ }
205+
206+ fn start_write ( & mut self , addr : u8 ) -> Result < ( ) > {
207+ self . return_on_error ( ) ?;
208+
209+ // Write the slave address with the RW bit set to 0 to the master data register MSTDAT.
210+ self . i2c
211+ . mstdat
212+ . modify ( |_, w| unsafe { w. data ( ) . bits ( addr << 1 ) } ) ;
213+ // Start the transmission by setting the MSTSTART bit to 1 in the master control register.
214+ self . i2c . mstctl . write ( |w| w. mststart ( ) . start ( ) ) ;
215+ // Wait for the pending status to be set (MSTPENDING = 1) by polling the STAT register
216+ // TODO: Consider implementing a timeout (loop at most N times...) :TODO
217+ while self . i2c . stat . read ( ) . mstpending ( ) . is_in_progress ( ) {
218+ continue ;
219+ }
220+
221+ self . return_on_error ( ) ?;
222+ if !self . i2c . stat . read ( ) . mststate ( ) . is_transmit_ready ( ) {
223+ // dbg!(Error::Bus);
224+ return Err ( Error :: Bus ) ;
225+ }
226+ Ok ( ( ) )
227+ }
228+
229+ fn write_without_stop ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) > {
230+ self . start_write ( addr) ?;
231+ self . write_inner_bytes ( bytes) ?;
197232
198233 // Fallthrough is success
199234 Ok ( ( ) )
@@ -214,6 +249,62 @@ where
214249 // Fallthrough is success
215250 Ok ( ( ) )
216251 }
252+
253+ fn read_byte ( & mut self ) -> u8 {
254+ self . i2c . mstdat . read ( ) . data ( ) . bits ( )
255+ }
256+
257+ fn wait_for_byte_ready ( & mut self ) -> Result < ( ) > {
258+ // Wait for next byte
259+ while self . i2c . stat . read ( ) . mstpending ( ) . is_in_progress ( ) { }
260+
261+ self . return_on_error ( ) ?;
262+ if !self . i2c . stat . read ( ) . mststate ( ) . is_receive_ready ( ) {
263+ return Err ( Error :: Bus ) ;
264+ }
265+
266+ Ok ( ( ) )
267+ }
268+
269+ fn wait_for_next_byte ( & mut self ) -> Result < u8 > {
270+ // Instruct master to continue
271+ self . i2c . mstctl . write ( |w| w. mstcontinue ( ) . continue_ ( ) ) ;
272+
273+ self . wait_for_byte_ready ( ) ?;
274+ Ok ( self . read_byte ( ) )
275+ }
276+
277+ fn start_read ( & mut self , addr : u8 ) -> Result < ( ) > {
278+ // Write the slave address with the RW bit set to 1 to the master data register MSTDAT.
279+ self . i2c
280+ . mstdat
281+ . modify ( |_, w| unsafe { w. data ( ) . bits ( ( addr << 1 ) | 1 ) } ) ;
282+ // Start the transmission by setting the MSTSTART bit to 1 in the master control register.
283+ self . i2c . mstctl . write ( |w| w. mststart ( ) . start ( ) ) ;
284+ Ok ( ( ) )
285+ }
286+
287+ fn read_inner_bytes ( & mut self , buffer : & mut [ u8 ] ) -> Result < ( ) > {
288+ for byte in buffer {
289+ // Read a byte
290+ * byte = self . wait_for_next_byte ( ) ?;
291+ }
292+ Ok ( ( ) )
293+ }
294+
295+ fn read_without_stop ( & mut self , addr : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) > {
296+ if let Some ( ( first, buffer) ) = buffer. split_first_mut ( ) {
297+ self . start_read ( addr) ?;
298+
299+ self . wait_for_byte_ready ( ) ?;
300+ // read first byte
301+ * first = self . read_byte ( ) ;
302+ self . read_inner_bytes ( buffer) ?;
303+ }
304+
305+ // Reading to an empty buffer is a noop
306+ Ok ( ( ) )
307+ }
217308}
218309
219310impl < PIO1 , PIO2 , I2C , PINS > Write for I2cMaster < PIO1 , PIO2 , I2C , PINS >
@@ -226,8 +317,7 @@ where
226317 type Error = Error ;
227318
228319 fn write ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) > {
229- self . write_without_stop ( addr, bytes) ?;
230- self . stop ( )
320+ <Self as I2cTrait >:: write ( self , addr, bytes)
231321 }
232322}
233323
@@ -241,45 +331,7 @@ where
241331 type Error = Error ;
242332
243333 fn read ( & mut self , addr : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) > {
244- if let Some ( ( last, buffer) ) = buffer. split_last_mut ( ) {
245- // Write the slave address with the RW bit set to 1 to the master data register MSTDAT.
246- self . i2c
247- . mstdat
248- . modify ( |_, w| unsafe { w. data ( ) . bits ( ( addr << 1 ) | 1 ) } ) ;
249- // Start the transmission by setting the MSTSTART bit to 1 in the master control register.
250- self . i2c . mstctl . write ( |w| w. mststart ( ) . start ( ) ) ;
251-
252- // Wait for the pending status to be set (MSTPENDING = 1) by polling the STAT register
253- while self . i2c . stat . read ( ) . mstpending ( ) . is_in_progress ( ) { }
254-
255- self . return_on_error ( ) ?;
256- if !self . i2c . stat . read ( ) . mststate ( ) . is_receive_ready ( ) {
257- return Err ( Error :: Bus ) ;
258- }
259-
260- for byte in buffer {
261- // Read a byte
262- * byte = self . i2c . mstdat . read ( ) . data ( ) . bits ( ) ;
263- // Instruct master to continue
264- self . i2c . mstctl . write ( |w| w. mstcontinue ( ) . continue_ ( ) ) ;
265-
266- // Wait for next byte
267- while self . i2c . stat . read ( ) . mstpending ( ) . is_in_progress ( ) { }
268-
269- self . return_on_error ( ) ?;
270- if !self . i2c . stat . read ( ) . mststate ( ) . is_receive_ready ( ) {
271- return Err ( Error :: Bus ) ;
272- }
273- }
274-
275- // Read last byte
276- * last = self . i2c . mstdat . read ( ) . data ( ) . bits ( ) ;
277-
278- self . stop ( ) ?;
279- }
280-
281- // Fallthrough is success
282- Ok ( ( ) )
334+ <Self as I2cTrait >:: read ( self , addr, buffer)
283335 }
284336}
285337
@@ -293,10 +345,66 @@ where
293345 type Error = Error ;
294346
295347 fn write_read ( & mut self , addr : u8 , bytes : & [ u8 ] , buffer : & mut [ u8 ] ) -> Result < ( ) > {
296- self . write_without_stop ( addr, bytes) ?;
297- self . read ( addr, buffer) ?;
348+ <Self as I2cTrait >:: write_read ( self , addr, bytes, buffer)
349+ }
350+ }
298351
299- Ok ( ( ) )
352+ impl < PIO1 , PIO2 , I2C , PINS > I2cTrait for I2cMaster < PIO1 , PIO2 , I2C , PINS >
353+ where
354+ PIO1 : PinId ,
355+ PIO2 : PinId ,
356+ I2C : I2c ,
357+ PINS : I2cPins < PIO1 , PIO2 , I2C > ,
358+ {
359+ fn transaction (
360+ & mut self ,
361+ address : u8 ,
362+ operations : & mut [ embedded_hal:: i2c:: Operation < ' _ > ] ,
363+ ) -> core:: result:: Result < ( ) , Self :: Error > {
364+ let [ ref mut current, ref mut rem @ ..] = operations else {
365+ // No operations mean noop
366+ return Ok ( ( ) ) ;
367+ } ;
368+
369+ // mut ref mut doesn't work above
370+ let mut current = current;
371+ let mut rem = rem;
372+ // None: first iteration
373+ // Some(true) iterating after a read
374+ // Some(false) iterating after a write
375+ let mut previous_was_read = None ;
376+
377+ loop {
378+ match current {
379+ Operation :: Read ( buf) => {
380+ if previous_was_read == Some ( true ) {
381+ self . read_inner_bytes ( buf) ?;
382+ } else {
383+ self . read_without_stop ( address, buf) ?;
384+ }
385+
386+ previous_was_read = Some ( true ) ;
387+ }
388+ Operation :: Write ( buf) => {
389+ if previous_was_read == Some ( false ) {
390+ self . write_inner_bytes ( buf) ?;
391+ } else {
392+ self . write_without_stop ( address, buf) ?;
393+ }
394+
395+ previous_was_read = Some ( false ) ;
396+ }
397+ }
398+
399+ let [ ref mut new_current, ref mut new_rem @ ..] = rem else {
400+ // No operations left
401+ self . stop ( ) ?;
402+ return Ok ( ( ) ) ;
403+ } ;
404+
405+ current = new_current;
406+ rem = new_rem;
407+ }
300408 }
301409}
302410
0 commit comments