Hello!
I am in the final stages of writing code for using the hyperlink interface, and I am having some trouble with the final portion of it, to generate interrupts reliably between the two processors. Sometimes both interrupts operate without issue, sometimes only one processor's interrupts operate, sometimes they both operate once or twice, and so on. With this behavior, I am having a difficult time getting consistent results from it, and was hoping someone could take a look at what I had and give me some advice.
As a note, it seems like this problem is stemming from the interrupt never being properly cleared (hyperlinkRegisters.intPendSet->intSet) is never being cleared to 0, and I set that value to 1 to generate an interrupt.
My basic program architecture is to send a message over hyperlink then generate an interrupt on the remote processor to inform the other processor that an message has been sent.
The majority of my code was taken and adapted from the hyperlink example within the pdk_c6678_1_0_0_17.
With respect for interrupts, my setup code is the following lines
(intCtrlTbl and control are structures mapped to a hyperlink register struct)
intCtrlTbl->intEn = 1;
/* Interrupt bits */
control.statusIntEnable = 1;
control.intLocal = 1;
control.int2cfg = 1;
control.statusIntVec = 0;
After this, my code to generate the interrupt is as follows:
hyplnkRet_e retVal;
Hyplnk_Handle handleLocal = NULL;
if ((retVal = Hyplnk_open(0, &handleLocal)) != hyplnk_RET_OK)
{
System_printf("open failed!\n");
}
Hyplnk_readRegs(handleLocal, hyplnk_LOCATION_REMOTE, &getRegs);
if (getRegs.intPendSet->intSet == 0) /* If there is no pending interrupt on the remote side */
{
setRegs.intPendSet->intSet = 0x01;
if ((retVal = Hyplnk_writeRegs(handleLocal, hyplnk_LOCATION_REMOTE, &setRegs)) != hyplnk_RET_OK)
{
System_printf("Control register write failed!\n");
}
}
if ((retVal = Hyplnk_close(&handleLocal)) != hyplnk_RET_OK)
{
System_printf("close failed!\n");
}
My code to initialize the interrupts is taken more or less directly from the example, and is given below:
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 CSL_INTC0_VUSR_INT_O */
CSL_CPINTC_clearSysInterrupt (hnd, CSL_INTC0_VUSR_INT_O);
/* Enable it */
CSL_CPINTC_enableSysInterrupt (hnd, CSL_INTC0_VUSR_INT_O);
CSL_CPINTC_mapSystemIntrToChannel (hnd, CSL_INTC0_VUSR_INT_O, hyplnk_INTC_OUTPUT);
/* Enable it */
CSL_CPINTC_enableHostInterrupt (hnd, hyplnk_INTC_OUTPUT);
CSL_CPINTC_enableAllHostInterrupt(hnd);
CSL_IntcParam vectId = hyplnk_COREPAC_VEC;
Int16 eventId = hyplnk_COREPAC_INT_INPUT;
hyplnkIntcHnd = CSL_intcOpen (&hyplnkIntcObj, eventId, &vectId, NULL);
if (! hyplnkIntcHnd) {
// return 0;
}
hyperlink_routine = intHandler;
EventRecord.handler = (CSL_IntcEventHandler)&HyperlinkHandler;
EventRecord.arg = (void *) hyplnk_COREPAC_INT_INPUT;
CSL_intcPlugEventHandler(hyplnkIntcHnd, &EventRecord);
CSL_intcHwControl(hyplnkIntcHnd, CSL_INTC_CMD_EVTCLEAR, NULL);
CSL_intcHwControl(hyplnkIntcHnd, CSL_INTC_CMD_EVTENABLE, NULL);
Finally, my ISR code to handle and clear the interrupt is the following:
static void HyperlinkHandler(void)
{
hyplnkRegisters_t regs;
hyplnkIntStatusClrReg_t intStatusClr;
Hyplnk_Handle handle = NULL;
uint32_t remainingInterrupts;
CSL_CPINTC_Handle cpintcHnd;
cpintcHnd = CSL_CPINTC_open (0);
if (! cpintcHnd) {
printf("CSL_CPINTC_Open Failure\n");
}
memset (®s, 0, sizeof(regs));
regs.intStatusClr = &intStatusClr;
if (Hyplnk_open(0, &handle) != hyplnk_RET_OK) {
printf("Hyplnk Open (Interrupt) Failure\n");
}
/* Figure out which interrupt it is */
if (Hyplnk_readRegs (handle, hyplnk_LOCATION_LOCAL, ®s) != hyplnk_RET_OK) {
printf("Read register write failed!\n");
}
/* Process the fatal error interrupt */
remainingInterrupts = intStatusClr.intClr;
if (remainingInterrupts & (1 ))
{
remainingInterrupts &= ~(1 );
}
/* Clear the interrupt */
if (Hyplnk_writeRegs (handle, hyplnk_LOCATION_LOCAL, ®s) != hyplnk_RET_OK) {
printf("Control register write failed!\n");
}
/* Acknowledge CorePac interrupt */
CSL_intcHwControl(hyplnkIntcHnd, CSL_INTC_CMD_EVTCLEAR, NULL);
/* Acknowledge cp intc interrupt */
CSL_CPINTC_clearSysInterrupt (cpintcHnd, CSL_INTC0_VUSR_INT_O);
}
I apologize in advance for the mass of code here, but I figure it is the best way to show what I am doing, and hope that someone sees some blatant problem in it that is causing this inconsistent behavior.
If anything is unclear or more information is required for this, just let me know and I will do my best to clear it up or provide more information.
Have a great day!