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.

F28069M eCAN interrupt problem

Other Parts Discussed in Thread: MOTORWARE

I am trying to add CAN support for Motorware 16 proj_lab09. Right now I'm trying to get interrupts to work. I went through spruh18f.pdf section 16.13.3.1, but either I misunderstood/missed something, or it's not enough. Here is how I configure the interrupts:

First this is executed as part of the initialization for eCAN (this bit is between calls to EALLOW; and EDIS;):

// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
//  as a matter of precaution.

	obj->ecanaHandle->ECanaRegs->CANTA.all = 0xFFFFFFFF;   /* Clear all TAn bits */

	obj->ecanaHandle->ECanaRegs->CANRMP.all = 0xFFFFFFFF;  /* Clear all RMPn bits */

	obj->ecanaHandle->ECanaRegs->CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
	obj->ecanaHandle->ECanaRegs->CANGIF1.all = 0xFFFFFFFF;

	//Enable interrupts.
	ECanaShadow.CANGIM.all = obj->ecanaHandle->ECanaRegs->CANGIM.all;
	ECanaShadow.CANGIM.bit.AAIM = 1;
	ECanaShadow.CANGIM.bit.WDIM = 1;
	ECanaShadow.CANGIM.bit.WUIM = 1;
	ECanaShadow.CANGIM.bit.BOIM = 1;
	ECanaShadow.CANGIM.bit.EPIM = 1;
	ECanaShadow.CANGIM.bit.WLIM = 1;
	ECanaShadow.CANGIM.bit.GIL = 1;  //the GIL (GIM.2) bit can be set to have the global interrupts on another level than the mailbox interrupts
	ECanaShadow.CANGIM.bit.I0EN = 1;
	ECanaShadow.CANGIM.bit.I1EN = 1;
	obj->ecanaHandle->ECanaRegs->CANGIM.all = ECanaShadow.CANGIM.all;

Call from main:

ECAN_configMbox(halHandle->ecanaHandle, 16, 6, 1, 1, 0x07FF, 1, 1);

The function that does most of the configuration:

void ECAN_configMbox(ECAN_Handle handle, uint8_t mboxNum, uint32_t msgid, uint8_t enable, uint8_t rx, uint32_t mask, uint8_t enable_interrupt, uint8_t interrupt_line){
	struct ECAN_REGS ecanaShadow;

	//Getting reference to the mbox with the given mboxNum.
	volatile struct MBOX *mbox = (&(handle->ECanaMboxes->MBOX0)) + (mboxNum);
	volatile union CANLAM_REG *lam = (&(handle->ECanaLAMRegs->LAM0)) + (mboxNum);

	//Setting local acceptance mask.
	//lam->all = mask;
	lam->bit.LAM_H = mask;

	//Setting msgid.
	//mbox->MSGID.all = msgid;
	mbox->MSGID.bit.STDMSGID = msgid;

	//Setting rx/tx mode.
	rx = rx & 1; //Making sure it's only one bit.
    ecanaShadow.CANMD.all = handle->ECanaRegs->CANMD.all;
    ecanaShadow.CANMD.all = (~((~ecanaShadow.CANMD.all) | (((uint32_t)1) << mboxNum))) | (((uint32_t)rx) << mboxNum);
	handle->ECanaRegs->CANMD.all = ecanaShadow.CANMD.all;

    //Enable/disable mbox.
	enable = enable & 1; //Making sure it's only one bit.
    ecanaShadow.CANME.all = handle->ECanaRegs->CANME.all;
    ecanaShadow.CANME.all = (~((~ecanaShadow.CANME.all) | (((uint32_t)1) << mboxNum))) | (((uint32_t)enable) << mboxNum);
	handle->ECanaRegs->CANME.all = ecanaShadow.CANME.all;

    // Specify that 8 bits will be sent/received
    mbox->MSGCTRL.bit.DLC = 8;

    EALLOW;
    //Enable/disable interrupt.
	enable_interrupt = enable_interrupt & 1; //Making sure it's only one bit.
    ecanaShadow.CANMIM.all = handle->ECanaRegs->CANMIM.all;
    ecanaShadow.CANMIM.all = (~((~ecanaShadow.CANMIM.all) | (((uint32_t)1) << mboxNum))) | (((uint32_t)enable_interrupt) << mboxNum);
    handle->ECanaRegs->CANMIM.all = ecanaShadow.CANMIM.all;

    //Selecting interrupt line 0 or 1.
	interrupt_line = interrupt_line & 1; //Making sure it's only one bit.
    ecanaShadow.CANMIL.all = handle->ECanaRegs->CANMIL.all;
    ecanaShadow.CANMIL.all = (~((~ecanaShadow.CANMIL.all) | (((uint32_t)1) << mboxNum))) | (((uint32_t)interrupt_line) << mboxNum);
    handle->ECanaRegs->CANMIL.all = ecanaShadow.CANMIL.all;

	//Disable self-test mode.
    ecanaShadow.CANMC.all = handle->ECanaRegs->CANMC.all;
    ecanaShadow.CANMC.bit.STM = 0;    // Disable self-test mode.
    handle->ECanaRegs->CANMC.all = ecanaShadow.CANMC.all;
    EDIS;
}

The interrupt functions (and halHandle->pieHandle->ECAN0INT / ECAN1INT are correctly pointing to these functions, verified with debugger):

interrupt void ecan0ISR(void){
	//ecanTestRead(16);
	canIsr0Count++;

	ECAN_clearInterrupts(halHandle->ecanaHandle);
	HAL_pieAckInt(halHandle, PIE_GroupNumber_9);
	return;
}

interrupt void ecan1ISR(void){
	//ecanTestRead(16);
	canIsr1Count++;

	ECAN_clearInterrupts(halHandle->ecanaHandle);
	HAL_pieAckInt(halHandle, PIE_GroupNumber_9);
	return;
}

The ECAN_clearInterrupts function (used in interrupts above):

void ECAN_clearInterrupts(ECAN_Handle handle){
	halHandle->ecanaHandle->ECanaRegs->CANTA.all = 0xFFFFFFFF;   /* Clear all TAn bits */

	halHandle->ecanaHandle->ECanaRegs->CANRMP.all = 0xFFFFFFFF;  /* Clear all RMPn bits */

	halHandle->ecanaHandle->ECanaRegs->CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
	halHandle->ecanaHandle->ECanaRegs->CANGIF1.all = 0xFFFFFFFF;
}

The interrupts are enabled in main via this function, before the call to (HAL_enableGlobalInts):

void HAL_enableEcanInt(HAL_Handle handle){
	HAL_Obj *obj = (HAL_Obj *)handle;

	PIE_enableInt(obj->pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_ECANA0);
	PIE_enableInt(obj->pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_ECANA1);

	return;
}

When I poll the mailboxes, I am receiving data, but the interrupts do not increase the counters. What am I missing?