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-F28379D: CAN Communication - two way between two F28379Ds

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: C2000WARE

Hi,

I am trying to implement two way CAN communication between 2 Launchpads F28379D using the can simple transmit and receive examples from C2000Ware.

I am able to transmit and receive data on both nodes. 

However, the transmitting node's ISR is getting triggered after CAN_sendMessage function is executed. 

Below is my Transmit side main code. Could you please check if I am enabling anything that is causing a CAN interrupt after transmission on Transmit side?

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

    //
    // Initialize GPIO and configure GPIO pins for CANTX/CANRX
    // on module A
    //
    Device_initGPIO();

	//
    // Configure GPIO pins for CANTX/CANRX
	//
    GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXB);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXB);

    //
    // Initialize the CAN controllers
    //
    CAN_initModule(CANB_BASE);

    //
    // Set up the CAN bus bit rate to 500kHz for each module
    // 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(CANB_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

    //******************************ADDED FOR INTERRUPTS********************************

    //
        // Enable interrupts on the CAN peripheral.
        // Enables Interrupt line 0, Error & Status Change interrupts in CAN_CTL
        // register.
        //
        CAN_enableInterrupt(CANB_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_CANB0, &canISR);

        //
        // Enable the CAN interrupt signal
        //
        Interrupt_enable(INT_CANB0);
        CAN_enableGlobalInterrupt(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

    	//
        // Configure GPIO pins for initiating CAN Transmit
    	//
        //PinMUX
        GPIO_setPinConfig(GPIO_63_GPIO63);

        GPIO_setDirectionMode(gpioButton01,GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(gpioButton01, GPIO_PIN_TYPE_PULLUP);
    	GPIO_setMasterCore(gpioButton01, GPIO_CORE_CPU1);
        GPIO_setQualificationMode(gpioButton01,GPIO_QUAL_SYNC);

        GPIO_SetupXINT1Gpio(gpioButton01);

        GPIO_setInterruptType(GPIO_INT_XINT1, GPIO_INT_TYPE_FALLING_EDGE);
        GPIO_setInterruptPin(gpioButton01, GPIO_INT_XINT1);
        GPIO_enableInterrupt(GPIO_INT_XINT1);

        Interrupt_register(INT_XINT1, &gpio63InterruptHandler);
        Interrupt_enable(INT_XINT1);

        //
        // Enables CPU interrupts
        //
        Interrupt_enableMaster();

    //******************************ADDED END********************************


    //
    // Initialize the transmit message object used for sending CAN messages.
    // Message Object Parameters:
    //      CAN Module: A
    //      Message Object ID Number: 1
    //      Message Identifier: 0x95555555
    //      Message Frame: Extended
    //      Message Type: Transmit
    //      Message ID Mask: 0x0
    //      Message Object Flags: None
    //      Message Data Length: 4 Bytes
    //
    CAN_setupMessageObject(CANB_BASE, TX_MSG_OBJ_ID, 0x95555555,
						   CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,
                           CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH);
    //
    // Initialize the receive message object used for receiving CAN messages.
    // Message Object Parameters:
    //      CAN Module: A
    //      Message Object ID Number: 1
    //      Message Identifier: 0x1
    //      Message Frame: Standard
    //      Message Type: Receive
    //      Message ID Mask: 0x0
    //      Message Object Flags: None
    //      Message Data Length: "Don't care" for a Receive mailbox
	//
    CAN_setupMessageObject(CANB_BASE, RX_MSG_OBJ_ID, 0x12345678,
						   CAN_MSG_FRAME_EXT, 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] = 0x01;
    txMsgData[1] = 0x23;
    txMsgData[2] = 0x45;
    txMsgData[3] = 0x67;
    txMsgData[4] = 0x89;
    txMsgData[5] = 0xAB;
    txMsgData[6] = 0xCD;
    txMsgData[7] = 0xEF;

    //
    // Start CAN module A operations
    //
    CAN_startModule(CANB_BASE);

    //
    // Transmit messages from CAN-A
    //
    while(1)
	{

        //
        // Check the error flag to see if errors occurred
        //
        if(errorFlag)
        {
            Example_Fail = 1;
            asm("   ESTOP0");
        }
	}
    //
    // Stop application
    //
    asm("   ESTOP0");
}

and here is the CAN ISR

__interrupt void gpio63InterruptHandler(void)
{
    CAN_sendMessage(CANB_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH, txMsgData);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}

//
// CAN B ISR - The interrupt service routine is called when an interrupt is
//             triggered on CAN module B. It will be executed twice for every
//             frame received.
//             First time for status-change; second time for Mailbox receive.
//
__interrupt void canISR(void)
{
    uint32_t status;

    //
    // Read the CAN-B interrupt status (in the CAN_INT register) to find the
    // cause of the interrupt
    //
    status = CAN_getInterruptCause(CANB_BASE);

    //
    // If the cause is a controller status interrupt, then get the status.
    // During first iteration of every ISR execution, status = 0x8000,
    // which simply means CAN_ES != 0x07.
    //
    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(CANB_BASE);  // Return CAN_ES value.
        //
		// Now status = 0x00000010, indicating RxOK.
        //

        //
        // Check to see if an error occurred.
        //
        if(((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_MSK) &&
           ((status  & ~(CAN_STATUS_RXOK)) != CAN_STATUS_LEC_NONE))
        {
            //
            // Set a flag to indicate some errors may have occurred.
            //
            errorFlag = 1;
        }
    }
    //
    // Check if the cause is the CAN-B receive message object 1. Will be skipped
    // in the first iteration of every ISR execution
	//
    else if(status == RX_MSG_OBJ_ID)
    {
        //
        // Get the received message
        //
        CAN_readMessage(CANB_BASE, RX_MSG_OBJ_ID, rxMsgData);

        //
        // Getting to this point means that the RX interrupt occurred on
        // message object 1, and the message RX is complete.  Clear the
        // message object interrupt.
        //
        CAN_clearInterruptStatus(CANB_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(CANB_BASE, CAN_GLOBAL_INT_CANINT0);

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

Regards,

Rashmitha