LPCxpresso 54628 I2C slave stop condition issue

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

LPCxpresso 54628 I2C slave stop condition issue

1,429 Views
mspenard603
Contributor IV

Hi All,

 I'm using a LPCxpresso 54628 and am running the I2C interrupt driven slave example code. My issue is that, while I see all my data come in on a ReceiveEvent, the I2C callback routine never hits the "kI2C_SlaveCompletionEvent" state despite my I2C-master sending a stop. Which I confirmed on my scope (see attachments).

The code is all untouched from the NXP example code (lpcxprrsso_54628_i2_interrupt_b2b_transfer_slave). And the SlaveCompletetionEvent flag is being passed:

reVal = I2C_SlaveTransferNonBlocking(EXAMPLE_I2C_SLAVE, &g_s_handle, kI2C_SlaveAddressMatchEvent | kI2C_SlaveCompletionEvent);

Any thoughts on why it never hits kI2C_SlaveCompletionEvent ?!

Mike

Labels (1)
0 Kudos
7 Replies

1,072 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Mike Spenard,

I test the demo on my side, it can hits   the case  of  "kI2C_SlaveCompletionEvent",

pastedImage_1.png

Try to set a breakpoint on line 67  g_SlaveCompletionFlag = true;  just like my picture above,  connect tow lpc54628 boards, flash mater project to Master board, download slave project to Slave board, click Run, then Reset Master board,

it should stop at the breakpoint.

BTW, please use the latest SDK v2.5.

Hope it helps,

BR

Alice

0 Kudos

1,072 Views
mspenard603
Contributor IV

In digging into this further in the LPC546xx Reference Manual (https://studio.segger.com/packages/LPC54000/CMSIS/Documents/UM10912.pdf ) I can see what happened:

There is a set of registers (MONACTIVE et al) specifically for monitoring the I2C bus condition (start stop etc). But the FSL_I2C.C API failed to implement them in its code! Rather, they took the example from 26.4.2.1 for transferring 8bits--that doesn't use the monitor registers--and used the same transfer scheme for transferring multiple bytes of data as if that is acceptable in the real world.

Someone needs to update the fsl_i2c API asap, this is asinine.

0 Kudos

1,072 Views
mspenard603
Contributor IV

Hi Alice,

 I'm using the latest SDK. I think there is some confusion on what exactly the issue is and why it is working for you:

The issue is that unless one reads the amount of data specified by "#define I2C_DATA_LENGTH (34)"  it never hits kI2C_SlaveCompletionEvent. fsl_i2c.c is written around the expectation to always receive a set size of data (i.e., I2C_DATA_LENGTH) rather than an I2C Stop.

Specifically, the xfer->rxSize is initialized to I2C_DATA_LENGTH and tries to count down to zero. If it doesn't reach 0 than no kI2C_SlaveCompletionEvent.

This isn't acceptable as a large degree of I2C sensors and implementations have varying data payload size. And the API needs to be written such that it hits a Completion State on a I2C stop rather than rxData counting down to 0.

/ms

0 Kudos

1,072 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Mike,

- "And the API needs to be written such that it hits a Completion State on a I2C stop rather than rxData counting down to 0." - Yes, this demo just shows raData down to 0. If you want to hit a completion state on Stop,  just need to add the  "case kI2C_SlaveDeselectedEvent " in  i2c_slave_callback function, for example :

In i2c salve callback function:

static void i2c_slave_callback(I2C_Type *base, volatile i2c_slave_transfer_t *xfer, void *userData)
{
    switch (xfer->event)
    {

...

        case kI2C_SlaveDeselectedEvent:
                   g_SlaveCompletionFlag = true;
         //        Your own code
                   break;

...

    }
}

And in transfer function. we need add kI2C_SlaveDeselectedEvent:

  /* Start accepting I2C transfers on the I2C slave peripheral */
    reVal = I2C_SlaveTransferNonBlocking(EXAMPLE_I2C_SLAVE, &g_s_handle,
                                         kI2C_SlaveAddressMatchEvent | kI2C_SlaveCompletionEvent|kI2C_SlaveDeselectedEvent);

- when Master send Stop, the Slave Deselected flag of STAT will set to 1 , then in the function of   I2C_SlaveTransferHandleIRQ invoke kI2C_SlaveDeselectedEvent .

Please check the driver code :

void I2C_SlaveTransferHandleIRQ(I2C_Type *base, i2c_slave_handle_t *handle)
{
    uint32_t i2cStatus = base->STAT;

    if (i2cStatus & I2C_STAT_SLVDESEL_MASK)
    {
        I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveDeselectedEvent);
        I2C_SlaveClearStatusFlags(base, I2C_STAT_SLVDESEL_MASK);
    }

...

}

Also have a look at the LPC546xx Reference Manual page 445.

pastedImage_1.png


Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,072 Views
mspenard603
Contributor IV

A subsequent issue is it's accepting bad NAKd data into the receive buffer. This needs to be avoided. Any suggestions? 

0 Kudos

1,072 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Mike,

Sorry I'm afraid I can't understand your meaning.

Could you please describe the process detail about "it's accepting bad NAKd data into the receive buffer."

BR

Alice

0 Kudos

1,072 Views
mspenard603
Contributor IV

Ah, very good! Thank you!

0 Kudos