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.

LAUNCHXL-F280049C: About interrupt line 1(CAN1INT) in CAN module

Part Number: LAUNCHXL-F280049C

Hi,

    1.I want to use  interrupt line 1(CAN1INT) in DCAN module, and I have tried to modify the program(can_ex2_loopback_interrupt), but it didn't generate CAN1INT. Can you help me? The modifed file is in the attachment.

can_ex2_loopback_interrupts.c
//#############################################################################
//
// FILE:   can_ex2_loopback_interrupts.c
//
// TITLE:   CAN External Loopback with Interrupts Example
//
//! \addtogroup driver_example_list
//! <h1> CAN External Loopback with Interrupts </h1>
//!
//! This example shows the basic setup of CAN in order to transmit and receive
//! messages on the CAN bus.  The CAN peripheral is configured to transmit
//! messages with a specific CAN ID.  A message is then transmitted once per
//! second, using a simple delay loop for timing.  The message that is sent is
//! a 4 byte message that contains an incrementing pattern.  A CAN interrupt
//! handler is used to confirm message transmission and count the number of
//! messages that have been sent.
//!
//! This example sets up the CAN controller in External Loopback test mode.
//! Data transmitted is visible on the CANTXA/CANATX pin and is received internally
//! back to the CAN Core.
//!
//! \b External \b Connections \n
//!  - None.
//!
//! \b Watch \b Variables \n
//!  - txMsgCount - A counter for the number of messages sent
//!  - rxMsgCount - A counter for the number of messages received
//!  - txMsgData - An array with the data being sent
//!  - rxMsgData - An array with the data that was received
//!  - errorFlag - A flag that indicates an error has occurred
//!
//
//#############################################################################
// $TI Release: F28004x Support Library v1.11.00.00 $
// $Release Date: Sun Oct  4 15:49:15 IST 2020 $
// $Copyright:
// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Defines
//
#define MSG_DATA_LENGTH    4
#define TX_MSG_OBJ_ID      1
#define RX_MSG_OBJ_ID      2

//
// Globals
//
volatile uint32_t txMsgCount = 0;
volatile uint32_t rxMsgCount = 0;
volatile uint32_t errorFlag = 0;
uint16_t txMsgData[4];
uint16_t rxMsgData[4];

//
// Function Prototypes
//
__interrupt void canISR(void);

//
// Main
//
void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Initialize GPIO and configure GPIO pins for CANTX/CANRX
    //
    Device_initGPIO();
    GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);

    //
    // Initialize the CAN controller
    //
    CAN_initModule(CANA_BASE);

    //
    // Set up the CAN bus bit rate to 500kHz
    // Refer to the Driver Library User Guide for information on how to set
    // tighter timing control. Additionally, consult the device data sheet
    // for more information about the CAN module clocking.
    //
    CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);

    //
    // Enable interrupts on the CAN peripheral.
    //
    CAN_enableInterrupt(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR |
                        CAN_INT_STATUS);

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    // This registers the interrupt handler in PIE vector table.
    //
    Interrupt_register(INT_CANA1, &canISR);

    //
    // Enable the CAN interrupt signal
    //
    Interrupt_enable(INT_CANA1);
    CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT1);
    HWREG(CANA_BASE + CAN_O_IP_MUX21) = 0xFFFFFFFF;

    //
    // Enable CAN test mode with external loopback
    //
    CAN_enableTestMode(CANA_BASE, CAN_TEST_EXL);

    //
    // Initialize the transmit message object used for sending CAN messages.
    // Message Object Parameters:
    //      Message Object ID Number: 1
    //      Message Identifier: 0x1
    //      Message Frame: Standard
    //      Message Type: Transmit
    //      Message ID Mask: 0x0
    //      Message Object Flags: Transmit Interrupt
    //      Message Data Length: 4 Bytes
    //
    CAN_setupMessageObject(CANA_BASE, TX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
                           CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,
                           MSG_DATA_LENGTH);

    //
    // Initialize the receive message object used for receiving CAN messages.
    // Message Object Parameters:
    //      Message Object ID Number: 2
    //      Message Identifier: 0x1
    //      Message Frame: Standard
    //      Message Type: Receive
    //      Message ID Mask: 0x0
    //      Message Object Flags: Receive Interrupt
    //      Message Data Length: 4 Bytes
    //
    CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
                           CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
                           MSG_DATA_LENGTH);

    //
    // Initialize the transmit message object data buffer to be sent
    //
    txMsgData[0] = 0x12;
    txMsgData[1] = 0x34;
    txMsgData[2] = 0x56;
    txMsgData[3] = 0x78;

    //
    // Start CAN module operations
    //
    CAN_startModule(CANA_BASE);

    //
    // Loop Forever - A new message will be sent once per second.
    //
    for(;;)
    {
        //
        // Check the error flag to see if errors occurred
        //
        if(errorFlag)
        {
            Example_Fail = 1;
            asm("   ESTOP0");
        }

        //
        // Verify that the number of transmitted messages equal the number of
        // messages received before sending a new message
        //
        if(txMsgCount == rxMsgCount)
        {
            CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
                            txMsgData);

            Example_PassCount++;
        }
        else
        {
            errorFlag = 1;
        }

        //
        // Delay 1 second before continuing
        //
        DEVICE_DELAY_US(1000000);

        //
        // Increment the value in the transmitted message data.
        //
        txMsgData[0] += 0x01;
        txMsgData[1] += 0x01;
        txMsgData[2] += 0x01;
        txMsgData[3] += 0x01;

        //
        // Reset data if exceeds a byte
        //
        if(txMsgData[0] > 0xFF)
        {
            txMsgData[0] = 0;
        }
        if(txMsgData[1] > 0xFF)
        {
            txMsgData[1] = 0;
        }
        if(txMsgData[2] > 0xFF)
        {
            txMsgData[2] = 0;
        }
        if(txMsgData[3] > 0xFF)
        {
            txMsgData[3] = 0;
        }
    }
}

