I2C gets stuck

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C gets stuck

1,256 Views
EduardoGoncalves1966
Contributor I

Hi

 

I'm using this function that is provided with the I2C examples in lpcopen_2_20_lpcxpresso_nxp_lpcxpresso_1549.zip

 

static void SetupXferRecAndExecute(uint8_t devAddr,
uint8_t *txBuffPtr,
uint16_t txSize,
uint8_t *rxBuffPtr,
uint16_t rxSize)
{
/* Setup I2C transfer record */
i2cmXferRec.slaveAddr = devAddr;
i2cmXferRec.status = 0;
i2cmXferRec.txSz = txSize;
i2cmXferRec.rxSz = rxSize;
i2cmXferRec.txBuff = txBuffPtr;
i2cmXferRec.rxBuff = rxBuffPtr;

Chip_I2CM_Xfer(LPC_I2C0, &i2cmXferRec);
/* Enable Master Interrupts */
Chip_I2C_EnableInt(LPC_I2C0, I2C_INTENSET_MSTPENDING | I2C_INTENSET_MSTRARBLOSS | I2C_INTENSET_MSTSTSTPERR);

/* Wait for transfer completion */
while (i2cmXferRec.status == I2CM_STATUS_BUSY)
__WFI(); /* Sleep until next interrupt */

/* Clear all Interrupts */
Chip_I2C_ClearInt(LPC_I2C0, I2C_INTENSET_MSTPENDING | I2C_INTENSET_MSTRARBLOSS | I2C_INTENSET_MSTSTSTPERR);
}

 

The function seems to wait for the completion of the I2C transfer.

However if I call SetupXferRecAndExecute twice, one after the other, it gets back with wrong values.

If I put a delay between the 2 calls all is fine:

 

SetupXferRecAndExecute ( PCA9535_I2C_ADDRESS, config_W, sizeof(config_W), NULL, 0 );

for ( int i=0 ; i<100 ; i++ );  // about 20us

SetupXferRecAndExecute ( PCA9535_I2C_ADDRESS, config_R, 1, &config_R[1], 2 );

 

Sometimes it also gets stuck on the second call generating an infinite amount interrupts that call I2C0_IRQHandler().

These interrupts keep calling

/* Master is Pending */
else if (status & I2C_STAT_MSTPENDING) {

     /* Branch based on Master State Code */
     switch (Chip_I2CM_GetMasterState(pI2C)) {
         /* Master idle */
         case I2C_STAT_MSTCODE_IDLE:     <<<---
            break;    /* Do Nothing */     

where status is 0x801.

 

It looks like the transfer is considered as ended too soon... And when the second transfer is requested it gets stuck.

Is this known? Is there any update that solves this problem?

thanks

0 Kudos
Reply
3 Replies

1,239 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello ,

How about first check  Status of the current I2C transfer before call this function.

 

BR

Alice

0 Kudos
Reply

1,207 Views
EduardoGoncalves1966
Contributor I


I have copied the while loop to check if the I2C is busy to the beginning of SetupXferRecAndExecute()

/* Wait for transfer completion */
while (i2cmXferRec.status == I2CM_STATUS_BUSY)
__WFI(); /* Sleep until next interrupt */

But still it doesn't work.

 

0 Kudos
Reply

1,206 Views
EduardoGoncalves1966
Contributor I

I have used a scope to get more information:

If I insert a small delay between two consecutive calls to SetupXferRecAndExecute it works fine!

See 1.png

SetupXferRecAndExecute ( SC18IS602B_I2C_ADDRESS, sc18_LCDpage, 2, NULL, 0 );

for ( int i=0 ; i<50 ; i++ );

SetupXferRecAndExecute ( SC18IS602B_I2C_ADDRESS, sc18_LCDcol, 3, NULL, 0 );

But if I omit that delay then the address byte of the second transfer is appended to the first transfer and it blocks

See 2.png

Any explanation/workaround for this? thanks

 

0 Kudos
Reply