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.
}
}