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.

TMS320C6672: Externally generated PCIe Legacy INTA is not triggering the associated Event Handler

Part Number: TMS320C6672

Tool/software:

I have a custom board with a C6672, configured as a Root Complex, connected to an external PCIe Endpoint device. The C6672 is running baremetal (no rtos) and I'm using the CSL library to configure interrupts.

During PCIe initialization, I set INTn_EN_SET (0x21800188) and INTn_EN_CLR(0x2180018C) to 1 and all MSIn_IRQ registers to 0 (0x21800100 through 0x21800170)

INTC and CPINTC Configuration results in the following registers being set:
ENABLE_REG unsigned int[32] [0x00000000,0x00040000,0x00000000,0x00000000,0x00000000...] (Hex) 0x02600300
ENABLE_CLR_REG unsigned int[32] [0x00000000,0x00040000,0x00000000,0x00000000,0x00000000...] (Hex) 0x02600380
ENABLE_HINT_REG unsigned int[8] [0x00000001,0x00000000,0x00000000,0x00000000,0x00000000...] (Hex) 0x02601500
GLOBAL_ENABLE_HINT_REG unsigned int 0x00000001 (Hex) 0x02600010

When the external device generates a PCIe Legacy INTA interrupt, I see the following registers are modified:
INTn_RAW_STATUS (0x21800180) = 1
INTn_STATUS (0x21800184) = 1.
RAW_STATUS_REG unsigned int[32] [0x00000000,0x00040000,0x00000000,0x00000000,0x00000000...] (Hex) 0x02600200
ENA_STATUS_REG unsigned int[32] [0x00000000,0x00040000,0x00000000,0x00000000,0x00000000...] (Hex) 0x02600280

However, my ISR connected to the event does not execute.

I can clear the interrupt by writing to a register in the external device, writing a 1 to INTn_STATUS, and writing a 0 to IRQ_EOI (0x21800050). After clearing the interrupt, I verify the interrupt is triggered again by viewing the INTn_RAW_STATUS and INTn_STATUS registers get set back to 1.

I've attached my code below, following the code example in SPRUGW4A KeyStone Architecture Chip Interrupt Controller (CIC) User Guide Section 2.3 Interrupt Servicing.

I would appreciate any advice.

#include <ti/csl/cslr_device.h>
#include <ti/csl/csl_cpIntcAux.h>
#include <csl_intc.h>
#include <csl_intcAux.h>

CSL_IntcContext Intcontext;         //For CorePac INTC
CSL_IntcObj intcPCIe;               //For CorePac INTC
CSL_IntcHandle hIntcPCIe;           //For CorePac INTC
CSL_IntcEventHandlerRecord Record;  //For CorePac INTC
CSL_CPINTC_Handle cphnd;            //For chip-level CIC
Int16 sys_event;
Int16 host_event;

void InitializeInterrupts( void )
{
   CSL_IntcGlobalEnableState state;
   /* Setup the global Interrupt */
   Intcontext.numEvtEntries = 1;
   Intcontext.eventhandlerRecord = &Record;
   CSL_intcInit( &Intcontext );
   CSL_intcGlobalNmiEnable( );     /* Enable NMIs */
   CSL_intcGlobalEnable( &state ); /* Enable Global Interrupts */
   cphnd = CSL_CPINTC_open( 0 );   /* Initialize the chip level CIC CSL handle. */
}

/**
 * This method connects a System Event to a Core Event.
 * @note System Events are listed in SPRS708E Table 7-38 CIC0 Event Inputs (Secondary Interrupts for C66x CorePacs)
 * @note Host Events are listed in Figure 7-32 TMS320C6672 System Event Inputs
 * @param[in] kusSystemEvent  System Event from SPRS708E Table 7-38 CIC0 Event Inputs
 * @param[in] kusHostEvent    Host Event from SPRS708E Figure 7-32 TMS320C6672 System Event Inputs
 * @return This method returns nothing.
 */
