catalogue
1, Two interrupt events for C66x
2. Mapping to secondary events through CIC
2, Method of interrupt configuration
a,configuring the CorePac's INTC
2. Interrupt configuration of sysbios
1, Two interrupt events for C66x
The CorePac interrupt controller allows 124 interrupts to be mapped to the DSP core and has events, as shown in the figure: events can be mapped separately
To the CPU, multiple events can also form a combination, and events can be mapped to the CPU.
At the same time, a CPU core has 16 interrupts, and 4-15 bits can mask configurable interrupts.
1. 98 primary events
Under SYSBIOS, HWI module can be used for direct configuration, and the hardware interrupt number can be queried from the interrupt manual.
If you do not run SYSBIOS, you need to configure the interrupt.
2. Mapping to secondary events through CIC
SYSBIOS does not support the direct mapping of CIC events to core interrupts, so first configure CIC and map system interrupt
It is Host interrupt. The Event id from Host interrupt to Event id is fixed, which can be queried in the manual; Next, perform the first step
Step.
2, Method of interrupt configuration
1.CSL method configuration
a,configuring the CorePac's INTC
Map Event ID63 to CPU interrupt 4
{ C SL_IntcObj intcObj63p; CSL_IntcGlobalEnableState state; CSL_IntcContext context; CSL_Status intStat; CSL_IntcParam vectId; context.numEvtEntries = 0; context.eventhandlerRecord = NULL; CSL_intcInit(&context); CSL_intcGlobalNmiEnable(); intStat = CSL_intcGlobalEnable(&state); /*The comment part is the modification part*/ // interrupt number vectId = CSL_INTC_VECTID_4; //CSL_INTC_EVENTID_63 stands for Event ID63 hIntc63 = CSL_intcOpen (&intcObj63, CSL_INTC_EVENTID_63, &vectId, NULL); //event63Handler interrupt function EventRecord.handler = &event63Handler; EventRecord.arg = hIntc63; CSL_intcPlugEventHandler(hIntc63,&EventRecord); CSL_intcHwControl(hIntc63,CSL_INTC_CMD_EVTENABLE, NULL); //Close interrupt CSL_IntcClose(hIntc63); } / /Interrupt function oid event63Handler(CSL_IntcHandle hIntc) { . . . }
CSL_intcGlobalEnable() and CSL_intcGlobalNmiEnable() APIs
CSL_ The intcopen (...) API is an interrupt mapping. When the mapping is successful, the event will be saved to the interrupt and a valid handle will be returned.
CSL_intcPlugEventHandler(...) API binding event and interrupt functions
CSL_intcHwControl(...) API enable event
CSL_ The intcclose (...) API deallocates and releases events
b ,Configuring CIC
/* Disable all host interrupts. */ CSL_CPINTC_disableAllHostInterrupt(hnd); /* Configure no nesting support in the CPINTC Module. */ //KeyStone devices does not support interrupt preemption CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING); /* We now map System Interrupt 0 - 3 to channel 3 */ CSL_CPINTC_mapSystemIntrToChannel (hnd, 0 , 2); CSL_CPINTC_mapSystemIntrToChannel (hnd, 1 , 4); CSL_CPINTC_mapSystemIntrToChannel (hnd, 2 , 5); CSL_CPINTC_mapSystemIntrToChannel (hnd, 3 , 3); /* Enable system interrupts 0 - 3 */ CSL_CPINTC_enableSysInterrupt (hnd, 0); CSL_CPINTC_enableSysInterrupt (hnd, 1); CSL_CPINTC_enableSysInterrupt (hnd, 2); CSL_CPINTC_enableSysInterrupt (hnd, 3); /* Enable Host interrupt 3 */ CSL_CPINTC_enableHostInterrupt (hnd, 3); /* Enable all host interrupts also. */ CSL_CPINTC_enableAllHostInterrupt(hnd);
' pdk_C6678_x_x_x_xx\packages\ti\csl\example\cpintc 'you can learn more about CIC
c,Example
01
/************************ --- Header file ---************************/ #include <stdio.h> #include <ti/csl/csl.h> #include <ti/csl/tistdtypes.h> #include <ti/csl/csl_error.h>#include <ti/csl/csl_intc.h> #include <ti/csl/csl_cpIntcAux.h> #include <ti/csl/csl_chip.h> #include <ti/csl/soc.h> /************************ --- Header file ---************************/ /************************ --- INTC Initializations --- ************************/ CSL_IntcEventHandlerRecord hyplnkExampleEvtHdlrRecord[ 6]; CSL_IntcContext hyplnkExampleIntcContext; CSL_IntcHandle hyplnkExampleIntcHnd[ 6]; #define hyplnk_EXAMPLE_COREPAC_VEC 4 #define hyplnk_EXAMPLE_COREPAC_INT_INPUT 0x15 /* Note that hyplnk_EXAMPLE_COREPAC_VEC = 4, hyplnk_EXAMPLE_COREPAC_INT_INPUT = 0x15, */ /* CSL_INTC_CMD_EVTCLEAR = 3, CSL_INTC_CMD_EVTENABLE = 0 */ //hyplnk_EXAMPLE_COREPAC_VEC = 4; Map to interrupt 4; CSL_IntcParam vectId = hyplnk_EXAMPLE_COREPAC_VEC; //hyplnk_EXAMPLE_COREPAC_INT_INPUT = 21;Event ID is 21 Int16 eventId = hyplnk_EXAMPLE_COREPAC_INT_INPUT; CSL_IntcGlobalEnableState state; /* INTC module initialization */ hyplnkExampleIntcContext.eventhandlerRecord = hyplnkExampleEvtHdlrRecord; hyplnkExampleIntcContext.numEvtEntries = 2; CSL_intcInit(&hyplnkExampleIntcContext); /* Enable NMIs */ CSL_intcGlobalNmiEnable(); /* Enable global interrupts */ CSL_intcGlobalEnable(&state); hyplnkExampleIntcHnd = CSL_intcOpen (&hyplnkExampleIntcObj, eventId, &vectId, NULL); hyplnkExampleEvtHdlrRecord[ 0].handler = hyplnkExampleIsr; hyplnkExampleEvtHdlrRecord[ 0].arg = ( void *)eventId; CSL_intcPlugEventHandler(hyplnkExampleIntcHnd, hyplnkExampleEvtHdlrRecord); /* Clear the event in case it is pending */ CSL_intcHwControl(hyplnkExampleIntcHnd, CSL_INTC_CMD_EVTCLEAR, NULL); /* Enable event */ CSL_intcHwControl(hyplnkExampleIntcHnd, CSL_INTC_CMD_EVTENABLE, NULL); /************************ --- INTC Initializations --- ************************/ /************************ --- CIC Initializations --- ************************/ #define hyplnk_EXAMPLE_INTC_OUTPUT 43 CSL_CPINTC_Handle hnd; hnd = CSL_CPINTC_open ( 0); /* Disable all host interrupts. */ CSL_CPINTC_disableAllHostInterrupt(hnd); /* Configure no nesting support in the CPINTC Module */ CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING); /* Clear Hyperlink system interrupt number 111 */ //CSL_INTC0_VUSR_INT_O is the system Interrupt id CSL_CPINTC_clearSysInterrupt (hnd, CSL_INTC0_VUSR_INT_O); /* Enable Hyperlink system interrupt number 111 on CIC0 */ CSL_CPINTC_enableSysInterrupt (hnd, CSL_INTC0_VUSR_INT_O); /* Map System Interrupt to Channel. */be careful: 6678 in host interrupt And channel Is a one-to-one correspondence. 02 /* Note that hyplnk_EXAMPLE_INTC_OUTPUT = 32 + (11 * CoreNumber) = 43 for Core0*/ CSL_CPINTC_mapSystemIntrToChannel (hnd, CSL_INTC0_VUSR_INT_O, hyplnk_EXAMPLE_INTC_OUTPUT); /* Enable the Host Interrupt */ CSL_CPINTC_enableHostInterrupt (hnd, hyplnk_EXAMPLE_INTC_OUTPUT); CSL_CPINTC_enableAllHostInterrupt(hnd); /************************ --- CIC Initializations --- ************************/
Note: host interrupt and channel in 6678 are one-to-one correspondence.
02
#include <stdio.h> #include <ti/csl/csl.h> #include <ti/csl/tistdtypes.h> #include <ti/csl/csl_error.h> #include <ti/csl/csl_intc.h> #include <ti/csl/csl_cpIntcAux.h> #include <ti/csl/csl_chip.h> #include <ti/csl/soc.h> #define QPEND_IDX 5 #define FIRST_QPEND_QUEUE 662 #define FIRST_QPEND_CIC0_OUT_EVENT 56 /* Function declarations */ void init_interrupt_controllers(); void setup_qpend_interrupt(Uint16 qnum,Uint16 CorePac_event); /* Global variable declarations */ CSL_IntcContext Intcontext; //For CorePac INTC CSL_IntcObj intcQmss; //For CorePac INTC CSL_IntcHandle hIntcQmss[ 6]; //For CorePac INTC CSL_IntcEventHandlerRecord Record[ 6]; //For CorePac INTC CSL_CPINTC_Handle cphnd; //For chip-level CIC Int16 sys_event; Int16 host_event; void main(void) { . ..... /* Init Interrupt Controllers including chip-level CIC and CorePac INTC.*/ init_interrupt_controllers(); /* Setup ISR for QMSS que pend queue */ /* Queue pending signals are from 662 to 671 to CIC0 */ setup_qpend_interrupt(FIRST_QPEND_QUEUE, FIRST_QPEND_CIC0_OUT_EVENT); ...... } / * Perform one-time initialization of chip-level and CorePac * interrupt controllers. */ void init_interrupt_controllers() { C SL_IntcGlobalEnableState state; /* Setup the global Interrupt */ Intcontext.numEvtEntries = 6; Intcontext.eventhandlerRecord = Record; CSL_intcInit(&Intcontext); /* Enable NMIs */ CSL_intcGlobalNmiEnable(); /* Enable Global Interrupts */ CSL_intcGlobalEnable(&state); /* Initialize the chip level CIC CSL handle. */ cphnd = CSL_CPINTC_open( 0); if (cphnd == 0) { p rintf ("Cannot initialize CPINTC\n"); return; } } / * This function connects a QMSS Queue Pend interrupt to a core event*/ void setup_qpend_interrupt(Uint16 qnum, Uint16 CorePac_event) { I nt16 chan; CSL_IntcParam vectId1; /* These are event input index of CIC0 for Que_pend events from Que Manager */ Uint8 events[ 10] = { 134, 135, 136, 137, 138, 139, 140, 141, 142, 175}; /* Step 1: Translate the queue number into the CIC input event. */ /* qnum is expected to be 662..671 */ chan = (qnum - FIRST_QPEND_QUEUE); if ((chan < 0) || (chan > 10)) { p rintf ("Invalid Queue Pend queue %d\n", qnum); return; } s ys_event = events[chan]; /* Step 2: Map the CIC input event to the CorePac input event * (which are 56 to 63). */ CSL_CPINTC_disableAllHostInterrupt(cphnd); CSL_CPINTC_setNestingMode(cphnd, CPINTC_NO_NESTING); /* Map the input system event to a channel. Note, the * mapping from channel to Host event is fixed.*/ CSL_CPINTC_mapSystemIntrToChannel(cphnd, sys_event, 0); /* Enable the system interrupt */ CSL_CPINTC_enableSysInterrupt(cphnd, sys_event); host_event = CorePac_event - FIRST_QPEND_CIC0_OUT_EVENT; /* Enable the channel (output). */ CSL_CPINTC_enableHostInterrupt(cphnd, host_event); /* Enable all host interrupts. */ CSL_CPINTC_enableAllHostInterrupt(cphnd); /* Step 3: Hook an ISR to the CorePac input event. */ vectId1 = CSL_INTC_VECTID_12; //4 through 15 are available hIntcQmss[QPEND_IDX] = CSL_intcOpen(&intcQmss, CorePac_event, // selected event ID &vectId1, NULL); /* Hook the ISR */ Record[QPEND_IDX].handler = (CSL_IntcEventHandler)&QPEND_USER_DEFINED_ISR; Record[QPEND_IDX].arg = ( void *)CorePac_event; CSL_intcPlugEventHandler(hIntcQmss[QPEND_IDX],&(Record[QPEND_IDX])); /* Clear the Interrupt */ CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTCLEAR, NULL); /* Enable the Event & the interrupt */ CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTENABLE, NULL); return; } / * This function ISR for QPEND interrupts. Note the interrupt is routed through chip-level CIC */ void QPEND_USER_DEFINED_ISR (Uint32 eventId) { / * Disable the CIC0 host interrupt output */ CSL_CPINTC_disableHostInterrupt(cphnd, host_event); /* Clear the CIC0 system interrupt */ CSL_CPINTC_clearSysInterrupt(cphnd, sys_event); ...... (service the interrupt at source) (clear the source interrupt flag is typically the first step in the service) /* Clear the CorePac interrupt */ CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTCLEAR, NULL); /* Enable the CIC0 host interrupt output */ CSL_CPINTC_enableHostInterrupt(cphnd, host_event); /* Optional: Close the handle if we are remapping with each call. */ CSL_intcClose(&intcQmss); }
2. Interrupt configuration of sysbios
a. Create HWI thread
(refer to Sys BIOS tutorial for detailed methods, which will not be repeated)
Example event ID 10 is mapped to interrupt vector 5
# include <xdc/runtime/Error.h> #include <ti/sysbios/hal/Hwi.h> Hwi_Handle myHwi; Int main(Int argc, char* argv[]) { H wi_Params hwiParams; Error_Block eb; Hwi_Params_init(&hwiParams); Error_init(&eb); // set the argument you want passed to your ISR function hwiParams.arg = 1; // set the event id of the peripheral assigned to this interrupt hwiParams.eventId = 10; // don't allow this interrupt to nest itself hwiParams.maskSetting = Hwi_MaskingOption_SELF; // // Configure interrupt 5 to invoke "myIsr". // Automatically enables interrupt 5 by default // set params.enableInt = FALSE if you want to control // when the interrupt is enabled using Hwi_enableInterrupt() // myHwi = Hwi_create( 5, myIsr, &hwiParams, &eb); if ( Error_check(&eb)) { // handle the error } } void myIsr(UArg arg) { / / this runs when interrupt # 5 goes offc }
b. Event Union
EventCombiner supports the combination of up to 32 events into one event. The output of EventCombiner can be connected to any configurable interrupt, and supports the combination of up to 32 * 4 events.
Support enable control of each event and interrupt function.
01
var EventCombiner = xdc. useModule( 'ti.sysbios.family.c64p.EventCombiner'); EventCombiner. events[ 15]. unmask = true; EventCombiner. events[ 15]. fxn = '&event15Fxn'; EventCombiner. events[ 15]. arg = 0x15; EventCombiner. events[ 16]. unmask = true; EventCombiner. events[ 16]. fxn = '&event16Fxn'; EventCombiner. events[ 16]. arg = 0x16
02
eventId = 4; EventCombiner_dispatchPlug(eventId, &event4Fxn, arg, TRUE); EventCombiner_dispatchPlug(eventId + 1, &event5Fxn, arg, TRUE); Hwi_Params_init(¶ms); params. arg = (eventId / 32); params. eventId = (eventId / 32); params. enableInt = TRUE; intVector = 8; Hwi_create(intVector, & EventCombiner_dispatch, ¶ms, NULL);
c,CpIntc
CpIntc manages CIC, which does not support interrupt nesting.
Turn on or off system and host interrupts,
system interrupts to host interrupts mapping (CIC)
host interrupts to HWIs, EventCombiner
There is a dispatch function for handling GEM hardware interrupts triggered by a system
interrupt. The Global Enable Register is enabled by default in the module startup function.
CpIntc APIs is 'ti.sysbios.family.c66.tci66xx.CpIntc'
Example
01
// Map system interrupt 15 to host interrupt 8 CpIntc_mapSysIntToHostInt( 0, 15, 8); // Plug the function for event #15 CpIntc_dispatchPlug( 15, &event15Fxn, 15, TRUE); // Enable host interrupt #8 CpIntc_enableHostInt( 0, 8); // enable host interrupt 8
02
/* Map the System Interrupt i.e. the Interrupt Destination 0 interrupt to the DIO ISR Handler. */ CpIntc_dispatchPlug(CSL_INTC0_INTDST0, (CpIntc_FuncPtr)myDioTxCompletionIsr, (UArg)hSrioDrv, TRUE); /* The configuration is for CPINTC0. We map system interrupt 112 to Host Interrupt 8. */ CpIntc_mapSysIntToHostInt( 0, CSL_INTC0_INTDST0, 8); /* Enable the Host Interrupt. */ CpIntc_enableHostInt( 0, 8); /* Enable the System Interrupt */ CpIntc_enableSysInt( 0, CSL_INTC0_INTDST0); /* Get the event id associated with the host interrupt. */ eventId = CpIntc_getEventId( 8); Hwi_Params_init(¶ms); /* Host interrupt value*/ params.arg = 8; /* Event id for your host interrupt */ params.eventId = eventId; /* Enable the Hwi */params.enableInt = TRUE; /* This plugs the interrupt vector 4 and the ISR function. */ /* When using CpIntc, you must plug the Hwi fxn with CpIntc_dispatch */ /* so it knows how to process the CpIntc interrupts.*/ Hwi_create( 4, &CpIntc_dispatch, ¶ms, NULL);