//
// CAN ISR - The interrupt service routine called when a CAN interrupt is
//           triggered.  It checks for the cause of the interrupt, and
//           maintains a count of all messages that have been transmitted.
//
__interrupt void
canISR(void)
{
    uint32_t status;

    //
    // Read the CAN interrupt status to find the cause of the interrupt
    //
    status = CAN_getInterruptCause(CANA_BASE);

    //
    // If the cause is a controller status interrupt, then get the status
    //
    if(status == 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.
        //
        status = CAN_getStatus(CANA_BASE);

        //
        // Check to see if an error occurred.
        //
        if(((status  & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 7) &&
           ((status  & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 0))
        {
            //
            // Set a flag to indicate some errors may have occurred.
            //
            errorFlag = 1;
        }
    }

    //
    // Check if the cause is the transmit message object 1
    //
    else if(status == TX_MSG_OBJ_ID)
    {
        //
        // 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.
        //
        CAN_clearInterruptStatus(CANA_BASE, TX_MSG_OBJ_ID);

        //
        // 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.
        //
        txMsgCount++;

        //
        // Since the message was sent, clear any error flags.
        //
        errorFlag = 0;
    }

    //
    // Check if the cause is the receive message object 2
    //
    else if(status == RX_MSG_OBJ_ID)
    {
        //
        // Get the received message
        //
        CAN_readMessage(CANA_BASE, RX_MSG_OBJ_ID, rxMsgData);

        //
        // Getting to this point means that the RX interrupt occurred on
        // message object 2, and the message RX is complete.  Clear the
        // message object interrupt.
        //
        CAN_clearInterruptStatus(CANA_BASE, RX_MSG_OBJ_ID);

        //
        // Increment a counter to keep track of how many messages have been
        // received. In a real application this could be used to set flags to
        // indicate when a message is received.
        //
        rxMsgCount++;

        //
        // Since the message was received, clear any error flags.
        //
        errorFlag = 0;
    }

    //
    // If something unexpected caused the interrupt, this would handle it.
    //
    else
    {
        //
        // Spurious interrupt handling can go here.
        //
    }

    //
    // Clear the global interrupt flag for the CAN interrupt line
    //
    CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT1);

    //
    // Acknowledge this interrupt located in group 9
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

//
// End of File
//

  2. If the CAN1INT is effective, was the INT0ID bits in CAN_INT register never 0x8000?

     Thanks!

  • Hi Lei,

    In function call CAN_enableInterrupt(), make sure to change CAN_INT_IE0 to CAN_INT_IE1 to enable CAN1INT.

    Regards,

    Joseph

  • Hi,

        I so sorry,I have a misoperation. And I have modify "CAN_enableInterrupt(CANA_BASE, CAN_INT_IE1 | CAN_INT_ERROR | CAN_INT_STATUS);"

        But it never generate CAN1INT still.Why?

    2. If the CAN1INT is effective, was the INT0ID bits in CAN_INT register never 0x8000?

    And please answer this question.

        Thanks very much!

  • Hi Lei,

    2. If the CAN1INT is effective, was the INT0ID bits in CAN_INT register never 0x8000?

    CAN1INT does not handle error/status interrupts so it will never get a value of 0x8000.  See register descriptions.  CAN1INT only returns 

  • Hi Lei,

    2. If the CAN1INT is effective, was the INT0ID bits in CAN_INT register never 0x8000?

    CAN1INT does not handle error/status interrupts so it will never get a value of 0x8000.  See register descriptions.  CAN1INT only returns the number of message object that caused the interrupt (value from 0x1-0x20):

    Modify your CAN ISR and check for the flags in INT1D register to see which message object caused the interrupt.

    Regards,

    Joseph

  • Do I need to delete the follow CASE?

        if(status == 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.
            //
            status = CAN_getStatus(CANA_BASE);

            //
            // Check to see if an error occurred.
            //
            if(((status  & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 7) &&
               ((status  & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 0))
            {
                //
                // Set a flag to indicate some errors may have occurred.
                //
                errorFlag = 1;
            }
        }

      And the CAN1INT is only "0x01-0x20 Number of message object (mailbox) which caused the
    interrupt."  Is it?

  • Hi Lei,

    Yes, you need to modify that flag check and replace it instead with CAN_INT1ID status, and polling for the message object that caused the interrupt.

    Regards,

    Joseph

  • Hi,

       Thanks for your replay! I have modified the program(can_ex2_loopback_interrupt), but it neither generate CAN1INT, nor enter "__interrupt void canISR(void)". You can try it if it's convenient. The program is as follow:

    0143.can_ex2_loopback_interrupts.c
    //#############################################################################
    //
    // FILE:   can_ex2_loopback_interrupts.c
    //
    // TITLE:   CAN External Loopback with Interrupts Example
    //
    //! \addtogroup driver_example_list
    //! <h1> CAN External Loopback with Interrupts </h1>
    //!
    //! This example shows the basic setup of CAN in order to transmit and receive
    //! messages on the CAN bus.  The CAN peripheral is configured to transmit
    //! messages with a specific CAN ID.  A message is then transmitted once per
    //! second, using a simple delay loop for timing.  The message that is sent is
    //! a 4 byte message that contains an incrementing pattern.  A CAN interrupt
    //! handler is used to confirm message transmission and count the number of
    //! messages that have been sent.
    //!
    //! This example sets up the CAN controller in External Loopback test mode.
    //! Data transmitted is visible on the CANTXA/CANATX pin and is received internally
    //! back to the CAN Core.
    //!
    //! \b External \b Connections \n
    //!  - None.
    //!
    //! \b Watch \b Variables \n
    //!  - txMsgCount - A counter for the number of messages sent
    //!  - rxMsgCount - A counter for the number of messages received
    //!  - txMsgData - An array with the data being sent
    //!  - rxMsgData - An array with the data that was received
    //!  - errorFlag - A flag that indicates an error has occurred
    //!
    //
    //#############################################################################
    // $TI Release: F28004x Support Library v1.11.00.00 $
    // $Release Date: Sun Oct  4 15:49:15 IST 2020 $
    // $Copyright:
    // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Defines
    //
    #define MSG_DATA_LENGTH    4
    #define TX_MSG_OBJ_ID      1
    #define RX_MSG_OBJ_ID      2
    
    //
    // Globals
    //
    volatile uint32_t txMsgCount = 0;
    volatile uint32_t rxMsgCount = 0;
    volatile uint32_t errorFlag = 0;
    uint16_t txMsgData[4];
    uint16_t rxMsgData[4];
    
    //
    // Function Prototypes
    //
    __interrupt void canISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Initialize GPIO and configure GPIO pins for CANTX/CANRX
        //
        Device_initGPIO();
        GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
        GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
    
        //
        // Initialize the CAN controller
        //
        CAN_initModule(CANA_BASE);
    
        //
        // Set up the CAN bus bit rate to 500kHz
        // Refer to the Driver Library User Guide for information on how to set
        // tighter timing control. Additionally, consult the device data sheet
        // for more information about the CAN module clocking.
        //
        CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);
    
        //
        // Enable interrupts on the CAN peripheral.
        //
        CAN_enableInterrupt(CANA_BASE, CAN_INT_IE1 | CAN_INT_ERROR |
                            CAN_INT_STATUS);
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        // This registers the interrupt handler in PIE vector table.
        //
        Interrupt_register(INT_CANA1, &canISR);
    
        //
        // Enable the CAN interrupt signal
        //
        Interrupt_enable(INT_CANA1);
        CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT1);
        HWREG(CANA_BASE + CAN_O_IP_MUX21) = 0xFFFFFFFF;
    
        //
        // Enable CAN test mode with external loopback
        //
        CAN_enableTestMode(CANA_BASE, CAN_TEST_EXL);
    
        //
        // Initialize the transmit message object used for sending CAN messages.
        // Message Object Parameters:
        //      Message Object ID Number: 1
        //      Message Identifier: 0x1
        //      Message Frame: Standard
        //      Message Type: Transmit
        //      Message ID Mask: 0x0
        //      Message Object Flags: Transmit Interrupt
        //      Message Data Length: 4 Bytes
        //
        CAN_setupMessageObject(CANA_BASE, TX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
                               CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,
                               MSG_DATA_LENGTH);
    
        //
        // Initialize the receive message object used for receiving CAN messages.
        // Message Object Parameters:
        //      Message Object ID Number: 2
        //      Message Identifier: 0x1
        //      Message Frame: Standard
        //      Message Type: Receive
        //      Message ID Mask: 0x0
        //      Message Object Flags: Receive Interrupt
        //      Message Data Length: 4 Bytes
        //
        CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x1, CAN_MSG_FRAME_STD,
                               CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,
                               MSG_DATA_LENGTH);
    
        //
        // Initialize the transmit message object data buffer to be sent
        //
        txMsgData[0] = 0x12;
        txMsgData[1] = 0x34;
        txMsgData[2] = 0x56;
        txMsgData[3] = 0x78;
    
        //
        // Start CAN module operations
        //
        CAN_startModule(CANA_BASE);
    
        //
        // Loop Forever - A new message will be sent once per second.
        //
        for(;;)
        {
            //
            // Check the error flag to see if errors occurred
            //
            if(errorFlag)
            {
                Example_Fail = 1;
                asm("   ESTOP0");
            }
    
            //
            // Verify that the number of transmitted messages equal the number of
            // messages received before sending a new message
            //
            if(txMsgCount == rxMsgCount)
            {
                CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH,
                                txMsgData);
    
                Example_PassCount++;
            }
            else
            {
                errorFlag = 1;
            }
    
            //
            // Delay 1 second before continuing
            //
            DEVICE_DELAY_US(1000000);
    
            //
            // Increment the value in the transmitted message data.
            //
            txMsgData[0] += 0x01;
            txMsgData[1] += 0x01;
            txMsgData[2] += 0x01;
            txMsgData[3] += 0x01;
    
            //
            // Reset data if exceeds a byte
            //
            if(txMsgData[0] > 0xFF)
            {
                txMsgData[0] = 0;
            }
            if(txMsgData[1] > 0xFF)
            {
                txMsgData[1] = 0;
            }
            if(txMsgData[2] > 0xFF)
            {
                txMsgData[2] = 0;
            }
            if(txMsgData[3] > 0xFF)
            {
                txMsgData[3] = 0;
            }
        }
    }
    
    //
    // CAN ISR - The interrupt service routine called when a CAN interrupt is
    //           triggered.  It checks for the cause of the interrupt, and
    //           maintains a count of all messages that have been transmitted.
    //
    __interrupt void
    canISR(void)
    {
        uint32_t status;
    
        //
        // Read the CAN interrupt status to find the cause of the interrupt
        //
        status = CAN_getInterruptCause(CANA_BASE);
    
        //
        // If the cause is a controller status interrupt, then get the status
        //
        
    
        //
        // Check if the cause is the transmit message object 1
        //
        if(status == TX_MSG_OBJ_ID)
        {
            //
            // 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.
            //
            CAN_clearInterruptStatus(CANA_BASE, TX_MSG_OBJ_ID);
    
            //
            // 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.
            //
            txMsgCount++;
    
            //
            // Since the message was sent, clear any error flags.
            //
            errorFlag = 0;
        }
    
        //
        // Check if the cause is the receive message object 2
        //
        else if(status == RX_MSG_OBJ_ID)
        {
            //
            // Get the received message
            //
            CAN_readMessage(CANA_BASE, RX_MSG_OBJ_ID, rxMsgData);
    
            //
            // Getting to this point means that the RX interrupt occurred on
            // message object 2, and the message RX is complete.  Clear the
            // message object interrupt.
            //
            CAN_clearInterruptStatus(CANA_BASE, RX_MSG_OBJ_ID);
    
            //
            // Increment a counter to keep track of how many messages have been
            // received. In a real application this could be used to set flags to
            // indicate when a message is received.
            //
            rxMsgCount++;
    
            //
            // Since the message was received, clear any error flags.
            //
            errorFlag = 0;
        }
    
        //
        // If something unexpected caused the interrupt, this would handle it.
        //
        else
        {
            //
            // Spurious interrupt handling can go here.
            //
        }
    
        //
        // Clear the global interrupt flag for the CAN interrupt line
        //
        CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT1);
    
        //
        // Acknowledge this interrupt located in group 9
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    //
    // End of File
    //
    

       Thanks!

  • Hi Lei,

    Couple of changes you need to make in your code:

    1.) Change the enable interrupt function call to - CAN_enableInterrupt(CANA_BASE, CAN_INT_IE1);  Remove CAN_INT_ERROR and CAN_INT_STATUS bits as these are not supported by CAN interrupt line 1.  I tried it and when these 2 bits are active, the CANTINT1 is not generated at all.  By the way, good that you configured register CAN_IP_MUX21 to trigger the message object interrupts to line 1.  Note the description of this register that bit 0 is for object 32, bit 1 for object 1...etc in case you will have to configure specific object to interrupt line 1, but for this illustration, it is fine to configure all message object to line 1.

    2.) In the ISR, shift the 'status' by 16 bits to the right.  The function CAN_getInterruptCause() returns status of INT0 and INT1, where INT1 will be in the upper 16bits:

                status = CAN_getInterruptCause(CANA_BASE) >> 16;

    Regards,

    Joseph

  • Hi,

       Yes, I have removed CAN_INT_ERROR and CAN_INT_STATUS bits. It can generate CAN1INT. Thanks very much!

       But, what makes me curious is why I set CAN_INT_ERROR and CAN_INT_STATUS bits, the CAN module never generate CAN1INT? Although I know that ERROR interrupt and STATUS interrupt will generate through CAN0INT. But, if I set CAN_INT_ERROR and CAN_INT_STATUS bits, it will prevent generate CAN1INT. Is it? Why? As customers, we may often keep the CAN_INT_ERROR and CAN_INT_STATUS bits, when we modify from CAN0INT to CAN1INT.

  • Hi Lei,

    Yes, you have a valid point.  Let me check with our design team on why enabling the error and status flags on the the CAN control register when CAN interrupt line 1 is enabled will not propagate the interrupt.  There is likely a reason why such is the implementation in design.  It might take a while to get some response so please expect some delays.

    Regards,

    Joseph

  • Hi,

       Is there any news?

  • Hi Lei,

    Our design team is looking into this but I have not received results of their investigation yet.

    Joseph

  • Hi Lei,

    Our design team has confirmed that this is not a bug and that if CAN1NT is used and error and status flags are inadvertently routed to CAN1INT, then interrupt will not be generated.  We will have to add a note in our documentations to emphasize this.

    Regards,

    Joseph