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.
Hi team,
I'm working on developing code for an I2C slave that triggers an interrupt once the FIFO is full.
I am successfully entering my ISR but I am having trouble clearing the interrupt bit. Once I exit my ISR it returns to it immediately afterwards.
Here is what I have in my main to enable the interrupt:
I2CSlaveIntEnableEx(I2C0_BASE, I2C_SLAVE_INT_RX_FIFO_FULL);
And here is what I have in my ISR to clear the interrupt:
I2CSlaveIntClearEx(I2C0_BASE, I2C_SLAVE_INT_RX_FIFO_FULL);
Looking at the I2C registers, I see that the RXFFRIS bit is not cleared in the I2CSRIS register.
Regards,
Akash Patel
Hi Amit,
I wait for the FIFO to contain 8 elements (i.e. be full) to call the interrupt. Then, once in the ISR I go ahead and read them. Here is the whole code for my ISR:
void I2CSlaveISR(void) { I2CSlaveIntClearEx(I2C0_BASE, I2C_SLAVE_INT_RX_FIFO_FULL); UARTprintf("In I2C0 ISR\n"); uint8_t i; for (i = 0 ; i < 8; ++i){ // Get the data from the FIFO pui32DataRx[i] = I2CFIFODataGet(I2C0_BASE); // Display the data that the slave has received. UARTprintf("Received: '%c'\n", pui32DataRx[i]); } I2CRxFIFOFlush(I2C0_BASE); }
Hi Amit,
Thanks for your help! I am now clearing the interrupt at the end and it seems to be working!
Here is my new ISR code:
void I2CSlaveISR(void) { UARTprintf("In I2C0 ISR\n"); uint8_t i; for (i = 0 ; i < 8; ++i){ // Get the data from the FIFO pui32DataRx[i] = I2CFIFODataGet(I2C0_BASE); // Display the data that the slave has received. UARTprintf("Received: '%c'\n", pui32DataRx[i]); } I2CSlaveIntClearEx(I2C0_BASE, I2C_SLAVE_INT_RX_FIFO_FULL); }
Here is what my interrupt register looks like as I exit the ISR:
Regards,
Akash Patel
Hi Amit,
Sorry about that, here is the I2C_SIMR register:
Another question that I had was with regards to configuring the FIFO and the FIFO trigger.
I have this piece of code to configure the FIFO:
I2CRxFIFOConfigSet(I2C0_BASE, (I2C_FIFO_CFG_RX_SLAVE | I2C_FIFO_CFG_RX_TRIG_7));
Can you explain the trigger operation?
I have the trigger level set to 7. From my understanding this trigger is used if you want to trigger when there are 7 or more items in the FIFO. Is there an associated interrupt that will fire so when there are >= 7 in the FIFO? As you see above right now I am using the FIFO Full interrupt.
Regards,
Akash Patel
Hi Amit,
I am now trying to build the accompanying master code for this. I want to set up multiple I2C Masters on one TIVA board to continuously transmit data. I am starting out with just one I2C first and then will expand to multiple. Below is the code that I have, however, I am having issues triggering the interrupt and entering the ISR. Any suggestions on what I can do to enter the ISR?
int main(void) { g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // Set up the serial console InitConsole(); // Display title UARTprintf("I2C Evaluation - Master\n"); // Enable & configure I2C0, pb2 - scl, pb3 - sda SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinConfigure(GPIO_PB3_I2C0SDA); GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3); IntMasterEnable(); // Enable the I2C0 master module. I2CMasterEnable(I2C0_BASE); // Initialize the I2C clock I2CMasterInitExpClk(I2C0_BASE, g_ui32SysClock, false); // Set the slave address I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS0, false); // Set up the TX FIFO I2CTxFIFOConfigSet(I2C0_BASE, I2C_FIFO_CFG_TX_MASTER); // Enable I2C0 interrupts I2CMasterIntEnableEx(I2C0_BASE, I2C_MASTER_INT_TX_FIFO_EMPTY); IntEnable(INT_I2C0); I2CTxFIFOFlush(I2C0_BASE); // Indicate the direction of the data. UARTprintf("Tranferring from: Master -> Slave\n"); I2CFIFODataPut(I2C0_BASE, 0x48); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_FIFO_SINGLE_SEND); while (1); } void I2C0MasterISR(void) { UARTprintf("In I2C0 ISR\n"); uint8_t i; for (i = 0 ; i < 8; ++i){ // Put the data on the FIFO I2CFIFODataPut(I2C0_BASE, (i + 72)); // Display the data put on the FIFO UARTprintf("Put onto FIFO: '%c'\n", (i + 72)); } I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); I2CMasterIntClearEx(I2C0_BASE, I2C_MASTER_INT_TX_FIFO_EMPTY); }
Regards,
Akash Patel
Hi Amit,
I added the trigger functionality although I'm still not sure why I need that because I only wanted the interrupt to fire when my FIFO is empty and there is an interrupt for that already. I looked at the app note and now I have the code going into the ISR once but then it doesn't fire another interrupt after that even though the FIFO is empty and I am below the trigger.
int main(void) { g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // Set up the serial console InitConsole(); // Display title UARTprintf("I2C Evaluation - Master\n"); // Enable & configure I2C0, pb2 - scl, pb3 - sda SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinConfigure(GPIO_PB3_I2C0SDA); GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3); IntMasterEnable(); // Enable the I2C0 master module. I2CMasterEnable(I2C0_BASE); // Initialize the I2C clock I2CMasterInitExpClk(I2C0_BASE, g_ui32SysClock, false); // Set the slave address I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS0, false); // Set up the TX FIFO I2CTxFIFOConfigSet(I2C0_BASE, I2C_FIFO_CFG_TX_MASTER | I2C_FIFO_CFG_TX_TRIG_4); I2CTxFIFOFlush(I2C0_BASE); // Enable I2C0 interrupts I2CMasterIntEnableEx(I2C0_BASE, (I2C_MASTER_INT_TX_FIFO_REQ|I2C_MASTER_INT_TX_FIFO_EMPTY)); I2CMasterBurstLengthSet(I2C0_BASE, 8); IntEnable(INT_I2C0); // Indicate the direction of the data. UARTprintf("Tranferring from: Master -> Slave\n"); I2CFIFODataPut(I2C0_BASE, 0x48); I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_FIFO_SINGLE_SEND); while (1){ } } void I2C0MasterISR(void) { UARTprintf("In I2C0 ISR\n"); uint8_t i; for (i = 0 ; i < 8; ++i){ // Put the data on the FIFO I2CFIFODataPut(I2C0_BASE, (i + 72)); // Display the data put on the FIFO. UARTprintf("Put onto FIFO: '%c'\n", (i + 72)); } I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); I2CMasterIntClearEx(I2C0_BASE, (I2C_MASTER_INT_TX_FIFO_REQ | I2C_MASTER_INT_TX_FIFO_EMPTY)); }
Regards,
Akash Patel