LPI2C got FIFO error during transmission

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

LPI2C got FIFO error during transmission

5,766 Views
j_alex
Contributor I

Hello, I am currently using a MIMXRT1061CVL5 board. I am trying to run the LPI2C drivers sdk example "evkmimxrt1060_lpi2c_interrupt_b2b_transfer_master". The code works fine at first it sends the first byte of data then a fifo error (903) is raised. I don't know what could be the cause of this error. 

Thank you in advance for your help. 

0 Kudos
Reply
9 Replies

5,761 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @j_alex 

   Do you find two boards, one run as master:

  SDK_2_11_1_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\lpi2c\interrupt_b2b_transfer\master

  Another run as slave:

SDK_2_11_1_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\lpi2c\interrupt_b2b_transfer\slave

  After the connection, you need to run the slave at first, and wait the master clock and data.

  If you lack the related slave, then your master will have issue, as you know, I2C need the slave give ACK.

  So, it's better to use two RT1060 board, and one master and another is slave, test it in pairs.

 

Wish it helps you!

Best Regards,

Kerry

0 Kudos
Reply

5,755 Views
j_alex
Contributor I

Hello @kerryzhou thank you for your reply. i implement the following code:

 

#define EXAMPLE_I2C_MASTER_BASE (LPI2C3_BASE)

/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
/* Get frequency of lpi2c clock */
#define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))

#define LPI2C_MASTER_CLOCK_FREQUENCY LPI2C_CLOCK_FREQUENCY


#define EXAMPLE_I2C_MASTER ((LPI2C_Type *)EXAMPLE_I2C_MASTER_BASE)

#define I2C_MASTER_SLAVE_ADDR_7BIT 0x7EU
#define I2C_BAUDRATE 100000U
#define I2C_DATA_LENGTH 7U

 

/*******************************************************************************
* Variables
******************************************************************************/
uint8_t g_master_txBuff[I2C_DATA_LENGTH];
uint8_t g_master_rxBuff[I2C_DATA_LENGTH];
lpi2c_master_handle_t g_m_handle;
volatile bool g_MasterCompletionFlag = false;
volatile bool g_MasterNackFlag = false;

 

static void lpi2c_master_callback(LPI2C_Type *base, lpi2c_master_handle_t *handle, status_t status, void *userData)
{
if (status == kStatus_LPI2C_Nak)
{
g_MasterNackFlag = true;
}
else
{
g_MasterCompletionFlag = true;
/* Display failure information when status is not success. */
if (status != kStatus_Success)
{
PRINTF("Error occured during transfer!\n");
}
}
}

int main(void) {

lpi2c_master_transfer_t masterXfer = {0};
status_t reVal = kStatus_Fail;


/* Init board hardware. */
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
/* Init FSL debug console. */
BOARD_InitDebugConsole();
#endif

/*Clock setting for LPI2C*/
CLOCK_SetMux(kCLOCK_Lpi2cMux, LPI2C_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, LPI2C_CLOCK_SOURCE_DIVIDER);

PRINTF("\r\nLPI2C board2board interrupt example -- Master transfer.\r\n");

//* Set up i2c master to send data to slave*/
/* First data in txBuff is data length of the transmiting data. */
g_master_txBuff[0] = I2C_DATA_LENGTH - 1U;
for (uint32_t i = 1U; i < I2C_DATA_LENGTH; i++)
{
g_master_txBuff[i] = i-1;
}

PRINTF("Master will send data :");
for (uint32_t i = 0U; i < I2C_DATA_LENGTH - 1; i++)
{
if (i % 8 == 0)
{
PRINTF("\r\n");
}
PRINTF("0x%2x ", g_master_txBuff[i + 1]);
}
PRINTF("\r\n\r\n");

lpi2c_master_config_t masterConfig;

/*
* masterConfig.debugEnable = false;
* masterConfig.ignoreAck = false;
* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
* masterConfig.baudRate_Hz = 100000U;
* masterConfig.busIdleTimeout_ns = 0;
* masterConfig.pinLowTimeout_ns = 0;
* masterConfig.sdaGlitchFilterWidth_ns = 0;
* masterConfig.sclGlitchFilterWidth_ns = 0;
*/
LPI2C_MasterGetDefaultConfig(&masterConfig);

/* Change the default baudrate configuration */
masterConfig.baudRate_Hz = I2C_BAUDRATE;

LPI2C_MasterReset(EXAMPLE_I2C_MASTER);
/* Initialize the LPI2C master peripheral */
LPI2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, LPI2C_MASTER_CLOCK_FREQUENCY);

/* Create the LPI2C handle for the non-blocking transfer */
LPI2C_MasterTransferCreateHandle(EXAMPLE_I2C_MASTER, &g_m_handle, lpi2c_master_callback, NULL);

