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.

TMS320F280040-Q1: DCAN Configuration to receive different Message Objects ID

Part Number: TMS320F280040-Q1
Other Parts Discussed in Thread: C2000WARE, SYSCONFIG

Hi,

I'm not being able to identify two different message objects received into DCAN controller. The desirable configuration should trip an interruption every time a message is received and the filter ID would allow identifying with which Message Object ID has caused the interrupt. However, when I test the INT0ID register inside ISR its value is always 1, doesn't matter which Message Identifier was used to transmit the messages. 

I would like to know how to identify different received massages based on Message Identifier (What I'm supposed to be the CAN_ID).

Here there is the configuration of CAN controller (generated by SysConfing 11)

void CAN_init(){

	//myCAN0 initialization
	CAN_initModule(myCAN0_BASE);

	// 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_setBitTiming(myCAN0_BASE, 7, 0, 15, 7, 3);

	// Enable CAN Interrupts
	CAN_enableInterrupt(myCAN0_BASE, CAN_INT_IE0);

	CAN_enableGlobalInterrupt(myCAN0_BASE, CAN_GLOBAL_INT_CANINT0);          
	// Initialize the transmit message object used for sending CAN messages.
	// Message Object Parameters:
	//      Message Object ID Number: 1
	//      Message Identifier: 882
	//      Message Frame: CAN_MSG_FRAME_STD
	//      Message Type: CAN_MSG_OBJ_TYPE_RX
	//      Message ID Mask: 0
	//      Message Object Flags: CAN_MSG_OBJ_RX_INT_ENABLE,CAN_MSG_OBJ_USE_ID_FILTER
	//      Message Data Length: 0 Bytes
	//
	CAN_setupMessageObject(myCAN0_BASE, 1, myCAN0_MessageObj1_ID_DRIVERLIB_INP, CAN_MSG_FRAME_STD,CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE|CAN_MSG_OBJ_USE_ID_FILTER,0);
	// Initialize the transmit message object used for sending CAN messages.
	// Message Object Parameters:
	//      Message Object ID Number: 2
	//      Message Identifier: 58
	//      Message Frame: CAN_MSG_FRAME_STD
	//      Message Type: CAN_MSG_OBJ_TYPE_RX
	//      Message ID Mask: 0
	//      Message Object Flags: CAN_MSG_OBJ_RX_INT_ENABLE
	//      Message Data Length: 0 Bytes
	//
	CAN_setupMessageObject(myCAN0_BASE, 2, myCAN0_MessageObj2_ID_DRIVERLIB_INP, CAN_MSG_FRAME_STD,CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,0);
	CAN_setInterruptMux(myCAN0_BASE, 0);
	//
	// Start CAN module operations
	//
	CAN_startModule(myCAN0_BASE);
}

  This is the Interrupts setup

void INTERRUPT_init(){
	
	// Interrupt Setings for INT_ADC_C_1
	Interrupt_register(INT_ADC_C_1, &INT_ADC_C_1_ISR);
	Interrupt_enable(INT_ADC_C_1);
	
	// Interrupt Setings for INT_myCAN0_0
	Interrupt_register(INT_myCAN0_0, &INT_myCAN0_0_ISR);
	Interrupt_enable(INT_myCAN0_0);
	
	// Interrupt Setings for INT_myCAN0_1
	Interrupt_register(INT_myCAN0_1, &INT_myCAN0_1_ISR);
	Interrupt_disable(INT_myCAN0_1);
}

And here there is the ISR (based on driverlib example)

__interrupt void INT_myCAN0_0_ISR(void)
{
    uint32_t status;

    //
    // Read the CAN-B interrupt status to find the cause of the interrupt
    //
    status = CAN_getInterruptCause(myCAN0_BASE); //  <--Always return 1

    //
    // 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(myCAN0_BASE);

        //
        // 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
    //
   
    else if(status == 1)
    {
        //
        // Get the received message
        //

          CAN_readMessage(myCAN0_BASE, 1 , Payload);

        
        // 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(myCAN0_BASE, 1);


        
        // 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.
      
        
        // Since the message was received, clear any error flags.
        
        errorFlag = 0;
    }
    else if (status == 2)
    {

        CAN_readMessage(myCAN0_BASE, 2 , Payload);

        
        // 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(myCAN0_BASE, 2);

        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_CANINT0);

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

Any help would be much appreciated. 

Cheers

  • Luciano,

    However, when I test the INT0ID register inside ISR its value is always 1, doesn't matter which Message Identifier was used to transmit the messages. 

    Please refer to my App. Report www.ti.com/lit/SPRACE5. I have explained how the filter mask works with an example (which can be downloaded as part of c2000ware.

    I'm not being able to identify two different message objects received into DCAN controller.

    It is important to distinguish Message Objects (also referred to as Mailboxes) and the Message ID of frames (MSGID or ARBID) that are received into the message objects.  So I am unable to understand what you mean by "I'm not being able to identify two different message objects received into DCAN controller" Message objects exist inside the DCAN module. You don't "receive" them. The received frames are stored in the message objects.

    The desirable configuration should trip an interruption every time a message is received

    Yes, it is simple to generate an interrupt when a frame is received in  a message object. Refer to C2000ware examples.

    and the filter ID would allow identifying with which Message Object ID has caused the interrupt.

    No, the filter mask only determines which MSGIDs are received in a particular message object. It has nothing to do with interrupts.

    when I test the INT0ID register inside ISR its value is always 1, doesn't matter which Message Identifier was used to transmit the messages. 

    INT0ID register will only reflect the message object that generated the interrupt. It has nothing to do with the message identifier. The MSGID (or ARBID) has to be read from the IFxARB register through the IFx register set.

  • Hello Hareesh, thank you for your reply.

    Let me rephrase some points of my problem, hopefully it would allow you to give me other set of inputs.

    Considering two different data frames (for instance, Message IDs 0x372 and 0x58) can I configure the DCAN controller such that each dataframe information is stored in one particular mailbox? As far as I understood, the DCAN controller has 32 mailboxes and there is a possibility of filtering the inbound dataframes by message ID, am I correct? 

    I looked at the document you suggested, it's very nice, however, I would like to see an example of mask/filtering using CAN standard mode (11 bits arbitration). Complementary, any cross-reference with SysConfig tool would be very helpful.

    Finalizing my set of questions, if the assumption of having two mailboxes, each one handling a particular dataframe information, filtered by message IDs, is this correct to assume that when one of these dataframes are received by DCAN controller, triggering an interrupt, the content of  INT0ID will show which mailbox has the new data?

    I much appreciate your time,

    Regards,

  • Considering two different data frames (for instance, Message IDs 0x372 and 0x58) can I configure the DCAN controller such that each dataframe information is stored in one particular mailbox? 

    Yes, that is what filtering is all about and that is demonstrated by my example in SPRACE5.

    As far as I understood, the DCAN controller has 32 mailboxes and there is a possibility of filtering the inbound dataframes by message ID, am I correct? 

    Correct.

    I would like to see an example of mask/filtering using CAN standard mode (11 bits arbitration).

    The filtering principle is exactly identical for both Extended and Standard frames. Sorry, we don't have a separate example for standard frames.

    is this correct to assume that when one of these dataframes are received by DCAN controller, triggering an interrupt, the content of  INT0ID will show which mailbox has the new data?

    Correct. INT0ID or INT1D fields always reflect the mailbox # that caused the interrupt.