void ConnectEvents( uint16_t kusSystemEvent, uint16_t kusHostEvent )
{
   CSL_IntcParam vectId1;
   /// @par Process Design Language
   /// -# Record the System Event, Host Event, and MOL pointer
   sys_event = kusSystemEvent;
   host_event = kusHostEvent;

   /// -# Map the CIC input event to the CorePac input event
   ///   -# Map the input system event to a channel.
   ///      - Note, the mapping from channel to Host event is fixed.
   ///   -# Enable the system interrupt
   ///   -# Enable the channel (output).
   ///   -# Enable all host interrupts.
   CSL_CPINTC_disableAllHostInterrupt( cphnd );
   CSL_CPINTC_setNestingMode( cphnd, CPINTC_NO_NESTING );
   CSL_CPINTC_mapSystemIntrToChannel( cphnd, sys_event, 0 );
   CSL_CPINTC_enableSysInterrupt( cphnd, sys_event );
   CSL_CPINTC_enableHostInterrupt( cphnd, 0 );
   CSL_CPINTC_enableAllHostInterrupt( cphnd );

   /// -# Hook an ISR to the CorePac input event.
   ///   -# Hook the ISR (CSL_intcPlugEventHandler)
   ///   -# Clear the Interrupt
   ///   -# Enable the Event & the interrupt
   vectId1 = CSL_INTC_VECTID_12; //4 through 15 are available
   hIntcPCIe =
      CSL_intcOpen(
         &intcPCIe,
         host_event, // selected event ID
         &vectId1,
         NULL );
   Record.handler = ( CSL_IntcEventHandler )&SISR;
   Record.arg = ( void* )host_event;
   CSL_intcPlugEventHandler( hIntcPCIe, &( Record ) );
   CSL_intcHwControl( hIntcPCIe, CSL_INTC_CMD_EVTCLEAR, NULL );
   CSL_intcHwControl( hIntcPCIe, CSL_INTC_CMD_EVTENABLE, NULL );
}

void SISR( void* kopEventId )
{
   /// @par Process Design Language
   /// -# Disable the CIC0 host interrupt output
   CSL_CPINTC_disableHostInterrupt( cphnd, 0 );

   /// -# Clear the CIC0 system interrupt
   CSL_CPINTC_clearSysInterrupt( cphnd, sys_event );

   ...
   /// -# Service the interrupt at source
   ...

   /// -# Clear the CorePac interrupt
   CSL_intcHwControl( hIntcPCIe, CSL_INTC_CMD_EVTCLEAR, NULL );

   /// -# Enable the CIC0 host interrupt output
   CSL_CPINTC_enableHostInterrupt( cphnd, 0 );
}

