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.

C6670 Chip Level Interrupts - I2C/SPI

Hi I'm trying to implement the chip level interrupts for using the SPI/I2C for send/receive events, the problem I seem to be having is that the interrupts don't fire more than once.

 

/* Interrupt CorePac IDs */

//#define I2C_CORE_INTC CSL_GEM_INTC0_OUT_64_PLUS_10_MUL_N // CorePac Interrupt to route Chip Level Interrupt to (OUT2 0x3c = 60)

//#define I2C_CORE_INTC_CHANNEL (64 + 10 * DNUM)

#define I2C_CORE_INTC CSL_GEM_INTC0_OUT4 // CorePac Interrupt to route Chip Level Interrupt to (OUT2 0x3c = 60)

#define I2C_CORE_INTC_CHANNEL 4

/* Interrupt Chip Level IDs */

#define I2C_CHIP_INTC CSL_INTC0_I2CINT

#define I2C_CHIP_INTC_RX CSL_INTC0_I2CREVT

#define I2C_CHIP_INTC_TX CSL_INTC0_I2CXEVT

bool ti_interrupt_init() {

uint i;

long long start = ti_clock_count();

CSL_Status intStat;

 

Context.numEvtEntries = INTERRUPT_EVENTS; 

Context.eventhandlerRecord = (CSL_IntcEventHandlerRecord*) &(Record);

 

for(i = 0; i < 7; i++) {

switch(i) {

case 0:

intStat = CSL_intcInit(&(gIntc.Context));

break;

case 1:

intStat = CSL_intcExcepAllClear(CSL_INTC_EXCEP_0TO31,0xFFFF); // clear all exceptions

break;

case 2:

intStat = CSL_intcExcepAllClear(CSL_INTC_EXCEP_32TO63,0xFFFF);

break;

case 3:

intStat = CSL_intcExcepAllClear(CSL_INTC_EXCEP_64TO95,0xFFFF);

break;

case 4:

intStat = CSL_intcExcepAllClear(CSL_INTC_EXCEP_96TO127,0xFFFF);

break;

case 5:

intStat = CSL_intcGlobalNmiEnable(); // global NMI enable

break;

case 6:

intStat = CSL_intcGlobalEnable(NULL); // global intC enable

break;

default:

break;

}

if(intStat != CSL_SOK) {

/* Failed CSL Call */

printf("Interrupt Initialization Failed - %d \n", i);

return false;

}

}

 

/* Initialize the chip level INTC CSL handle. */

cphnd = CSL_CPINTC_open(0);

if (cphnd == 0) {

printf("Cannot initialize CPINTC\n");

return false;

}

return true;

}

bool twi_interrupt_setup(void) {

    CSL_IntcParam       vectId;

    CSL_IntcEventHandlerRecord      EventRecord;

    CSL_IntcObj                     intcObj0;

 

    /* Disable all host interrupts. */

    CSL_CPINTC_disableAllHostInterrupt(cphnd);

 

    /* Configure no nesting support in the CPINTC Module. */

    CSL_CPINTC_setNestingMode(cphnd, CPINTC_NO_NESTING);

 

    /* Clear CSL_INTC0_VUSR_INT_O */

   CSL_CPINTC_clearSysInterrupt(cphnd, I2C_CHIP_INTC);

    /* Enable it */

    CSL_CPINTC_enableSysInterrupt(cphnd, I2C_CHIP_INTC);

    CSL_CPINTC_mapSystemIntrToChannel(cphnd, I2C_CHIP_INTC, I2C_CORE_INTC_CHANNEL);

    /* Do not need to use CSL_CPINTC_mapChannelToHostInterrupt because the mapping is static

     * such that channel and host interrupt are the same

     */

    /* Enable it */

    CSL_CPINTC_enableHostInterrupt(cphnd, I2C_CORE_INTC_CHANNEL);

    CSL_CPINTC_enableAllHostInterrupt(cphnd);

    /* Opening a handle for CIC out 0 onto CPU vector 9 */

    vectId = I2C_INTC_VECTID;

    intcI2cHnd = CSL_intcOpen (&intcObj0, I2C_CORE_INTC, &vectId, NULL);

    EventRecord.handler = ti_i2c_isr;

    EventRecord.arg = (void *)I2C_CORE_INTC;

    CSL_intcPlugEventHandler(intcI2cHnd, &EventRecord); 

    CSL_intcHwControl(intcI2cHnd, CSL_INTC_CMD_EVTCLEAR, NULL);

    CSL_intcHwControl(intcI2cHnd, CSL_INTC_CMD_EVTENABLE, NULL);

return true;

}

I had this (or similar code should I say) working fine on the c6474 using the cpc interrupts, but I can't seem to get it working right w/ the C6670
/* Acknowledge CorePac interrupt */
CSL_intcHwControl(intcI2cHnd, CSL_INTC_CMD_EVTCLEAR, NULL);
/* Acknowledge cp intc interrupt */
CSL_CPINTC_clearSysInterrupt(cphnd, I2C_CHIP_INTC);
is called at the end of the routine to clear the flags, but it does not seem to want to fire again once called.  
I'm currently using an evm6670le board and I'm trying to read the boot eeprom as my interface. (I'm also working on trying to get the SPI interrupt going but have a similar issue with it, I figure once I get one solved, I can get the other one working w/o any issues).
Now I do notice that the 6670 does have more I2C INT0 flags, like an RX and TX flag, but it did not seem to make a difference when I initialized it to those vectors, and I do have a timer firing fine.  Any hints or examples that I could be pointed to would be greatly appreciated.
Thanks,
Erick

  • Ok, my I2C bus was locked up, so it's actually working fine... I am still having issues with the SPI though, that is set up the same way, but it only comes up once, I add a byte in the transmit buffer inside the interrupt, but it never fires again.  I set it up exactly the same as the I2C (except using different vectors and outputs) but it does not seem to want to fire more than once.

    Erick

  • Erick,

    In your ISR routine (might be ti_spi_isr), have you followed the step as below to clear the status and disable/enable the host interrupt please?

    1 Receive the interrupt

    2 Disable the interrupt:

        Write the Interrupt Controller Host Interrupt Disable Register

    3 Determine the exact interrupt and clear the status of the interrupt:

        Read the Interrupt Controller Enabled Status Register (for bit flags)

        Write to the Interrupt Controller Status Clear Register (to clear bit)

    4 Execute user ISR code

    5 Write the Interrupt Controller Host Interrupt Enable Register

    6 Return from interrupt

     

    Sincerely,

    Steven

     

  • Thanks Steven,

    I was not disabling (and re-enabling)  the interrupt in the ISR (I also did not in the I2C but it seems that the twi is slow enough that it does not matter).

    Anyway, everything works great now, thank you very much.

    Erick