This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 5ca9adbe61 Copy I2C_M_NOSTART support from sam7v/sam_twihs.c driver
5ca9adbe61 is described below

commit 5ca9adbe61350453f3bc175cb436ec6556a67e0d
Author: Bernd Walter <[email protected]>
AuthorDate: Sun Mar 5 15:15:43 2023 +0100

    Copy I2C_M_NOSTART support from sam7v/sam_twihs.c driver
---
 arch/arm/src/sam34/sam_twi.c | 82 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 68 insertions(+), 14 deletions(-)

diff --git a/arch/arm/src/sam34/sam_twi.c b/arch/arm/src/sam34/sam_twi.c
index 8f110ad82e..3cd93c2f41 100644
--- a/arch/arm/src/sam34/sam_twi.c
+++ b/arch/arm/src/sam34/sam_twi.c
@@ -475,21 +475,53 @@ static int twi_interrupt(int irq, void *context, void 
*arg)
 
       if (priv->xfrd >= msg->length)
         {
-          /* The transfer is complete.  Disable the RXRDY interrupt and
-           * enable the TXCOMP interrupt
+          struct i2c_msg_s *next = (msg + 1);
+
+          /* Is there another message to after this one?  Does it require a
+           * restart?
            */
 
-          twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_RXRDY);
-          twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP);
+          if (priv->msgc <= 1 || (next->flags & I2C_M_NOSTART) == 0)
+            {
+              /* The transfer is complete.  Disable the RXRDY interrupt and
+               * enable the TXCOMP interrupt
+               */
+
+               twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_RXRDY);
+               twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP);
+            }
+          else
+            {
+              /* No.. just switch to the next message and continue
+               * receiving.  On the next RXRDY, we will continue with the
+               * first byte of the next message.
+               */
+
+              DEBUGASSERT((next->flags & I2C_M_READ) != 0);
+              priv->msg = next;
+              priv->msgc--;
+              priv->xfrd = 0;
+            }
         }
 
       /* Not yet complete, but will the next be the last byte? */
 
       else if (priv->xfrd == (msg->length - 1))
         {
-          /* Yes, set the stop signal */
+          struct i2c_msg_s *next = (msg + 1);
+
+          /* Is there another message to after this one?  Does it require a
+           * restart?
+           */
+
+          if (priv->msgc <= 1 || (next->flags & I2C_M_NOSTART) == 0)
+            {
+              /* This is the last message OR a restart is required before
+               * the next message.  Send the stop signal.
+               */
 
-          twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP);
+              twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_STOP);
+            }
         }
     }
 
@@ -501,18 +533,40 @@ static int twi_interrupt(int irq, void *context, void 
*arg)
 
       if (priv->xfrd >= msg->length)
         {
-          /* The transfer is complete.  Disable the TXRDY interrupt and
-           * enable the TXCOMP interrupt
+          struct i2c_msg_s *next = (msg + 1);
+
+          /* Is there another message to after this one?  Does it require a
+           * restart?
            */
 
-          twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXRDY);
-          twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP);
+          if (priv->msgc <= 1 || (next->flags & I2C_M_NOSTART) == 0)
+            {
+              /* The transfer is complete.  Disable the TXRDY interrupt and
+               * enable the TXCOMP interrupt
+               */
 
-          /* Send the STOP condition */
+              twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXRDY);
+              twi_putrel(priv, SAM_TWI_IER_OFFSET, TWI_INT_TXCOMP);
 
-          regval  = twi_getrel(priv, SAM_TWI_CR_OFFSET);
-          regval |= TWI_CR_STOP;
-          twi_putrel(priv, SAM_TWI_CR_OFFSET, regval);
+              /* Send the STOP condition */
+
+              regval  = twi_getrel(priv, SAM_TWI_CR_OFFSET);
+              regval |= TWI_CR_STOP;
+              twi_putrel(priv, SAM_TWI_CR_OFFSET, regval);
+            }
+          else
+            {
+              /* No.. just switch to the next message and continue
+               * sending.
+               */
+
+              DEBUGASSERT((next->flags & I2C_M_READ) == 0);
+              priv->msg = next;
+              priv->msgc--;
+
+              twi_putrel(priv, SAM_TWI_THR_OFFSET, next->buffer[0]);
+              priv->xfrd = 1;
+            }
         }
 
       /* No, there are more bytes remaining to be sent */

Reply via email to