LAUNCHXL-F28379D: Issue with I2C Communication: F28379D as Slave

Part Number: LAUNCHXL-F28379D

Hello everyone,

I'm experiencing some issues when using I2C with the F28379D as a slave device.

  1. I have set the I2C slave address of the F28379D to 0x50, but on the master side, the detected address is 0x00. If I try to force a write operation to 0x50, the transmission fails.
  2. When writing to address 0x00 from the master, there is a data delay issue on the F28379D slave side. For example:
    • The first transmitted value is 10, but the slave does not update.
    • The second transmitted value is 11, but the slave only updates to the first value (10).
    • The third transmitted value is 12, but the slave updates to 11, and so on.

I have tested the same setup with other slave devices, and these issues did not occur.

I would appreciate any help in troubleshooting this problem. Thank you!

For reference, I am using the example code i2c_ex5_master_slave_interrupt.c as my slave-side implementation. Here is the code:


#include <i2cLib_FIFO_master_slave_interrupt.h>

#include "device.h"
#include "driverlib.h"
#include "board.h"

#define I2CA_ADDRESS 0x30
#define I2CB_ADDRESS 0x50

//
// Globals
//
uint16_t status = 0;
uint16_t status_intoisr = 0;
uint16_t status_interrupt = 0;
uint16_t slave = 0;
uint16_t slavefifo = 0;
uint16_t rData_size = 0;
uint16_t fifoDepth = 0;
uint16_t tempData[MAX_BUFFER_SIZE];

struct I2CHandle I2CA;
struct I2CHandle I2CB;

//
// Function Prototypes
//
//__interrupt void i2cAISR(void);
//__interrupt void i2cAFIFOISR(void);

__interrupt void i2cBISR(void);
__interrupt void i2cBFIFOISR(void);

uint16_t AvailableI2C_slaves[MAX_I2C_IN_NETWORK];

uint16_t I2CA_TXdata[MAX_BUFFER_SIZE];
uint16_t I2CB_TXdata[MAX_BUFFER_SIZE];

uint16_t I2CA_RXdata[MAX_BUFFER_SIZE];
uint16_t I2CB_RXdata[MAX_BUFFER_SIZE];

uint32_t I2CA_ControlAddr;
uint32_t I2CB_ControlAddr;
uint16_t status;

uint16_t rData[2];
uint16_t firstByte[2];

void I2C_GPIO_init(void);
void I2Cinit(void);

