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
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 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); }