/* subAddress = 0x01, data = g_master_txBuff - write to slave.
start + slaveaddress(w) + subAddress + length of data buffer + data buffer + stop*/
uint8_t deviceAddress = 0x01U;
masterXfer.slaveAddress = I2C_MASTER_SLAVE_ADDR_7BIT;
masterXfer.direction = kLPI2C_Write;
masterXfer.subaddress = (uint32_t)deviceAddress;
masterXfer.subaddressSize = 1;
masterXfer.data = g_master_txBuff;
masterXfer.dataSize = I2C_DATA_LENGTH;
masterXfer.flags = kLPI2C_TransferDefaultFlag;

/* Send master non-blocking data to slave */
reVal = LPI2C_MasterTransferNonBlocking(EXAMPLE_I2C_MASTER, &g_m_handle, &masterXfer);

if (reVal != kStatus_Success)
{
return -1;
}
/* Wait for transfer completed. */
while ((!g_MasterCompletionFlag) && (!g_MasterNackFlag))
{
PRINTF("wait for transfer to finish\n");
}
if (g_MasterNackFlag)
{
PRINTF("Master nacked by slave!");
g_MasterNackFlag = false;
}
g_MasterCompletionFlag = false;
PRINTF("transfer completed!");

while(1)

{

}

}

the I2C of the nxp is linked to an arduino, that plays the role of the slave. I can see on the oscillioscope that the address , subaddress, number of data and the first byte of data was sent correctly the problem start after that. Even in my arduino i have correctly received the first byte of data.  i have attached the view of my oscilloscope. 

0 Kudos
Reply

5,750 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @j_alex ,

  From your picture:

kerryzhou_0-1654678454092.png

So:

 address =0x7e,

subaddress =0x01,

number of data =0x06

 the first byte of data =0x00

Then it stops sendout the data, right?

Please also share the I2C status register, check which detail error happens.

Do you have two MIMXRT1060 board? If yes, you can run it, one as master, and another as slave, then test it, and modify it to match your situation, it will be more easy to checking.

About the wave test, it's better to find a logic analyzer, that will be more easy to check the I2C bus and data.

 

Best Regards,

Kerry

 

0 Kudos
Reply

5,747 Views
j_alex
Contributor I

Hello @kerryzhou , unfortunately i don't have another nxp neither a logic analyzer. I don't know how to share the I2C status register, but the error that i get is Kstatus_LPI2C_Fifo error when i test the status in my callback, i can see that the status is 903 which corresponds to the Kstatus_LPI2C_Fifo error.

0 Kudos
Reply

5,745 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @j_alex 

  Do you debug the code, which IDE and debugger you are using?

  You can check the I2C register directly when you debug it:

kerryzhou_0-1654684011545.png

Do you have the MIMXRT1060-EVK board?

If yes, you even can test this I2C code, as it will use the I2C to communicate with the on board I2C sensor:

SDK_2_11_1_EVK-MIMXRT1060\boards\evkmimxrt1060\demo_apps\bubble_peripheral

 

Best Regards,

Kerry

 

0 Kudos
Reply

5,741 Views
j_alex
Contributor I

Hi @kerryzhou , no i don't have a MIMXRT1060-EVK board. I am using mcuxpresso IDE version 11.5.1 and i am using its debugger (link server debgug) to debug my program. I see on the internet that i can see the contents of my registerd using the debug mode of the IDE, i can see their contents in the registers window while halting my program during debuging. I will test this.

But again i think that i will have the same flag fifo error that i get in the status of my function. So my question is when this flag is raised ? 

 

0 Kudos
Reply

5,733 Views
j_alex
Contributor I

Hello @kerryzhou i run the program in debug mode and i put a breakpoint in the function LPI2C_MasterGetStatusFlags to see the contents of the MSR and i get the following results, the function was called 5 times with the following values:

1- 1: TDF flag is set

2- 1: TDF flag is set

3- 769: TDF, EPF,SDF are set

4- 4864: EPF,SDF,FEF are set

5- 4865: TDF,EPF,SDF,FEF are set 

 

hope that this will hepl you to figure out the cause of my problem.

0 Kudos
Reply

5,731 Views
j_alex
Contributor I

Hello, @kerryzhou I found the problem. the problem is that the LPI2C driver send a stop after the first send and the cause was that LPI2C does not work in debug mode unless you set the flag BGEN in the MCR so when i call the function  LPI2C_MasterTransferNonBlocking after reseting the FIFO i add the following command:

base->MCR |= LPI2C_MCR_DBGEN_MASK;

and now it works perfectly for the transmission part.

0 Kudos
Reply

5,725 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @j_alex ,

    Thanks so much for your effort.

   So, you test it totally in the debug mode, and meet the issues.

   If you just download code to the chip flash, and run without the debug, even don't enable :base->MCR |= LPI2C_MCR_DBGEN_MASK;

   Whether that works or not?

   When debug, really need to enable MCR[DBGEN]:Master is enabled in debug mode

 

Best Regards,

Kerry

0 Kudos
Reply