This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294NCPDT: Problem with I2C FIFO

Part Number: TM4C1294NCPDT

Hello everyone, 

I have a problem regarding the configuration of TM4C1294 as a slave in I2C communication. In my project, it is communicating with other MCU (same type) which is master. I would like to configure this one as a slave which rises interrupt when a specific amount of bytes is received to the FIFO. For example, I first tried as with two, but I cannot get it to read data from FIFO. When checked in the debugger, the value is 0 when read with "nonblocking" or code blocks if it is read with blocking function. I suppose I did not configure MCU peripheral well. When I use single byte receive it works good, but I would rather use FIFO since messages transmitted between MCU-s will be of 2-3 bytes length. Here is my code for the slave MCU: 

void I2C_Configuration()
{
	SysCtlPeripheralDisable(SYSCTL_PERIPH_I2C2);
	SysCtlPeripheralReset(SYSCTL_PERIPH_I2C2);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
	while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C2));
	GPIOPinConfigure(GPIO_PN4_I2C2SDA);
	GPIOPinConfigure(GPIO_PN5_I2C2SCL);
	GPIOPinTypeI2CSCL(GPIO_PORTN_BASE, GPIO_PIN_5);
	GPIOPinTypeI2C(GPIO_PORTN_BASE, GPIO_PIN_4);
	I2CSlaveInit(I2C2_BASE, SLAVE_ADDRESS);
	I2CSlaveIntEnable(I2C2_BASE);
	I2CRxFIFOConfigSet(I2C2_BASE, I2C_FIFO_CFG_RX_SLAVE | I2C_FIFO_CFG_RX_TRIG_2);
	I2CRxFIFOFlush(I2C2_BASE);
	I2CSlaveIntEnableEx(I2C2_BASE, (I2C_SLAVE_INT_RX_FIFO_REQ));
	IntEnable(INT_I2C2);
	I2CIntRegister(I2C2_BASE, I2C2SlaveIntHandler);
	I2CSlaveEnable(I2C2_BASE);
}

void I2C2SlaveIntHandler(void)
{
	uint32_t ui32I2CMasterInterruptStatus;
	ui32I2CMasterInterruptStatus = I2CSlaveIntStatusEx(I2C2_BASE, true);
	uint32_t i =0;
	for(i=0; i<2; i++)
	{
		  I2CFIFODataGetNonBlocking(I2C2_BASE, &dat[i]);
	}
	I2CRxFIFOFlush(I2C2_BASE);
	I2CSlaveIntClearEx(I2C0_BASE, I2C_SLAVE_INT_RX_FIFO_REQ);
}

And here is master MCU configuration and write functions

void I2C_Configuration()
{
	SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);
	SysCtlPeripheralReset(SYSCTL_PERIPH_I2C2);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
	GPIOPinConfigure(GPIO_PN4_I2C2SDA);
	GPIOPinConfigure(GPIO_PN5_I2C2SCL);
	GPIOPinTypeI2CSCL(GPIO_PORTN_BASE, GPIO_PIN_5);
	GPIOPinTypeI2C(GPIO_PORTN_BASE, GPIO_PIN_4);
	I2CMasterInitExpClk(I2C2_BASE, g_ui32SysClock, false);
	I2CMasterSlaveAddrSet(I2C2_BASE, SLAVE_ADR, false);
}

