Hello everyone,
I'm experiencing some issues when using I2C with the F28379D as a slave device.
- I have set the I2C slave address of the F28379D to
0x50, but on the master side, the detected address is0x00. If I try to force a write operation to0x50, the transmission fails. 

- When writing to address
0x00from 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 to11, and so on. 


- The first transmitted value is
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);
}