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 */