uint8_t I2CWriteData(uint8_t slave_addr, uint8_t dev_reg, uint8_t *dat, uint8_t count)
{
	while ( I2CMasterBusy(I2C2_BASE) );

	I2CMasterSlaveAddrSet(I2C2_BASE, slave_addr, false);

	uint8_t i=0;

	while ( I2CMasterBusy(I2C2_BASE) );
	I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_START);

	for(i=0; i<count; i++)
	{
		while ( I2CMasterBusy(I2C2_BASE) );
		I2CMasterDataPut(I2C2_BASE, dat[i]);

		if(i!=(count-1))
			I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
		else
			I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_STOP);
	}
	while ( I2CMasterBusy(I2C2_BASE) );
	return 1;
}

  • Hello Djedjica,

    Looking at your slave code, I am not 100% sure this is the root cause but I see you have the wrong I2C Base for your interrupt clear:

    I2CSlaveIntClearEx(I2C0_BASE, I2C_SLAVE_INT_RX_FIFO_REQ);

    That should be I2C2_BASE. See if changing that helps.

    Also have you reviewed our I2C app note with software examples? www.ti.com/.../spma073.pdf You might find some useful tips on I2C FIFO there as well.
  • Hello Mr. Jacobi, yes yes I see now I made mistake there, but that happened while I was testing and changing some code to see what was wrong. But my interrupt never gets hit at all. I checked this document and but it hasn't got much about how to configure MCU to be slave and use FIFO reg. 

    Also, if I have two MCU-s sending some messages about 2-3 bytes long, can it be reliable if I make this communication without FIFO maybe some custom defined signs which would indicate start and end of  message? 

    Regards,

  • Hi,

    Are you saying that if you use I2CSlaveIntEnableEx(I2C2_BASE, I2C_SLAVE_INT_DATA) then it will interrupt but not when you use I2CSlaveIntEnableEx(I2C2_BASE, (I2C_SLAVE_INT_RX_FIFO_REQ))?

    Can you please dump the I2C2 slave register contents from the register browser window in CCS?
  • Hello Mr.Tsai,

    Interrupt occurs when data is send when I use I2CSlaveIntEnableEx(I2C2_BASE, (I2C_SLAVE_INT_RX_FIFO_REQ)) also. But it occurs even if only one byte is sent, no matter on I2C_FIFO_CFG_RX_TRIG level , and data cannot be read with using above code for slave ISR, i still can only reach the data only with  I2CSlaveDataGet(I2C2_BASE). Here is image with slave settings.

  • Hi,
    When did you take the register screenshot? I will suggest you first place a breakpoint in the very beginning of the I2C2SlaveIntHandler. The reason I'm asking is that based on your screenshot the RXFIFO is empty as indicated in the I2C FIFO Status register and the I2C_SRIS and I2C_SMIS are both zero indicating there is no interrupt flags set.
  • Hi,

     You have the below code sequence where  you first call I2CSlaveIntEnable and later on you call I2CSlaveIntEnableEx again. Can you try to remove the first line. In your screenshot you are enabling both the Data interrupt as well as RX FIFO interrupt? See if it makes a difference. 

        I2CSlaveIntEnable(I2C2_BASE);
        I2CRxFIFOConfigSet(I2C2_BASE, I2C_FIFO_CFG_RX_SLAVE | I2C_FIFO_CFG_RX_TRIG_2);
        I2CRxFIFOFlush(I2C2_BASE);
        I2CSlaveIntEnableEx(I2C2_BASE, (I2C_SLAVE_INT_RX_FIFO_REQ));

  • Hello Mr.Tsai, 

    I tried, but in that case trigger is not hit at all, although I see data in data reg, but FIFO is still empty. Here is register view. 

  • Hi,
    I don't see you calling the I2CSlaveFIFOEnable to enable the FIFO for the I2C slave. You need to call I2CSlaveFIFOEnable after you call I2CSlaveEnable. Try below.

    I2CSlaveEnable(I2C2_BASE);
    I2CSlaveFIFOEnable(I2C2_BASE, I2C_SLAVE_RX_FIFO_ENABLE);
  • Yes, thank You very much, this resolved my issue, you were right.
    I2CSlaveIntEnable(I2C2_BASE);
    is unnecessary in configuration function and I added
    I2CSlaveFIFOEnable(I2C2_BASE, I2C_SLAVE_RX_FIFO_ENABLE);
    now it triggers just as it should. Thank You very much and sorry for taking Your time.
    Kind regards
  • Glad your problem is resolved.