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.

F28M35x Cortex M3 CA Interrupt and MessageBox issues

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