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.
Tool/software:
I'm experiencing some issues when using I2C with the F28379D as a slave device.
0x50
, but on the master side, the detected address is 0x00
. If I try to force a write operation to 0x50
, the transmission fails.0x00
from the master, there is a data delay issue on the F28379D slave side. For example:
10
, but the slave does not update.11
, but the slave only updates to the first value (10).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); }
Hi, I'd appreciate a response soon. Let me know if you need any more information. Thanks
Hi TingHsuan,
Apologies for the delay. Could you confirm if the C2000 target is only in receiver mode or also transmitter? You'll need the 'I2C_setOwnAddress' function to set the own address for the I2C target. It's is compared against the target address sent by an I2C controller. I believe that line 290 is unnecessary if I2CB is only acting as the target as per your above comments. The example configures I2CA and I2CB as controller because there are four combinations of I2C operations happening.
In addition, if you are communicating with a temp sensor, you could also use any of the EEPROM examples as a basis instead too.
Best Regards,
Aishwarya
Thank you for your response.
I2C_setOwnAddress
fixed my first problem."I2C_setConfig(I2CB_BASE, I2C_MASTER_SEND_MODE);"
to "I2C_setConfig(I2CB_BASE, I2C_SLAVE_RECEIVE_MODE);"
—but in this case, the I2C communication did not work. It only works when set to "I2C_MASTER_SEND_MODE"
or "I2C_MASTER_RECEIVE_MODE"
, and my second issue still remains.Do you have any suggestions? Thanks!
Hi TingHsuan,
Please expect a delayed response as Aishwarya is currently out of office for the next week. I apologize for any inconvenience.
Best Regards,
Delaney