Hi,
I haave some issues with the CanInntHandler on my Cortex M3, I set it to call the handler when an interrupt is geerate by a reception(canRx) but it never call it. I can see on te registers value that the interrupt is created, the message is seen and processed cause the register CAN_ES update the bit Rxok an the IF2CMD register do an ClrIntPnd
there is mycode of the CanInit and the CanIntHandler
/****************************************************************************** Initialize the hardware to receive CAN messages and start the timer for the CANopen stack. INPUT bitrate bitrate in kilobit OUTPUT 1 if successful ******************************************************************************/ unsigned char canInit(unsigned int bitrate) { // Initialize the CAN controller int ulBase = CAN0_BASE; int iMsg; // Check the arguments. ASSERT(CANBaseValid(ulBase)); // Place CAN controller in init state, regardless of previous state. This // will put controller in idle, and allow the message object RAM to be // programmed. HWREG(ulBase + CAN_O_CTL) = CAN_CTL_INIT; HWREG(ulBase + CAN_O_CTL) = CAN_CTL_SWR; // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF1_CMD) & CAN_IF1_CMD_BUSY) { } // Clear the message value bit in the arbitration register. This indicates // the message is not valid and is a "safe" condition to leave the message // object. The same arb reg is used to program all the message objects. /* HWREGH(ulBase + CAN_O_IF1_MSK) = 0; HWREGH(ulBase + CAN_O_IF1_CMD ) = (unsigned char) 0xF8; HWREG(ulBase + CAN_O_IF1_ARB) = (int)0x80000000 | (int)0x00000000 | (int)0x20000000 | (int)((int)((int)0 & (int)0x000007FF) << (int)18); HWREG(ulBase + CAN_O_IF1_MCTL) = 0x00001080 | (int)0x00000000 | (int)0x00000000 | (int)8; HWREGH(ulBase + CAN_O_IF2_MSK) = 0; HWREGH(ulBase + CAN_O_IF2_CMD ) = (unsigned char) 0xF8; HWREG(ulBase + CAN_O_IF2_ARB) = (int)0x80000000 | (int)0x00000000 | (int)0x00000000 | (int)((int)((int)0 & (int)0x000007FF) << (int)18); HWREG(ulBase + CAN_O_IF2_MCTL) = 0x00001080 | (int)0x00000400 | (int)0x00000000 | (int)8; // Loop through to program all 32 message objects for(iMsg = 1; iMsg <= 16; iMsg++) { // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF1_CMD) & CAN_IF1_CMD_BUSY) { } // Initiate programming the message object HWREGH(ulBase + CAN_O_IF1_CMD) = iMsg; } for(iMsg = 16; iMsg <= 32; iMsg++) { // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF2_CMD) & CAN_IF2_CMD_BUSY) { } // Initiate programming the message object HWREGH(ulBase + CAN_O_IF2_CMD) = iMsg; } */ HWREGH(ulBase + CAN_O_IF1_CMD + 2) = (CAN_IF1_CMD_WR_RD | CAN_IF1_CMD_ARB | CAN_IF1_CMD_CONTROL) >> 16; HWREG(ulBase + CAN_O_IF1_ARB) = 0; HWREG(ulBase + CAN_O_IF1_MCTL) = 0x1088; HWREGH(ulBase + CAN_O_IF2_CMD + 2) = (CAN_IF2_CMD_WR_RD | CAN_IF2_CMD_ARB | CAN_IF1_CMD_CONTROL) >> 16; HWREG(ulBase + CAN_O_IF2_ARB) = 0; HWREG(ulBase + CAN_O_IF2_MCTL) = 0x1488; // Loop through to program all 32 message objects for(iMsg = 1; iMsg <= 16; iMsg++) { // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF1_CMD) & CAN_IF1_CMD_BUSY) { } // Initiate programming the message object HWREGH(ulBase + CAN_O_IF1_CMD) = iMsg; } for(iMsg = 16; iMsg <= 32; iMsg++) { // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF2_CMD) & CAN_IF2_CMD_BUSY) { } // Initiate programming the message object HWREGH(ulBase + CAN_O_IF2_CMD) = iMsg; } // Make sure that the interrupt and new data flags are updated for the // message objects. HWREGH(ulBase + CAN_O_IF1_CMD + 2) = (CAN_IF1_CMD_CLRINTPND) >> 16; HWREGH(ulBase + CAN_O_IF2_CMD + 2) = (CAN_IF2_CMD_CLRINTPND) >> 16; // Loop through to program all 32 message objects for(iMsg = 1; iMsg <= 16; iMsg++) { // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF1_CMD) & CAN_IF1_CMD_BUSY) { } // Initiate programming the message object HWREGH(ulBase + CAN_O_IF1_CMD) = iMsg; } for(iMsg = 16; iMsg <= 32; iMsg++) { // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF2_CMD) & CAN_IF2_CMD_BUSY) { } // Initiate programming the message object HWREGH(ulBase + CAN_O_IF2_CMD) = iMsg; } // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF1_CMD) & CAN_IF1_CMD_BUSY) { } HWREGH(ulBase + CAN_O_IF1_CMD) = 0x87; // Wait for busy bit to clear while(HWREG(ulBase + CAN_O_IF2_CMD) & CAN_IF2_CMD_BUSY) { } HWREGH(ulBase + CAN_O_IF2_CMD) = 0x17; // Acknowledge any pending status interrupts. HWREG(ulBase + CAN_O_ES); // Setup CAN to be clocked off the M3/Master subsystem clock CANClkSourceSelect(CAN0_BASE, CAN_CLK_M3); // Set up the bit rate for the CAN bus. This function sets up the CAN // bus timing for a nominal configuration. You can achieve more control // over the CAN bus timing by using the function CANBitTimingSet() instead // of this one, if needed. // In this example, the CAN bus is set to 500 kHz. In the function below, // the call to SysCtlClockGet() is used to determine the clock rate that // is used for clocking the CAN peripheral. This can be replaced with a // fixed value if you know the value of the system clock, saving the extra // function call. For some parts, the CAN peripheral is clocked by a fixed // 8 MHz regardless of the system clock in which case the call to // SysCtlClockGet() should be replaced with 8000000. Consult the data // sheet for more information about CAN peripheral clocking. CANBitRateSet(CAN0_BASE, SysCtlClockGet(SYSTEM_CLOCK_SPEED), bitrate); // Enable interrupts on the CAN peripheral. This example uses static // allocation of interrupt handlers which means the name of the handler // is in the vector table of startup code. If you want to use dynamic // allocation of the vector table, then you must also call CANIntRegister() // here. // CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors CANIntEnable(CAN0_BASE, CAN_INT_MASTER /*| CAN_INT_ERROR | CAN_INT_STATUS*/); // Register interrupt handler in RAM vector table IntRegister(INT_CAN0INT0, CANIntHandler); IntRegister(INT_CAN0INT1, CANIntHandler); // Enable the CAN interrupt on the processor (NVIC). IntEnable(INT_CAN0INT0); IntEnable(INT_CAN0INT1); IntMasterEnable(); // Disable test mode and select external loopback HWREG(CAN0_BASE + CAN_O_CTL) |= (0 | CAN_CTL_IE0 | CAN_CTL_IE1) ; //disable test mode HWREG(CAN0_BASE + CAN_O_TEST) = 0; //disable external loopback mode // Enable the CAN for operation. CANEnable(CAN0_BASE); return 1; }
void CANIntHandler(void) { unsigned long ulStatus; Message m = Message_Initializer; // contain a CAN message; // Read the CAN interrupt status to find the cause of the interrupt ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); x=ulStatus; // If the cause is a controller status interrupt, then get the status if(ulStatus == CAN_INT_INT0ID_STATUS) { // Read the controller status. This will return a field of status // error bits that can indicate various errors. Error processing // is not done in this example for simplicity. Refer to the // API documentation for details about the error status bits. // The act of reading this status will clear the interrupt. If the // CAN peripheral is not connected to a CAN bus with other CAN devices // present, then errors will occur and will be indicated in the // controller status. ulStatus = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); // Set a flag to indicate some errors may have occurred. g_bErrFlag = 1; } // Check if the cause is message object 1, which what we are using for // sending messages. else if((ulStatus > 0) && (ulStatus <= 32)) { // Getting to this point means that the TX interrupt occurred on // message object 1, and the message TX is complete. Clear the // message object interrupt. CANIntClear(CAN0_BASE, 1); // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. g_ulMsgCount++; if(canPreReceive(ulStatus, &m)) { canReceive(&m); } // Since the message was sent, clear any error flags. g_bErrFlag = 0; } // Otherwise, something unexpected caused the interrupt. This should // never happen. else { // Spurious interrupt handling can go here. } }