void main( void )
{
   ...
   InitializeInterrupts( );
   ConnectEvents( CSL_INTC0_PCIEXPRESS_LEGACY_INTA, CSL_GEM_CIC0_OUT0_OR_CIC1_OUT0 );
   ...
}

  • Hi,

    The engineer responsible is currently out of office. Please expect 1 day delay in response.

  • Thank you for the update.

  • Hi Edward,

    Could you update the code to set the Core-Pac event parameter to 91 in place of 102?

    Reference Documenthttps://www.ti.com/lit/ds/sprs708e/sprs708e.pdf

    Best Regards,

    Betsy Varughese

  • Hello Besty, I replaced the Core-Pac event parameter with 91 instead of 102, but I did not see any difference in the behavior.

  • I have the interrupts working. It seems the CSL_IntcEventHandlerRecord must be an array of 2 in my case. Here is the final code:

    // TI LLD Includes
    #include <ti/csl/cslr_device.h>
    #include <ti/csl/csl_cpIntcAux.h>
    #include <csl_intc.h>
    #include <csl_intcAux.h>
    #include <ti/csl/cslr_pcie.h>
    
    CSL_IntcContext intcContext;                //For CorePac INTC
    CSL_IntcObj intcObj;                        //For CorePac INTC
    CSL_IntcHandle intcHandle;                  //For CorePac INTC
    CSL_IntcEventHandlerRecord intcRecord[ 2 ]; //For CorePac INTC
    CSL_IntcParam intcVectorId = CSL_INTC_VECTID_4;
    CSL_IntcEventId intcEventId = CSL_GEM_INTC0_OUT0_OR_INTC1_OUT0;
    CSL_CPINTC_Handle cpintcHandle;              //For chip-level CIC
    CSL_CPINTCSystemInterrupt cpintcSystemInterrupt = CSL_INTC0_PCIEXPRESS_LEGACY_INTA;
    CSL_CPINTCChannel cpintcChannel = 0;
    
    void InitializeInterrupts( void )
    {
       CSL_IntcGlobalEnableState state;
       /* Setup the global Interrupt */
       intcContext.numEvtEntries = 2;
       intcContext.eventhandlerRecord = intcRecord;
       CSL_intcInit( &intcContext );
       CSL_intcGlobalNmiEnable( );     /* Enable NMIs */
       CSL_intcGlobalEnable( &state ); /* Enable Global Interrupts */
    }
    
    /**
     * This method connects a System Event to a Core Event.
     * @note System Events are listed in SPRS708E Table 7-38 CIC0 Event Inputs (Secondary Interrupts for C66x CorePacs)
     * @param[in] kuiCPINTCSystemInterrupt  System Event from SPRS708E Table 7-38 CIC0 Event Inputs
     * @param[in] kuiCPINTCChannel          Channel
     * @return This method returns nothing.
     */
    void ConnectEvent(
       CSL_CPINTCSystemInterrupt kuiCPINTCSystemInterrupt,
       CSL_CPINTCChannel kuiCPINTCChannel )
    {
       /// @par Process Design Language
       /// -# Record the CPINTC System Interrupt and CPINTC Channel
       cpintcSystemInterrupt = kuiCPINTCSystemInterrupt;
       cpintcChannel = kuiCPINTCChannel;
    
       /// -# Map the CIC input event to the CorePac input event
       ///   -# Map the input system event to a channel.
       ///      - Note, the mapping from channel to Host event is fixed.
       ///   -# Enable the system interrupt
       ///   -# Enable the channel (output).
       ///   -# Enable all host interrupts.
       cpintcHandle = CSL_CPINTC_open( 0 );   /* Initialize the chip level CIC CSL handle. */
       CSL_CPINTC_disableAllHostInterrupt( cpintcHandle );
       CSL_CPINTC_setNestingMode( cpintcHandle, CPINTC_NO_NESTING );
       CSL_CPINTC_clearSysInterrupt( cpintcHandle, cpintcSystemInterrupt );
       CSL_CPINTC_enableSysInterrupt( cpintcHandle, cpintcSystemInterrupt );
       CSL_CPINTC_mapSystemIntrToChannel( cpintcHandle, cpintcSystemInterrupt, cpintcChannel );
       CSL_CPINTC_enableHostInterrupt( cpintcHandle, cpintcChannel );
       CSL_CPINTC_enableAllHostInterrupt( cpintcHandle );
    }
    
    
    void InstallHandler(
       CSL_IntcEventId kiIntcEventId,
       CSL_IntcParam kiIntcVectorId )
    {
       CSL_Status cslStatus;
    
       /// @par Process Design Language
       /// -# Record the INTC Event ID and INTC Vector ID
       intcEventId = kiIntcEventId;
       intcVectorId = kiIntcVectorId,
    
       /// -# Hook an ISR to the CorePac input event.
       ///   -# Hook the ISR (CSL_intcPlugEventHandler)
       ///   -# Clear the Interrupt
       ///   -# Enable the Event & the interrupt
       intcHandle =
          CSL_intcOpen(
             &intcObj,
             intcEventId, // selected event ID
             &intcVectorId,
             &cslStatus );
       intcRecord[ 0 ].handler = ( CSL_IntcEventHandler )ISR;
       intcRecord[ 0 ].arg = ( void* )intcEventId;
       CSL_intcPlugEventHandler( intcHandle, intcRecord );
       CSL_intcHwControl( intcHandle, CSL_INTC_CMD_EVTCLEAR, NULL );
       CSL_intcHwControl( intcHandle, CSL_INTC_CMD_EVTENABLE, NULL );
    }
    
    void ISR( void* kopEventId )
    {
       /// @par Process Design Language
       /// -# Disable the CIC0 host interrupt output
       CSL_CPINTC_disableHostInterrupt( cpintcHandle, cpintcChannel );
    
       ...
       
       /// -# Service the interrupt at source
    
       /// -# Clear the CorePac interrupt
       CSL_intcHwControl( intcHandle, CSL_INTC_CMD_EVTCLEAR, NULL );
       CSL_intcEventClear( intcEventId );
    
       /// -# Clear the CIC0 system interrupt
       CSL_CPINTC_clearSysInterrupt( cpintcHandle, cpintcSystemInterrupt );
    
       /// -# Enable the CIC0 host interrupt output
       CSL_CPINTC_enableHostInterrupt( cpintcHandle, cpintcChannel );
    }
    
    void main( void )
    {
       ...
       /// @par Process Design Language
       /// -# Initialize Interrupt
       InitializeInterrupts( );
    
       /// -# Connect the PCIe Legacy INTA to the Host Event
       ConnectEvent(
          CSL_INTC0_PCIEXPRESS_LEGACY_INTA,
          0 );
    
       /// -# Install the Handler
       InstallHandler(
          CSL_GEM_INTC0_OUT0_OR_INTC1_OUT0, 
          CSL_INTC_VECTID_4 );
    }