I2C gets stuck

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

I2C gets stuck

1,259件の閲覧回数
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 件の賞賛
返信
3 返答(返信)

1,242件の閲覧回数
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello ,

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

 

BR

Alice

0 件の賞賛
返信

1,210件の閲覧回数
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 件の賞賛
返信

1,209件の閲覧回数
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 件の賞賛
返信