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,81 @@ 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+ }
308+
309+ fn read_ ( & mut self , addr : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) > {
310+ self . read_without_stop ( addr, buffer) ?;
311+ self . stop ( ) ?;
312+
313+ Ok ( ( ) )
314+ }
315+
316+ fn write_ ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) > {
317+ self . write_without_stop ( addr, bytes) ?;
318+ self . stop ( )
319+ }
320+
321+ fn write_read_ ( & mut self , addr : u8 , bytes : & [ u8 ] , buffer : & mut [ u8 ] ) -> Result < ( ) > {
322+ self . write_without_stop ( addr, bytes) ?;
323+ self . read_ ( addr, buffer) ?;
324+
325+ Ok ( ( ) )
326+ }
217327}
218328
219329impl < PIO1 , PIO2 , I2C , PINS > Write for I2cMaster < PIO1 , PIO2 , I2C , PINS >
@@ -226,8 +336,7 @@ where
226336 type Error = Error ;
227337
228338 fn write ( & mut self , addr : u8 , bytes : & [ u8 ] ) -> Result < ( ) > {
229- self . write_without_stop ( addr, bytes) ?;
230- self . stop ( )
339+ <Self as I2cTrait >:: write ( self , addr, bytes)
231340 }
232341}
233342
@@ -241,45 +350,7 @@ where
241350 type Error = Error ;
242351
243352 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 ( ( ) )
353+ <Self as I2cTrait >:: read ( self , addr, buffer)
283354 }
284355}
285356
@@ -293,10 +364,63 @@ where
293364 type Error = Error ;
294365
295366 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) ?;
367+ <Self as I2cTrait >:: write_read ( self , addr, bytes, buffer)
368+ }
369+ }
298370
299- Ok ( ( ) )
371+ impl < PIO1 , PIO2 , I2C , PINS > I2cTrait for I2cMaster < PIO1 , PIO2 , I2C , PINS >
372+ where
373+ PIO1 : PinId ,
374+ PIO2 : PinId ,
375+ I2C : I2c ,
376+ PINS : I2cPins < PIO1 , PIO2 , I2C > ,
377+ {
378+ fn transaction (
379+ & mut self ,
380+ address : u8 ,
381+ operations : & mut [ embedded_hal:: i2c:: Operation < ' _ > ] ,
382+ ) -> core:: result:: Result < ( ) , Self :: Error > {
383+ let [ ref mut current, ref mut rem @ ..] = operations else {
384+ // No operations mean noop
385+ return Ok ( ( ) ) ;
386+ } ;
387+
388+ // mut ref mut doesn't work above
389+ let mut current = current;
390+ let mut rem = rem;
391+ let mut previous_was_read = false ;
392+
393+ loop {
394+ match current {
395+ Operation :: Read ( buf) => {
396+ if previous_was_read {
397+ self . read_inner_bytes ( buf) ?;
398+ } else {
399+ self . read_without_stop ( address, buf) ?;
400+ }
401+
402+ previous_was_read = true ;
403+ }
404+ Operation :: Write ( buf) => {
405+ if !previous_was_read {
406+ self . write_inner_bytes ( buf) ?;
407+ } else {
408+ self . write_without_stop ( address, buf) ?;
409+ }
410+
411+ previous_was_read = false ;
412+ }
413+ }
414+
415+ let [ ref mut new_current, ref mut new_rem @ ..] = rem else {
416+ // No operations left
417+ self . stop ( ) ?;
418+ return Ok ( ( ) ) ;
419+ } ;
420+
421+ current = new_current;
422+ rem = new_rem;
423+ }
300424 }
301425}
302426
0 commit comments