//
// Main
//
void main(void)
{

//
// Initialize device clock and peripherals
//
Device_init();

//
// Disable pin locks and enable internal pullups.
//
Device_initGPIO();

//
// Board initialization
//

I2C_GPIO_init();

//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();

I2Cinit();


//I2C_setOwnSlaveAddress(I2CA_BASE, I2CA_ADDRESS);
//I2C_setOwnSlaveAddress(I2CB_BASE, I2CB_ADDRESS);



//I2Cs connected to I2CA will be found in AvailableI2C_slaves buffer
//after you run I2CBusScan function.
//When you run I2C BusScan you need to disable I2C interrupts and clear
//the flag set during I2CBusScan
uint16_t i;

for(i=0;i<MAX_I2C_IN_NETWORK;i++)
{
AvailableI2C_slaves[i] = 0;
}

I2C_disableInterrupt(I2CA_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
I2C_disableInterrupt(I2CB_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));

uint16_t *pAvailableI2C_slaves = AvailableI2C_slaves;
//status = I2CBusScan(I2CA_BASE, pAvailableI2C_slaves);

I2C_clearStatus(I2CA_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
I2C_clearStatus(I2CB_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);

ESTOP0;
I2C_disableInterrupt(I2CA_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
I2C_disableInterrupt(I2CB_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));

status = I2CBusScan(I2CB_BASE, pAvailableI2C_slaves);

I2C_clearStatus(I2CA_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
I2C_clearStatus(I2CB_BASE,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);


I2C_enableInterrupt(I2CA_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
I2C_enableInterrupt(I2CB_BASE, (I2C_INT_ADDR_SLAVE|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));


//
// Set I2C use, initializing it for FIFO mode
//

//Interrupt_register(INT_I2CA, &i2cAISR);
Interrupt_enable(INT_I2CA);

Interrupt_register(INT_I2CB, &i2cBISR);
Interrupt_enable(INT_I2CB);

//Interrupt_register(INT_I2CA_FIFO, &i2cAFIFOISR);
Interrupt_enable(INT_I2CA_FIFO);

Interrupt_register(INT_I2CB_FIFO, &i2cBFIFOISR);
Interrupt_enable(INT_I2CB_FIFO);

//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
ERTM;


for(i=0;i<MAX_BUFFER_SIZE;i++)
{
I2CA_TXdata[i] = i+1;
I2CA_RXdata[i] = 0;
I2CB_TXdata[i] = 0;
I2CB_RXdata[i] = 0;
}

I2CA.currentHandlePtr = &I2CA;
I2CA.base = I2CA_BASE;
I2CA.SlaveAddr = I2CB_ADDRESS;
I2CA.pControlAddr = &I2CA_ControlAddr;
I2CA.NumOfAddrBytes = 4;
I2CA.pTX_MsgBuffer = I2CA_TXdata;
I2CA.pRX_MsgBuffer = I2CA_RXdata;
I2CA.NumOfDataBytes = 64;

I2CB.currentHandlePtr = &I2CB;
I2CB.base = I2CB_BASE;
I2CB.SlaveAddr = I2CB_ADDRESS;
I2CB.NumOfAddrBytes = 4;
I2CB.pControlAddr = (uint32_t *)0;
I2CB.pTX_MsgBuffer = (uint16_t *)0;
I2CB.pRX_MsgBuffer = (uint16_t *)0;

// Example1: I2CA as Master Transmitter and I2CB working Slave Receiver //

// I2CA = Master Transmitter
// I2CB = Slave Receiver
// I2CA generates
// 1) START condition
// 2) I2CB address (Slave address) + Write mode
// 3) Transmit start address of I2CB_RXdata
// 4) Transmit contents of I2CA_TXdata array
// 5) I2CB received data is stored in I2CB_RXdata array
// 6) Contents of I2CA_TXdata and I2CB_RXdata should match

//Slave pControlAddr should be 0 proper operation.
//Slave pControlAddr is transmitted by I2CA master
//I2CB.pControlAddr = (uint32_t *)0;
//I2CA_ControlAddr = (uint32_t)I2CB_RXdata;
//status = I2C_MasterTransmitter(&I2CA);

// Wait for I2CA to be complete transmission of data
//while(I2C_getStatus(I2CA.base) & I2C_STS_BUS_BUSY);

//for(i=0;i<I2CA.NumOfDataBytes;i++)
//{
//if((I2CB_RXdata[i] != I2CA_TXdata[i]) || (status != 0))
//{
//Fail condition. Code shouldn't reach here
//Check status (global variable) for I2C errors
//ESTOP0;
//}
//}


//If code reached below ESTOP0, I2CA as master transmitter and
//I2CB as slave receiver worked correctly
//Observe the contents of I2CA_TXdata and I2CB_RXdata in memory browser
// Example1: I2CA as Master Transmitter and I2CB working Slave Receiver - PASSED//

ESTOP0;
}


//
// I2CB ISR
//
__interrupt void i2cBISR(void)
{
uint16_t MasterSlave = I2C_getStatus(I2CB.base) & I2C_STS_ADDR_SLAVE;

status_interrupt = I2C_getInterruptStatus(I2CB.base);
status_intoisr = I2C_getRxFIFOStatus(I2CB.base);

uint16_t i;

if(MasterSlave)
{
slave++;

//I2CB working as slave

fifoDepth = I2C_getRxFIFOStatus(I2CB.base);
if (fifoDepth > 0)
{

for (i = 0; i < fifoDepth; i++) {
tempData[i] = I2C_getData(I2CB.base);
}


I2C_clearStatus(I2CB.base, I2C_STS_RX_DATA_RDY);
I2C_clearInterruptStatus(I2CB.base, I2C_INT_RXFF);


if (fifoDepth > 1) {
for (i = 0; i < fifoDepth - 1; i++) {
rData[i] = tempData[i + 1];
}
rData_size = fifoDepth - 1;
} else {
rData_size = 0;
}
}

I2C_clearInterruptStatus(I2CB.base, I2C_INT_RXFF);
}


handleI2C_ErrorCondition(&I2CB);

Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
}


void I2C_GPIO_init(void)
{

// I2CB pins (SDAB / SCLB)
GPIO_setDirectionMode(DEVICE_GPIO_PIN_SDAB, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(DEVICE_GPIO_PIN_SDAB, GPIO_PIN_TYPE_PULLUP);
GPIO_setMasterCore(DEVICE_GPIO_PIN_SDAB, GPIO_CORE_CPU1);
GPIO_setQualificationMode(DEVICE_GPIO_PIN_SDAB, GPIO_QUAL_ASYNC);

GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCLB, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(DEVICE_GPIO_PIN_SCLB, GPIO_PIN_TYPE_PULLUP);
GPIO_setMasterCore(DEVICE_GPIO_PIN_SCLB, GPIO_CORE_CPU1);
GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCLB, GPIO_QUAL_ASYNC);

GPIO_setPinConfig(DEVICE_GPIO_CFG_SDAB);
GPIO_setPinConfig(DEVICE_GPIO_CFG_SCLB);
}

void I2Cinit(void)
{

//I2CB initialization
I2C_disableModule(I2CB_BASE);
I2C_initMaster(I2CB_BASE, DEVICE_SYSCLK_FREQ, 400000, I2C_DUTYCYCLE_50);
I2C_setConfig(I2CB_BASE, I2C_MASTER_SEND_MODE);
I2C_setSlaveAddress(I2CB_BASE, 50);
I2C_disableLoopback(I2CB_BASE);
I2C_setBitCount(I2CB_BASE, I2C_BITCOUNT_8);
I2C_setDataCount(I2CB_BASE, 2);
I2C_setAddressMode(I2CB_BASE, I2C_ADDR_MODE_7BITS);
I2C_enableFIFO(I2CB_BASE);
I2C_clearInterruptStatus(I2CB_BASE, I2C_INT_ADDR_SLAVE | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
I2C_setFIFOInterruptLevel(I2CB_BASE, I2C_FIFO_TXEMPTY, I2C_FIFO_RX16);
I2C_enableInterrupt(I2CB_BASE, I2C_INT_ADDR_SLAVE | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
I2C_setEmulationMode(I2CB_BASE, I2C_EMULATION_FREE_RUN);
I2C_enableModule(I2CB_BASE);

}