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.

CCS/TMS320F28379D: CAN_External_Transmit source code issues

Part Number: TMS320F28379D


Tool/software: Code Composer Studio

Hi all,

          I am debugging the CAN_External_Transmit source code in F2837x control card for data transmission. The source code is perfectly working if tested between 2 CAN ports of an individual card, but failing to operate with similar CAN PORTS of 2 different control cards. I want to share some more informations regarding the status of CANA and CANB registers while performing the data transmission between 2 CAN ports:

In CANa register:

1) Last Error code (LEC) = 111, TxRqstReg1 = 01, Msg valid Register1 = 01, Access Data bytes (0-3) = 1,

2) Access Data bytes (4-7) = 1, Transmit Interrupt Enable = 1, Transmit Request = 1, End of Block = 1,

3) Data Length Code = 1000, 

4) CAN_IF1DATB and CAN_IF1DATA

Data Byte 0 = 01111100, 
Data_1 = 10000001,
Data_2 = 01111010,
Data_3 = 10001010,
Data_4 = 10000010,
Data_5 = 10000010,
Data_6 = 01110101,
Data_7 = 10000001,

In CANb register almost all parameters are having value of zero.

Can anyone suggest some informations based on above parameters to find out the reason of not having proper data transmission between the CAN ports.

Thanks in advance.


Regards
Sumanta

  • Hi Sumanta,

    As per your query the CAN_External_Transmit is working if you use the CAN transceivers on the same control card using external CAN Transceivers.
    You are now trying to split the example and use two different control cards, to communicate. CAN A is transmitting data and CAN B is receiving data.

    If you are Transmitting the data from CAN A you should get an interrupt when the data is sent successfully and CAN B receives the data.
    The configuration of both the CAN A for transmission and CAN B for reception needs to be done properly.

    CAN B should be waiting for the data to be received when CAN A starts to transmit data. Can you check if the configuration is being done properly and data is being written on the message RAM.

    If you can provide more detail of your example maybe it will be easier to help.

    Thanks and Regards
    Harshmeet Singh
  • Hi Harshmeet,

                            Thanks for your response, can you clear my confusion regarding the configuration settings for CAN A starts to transmit data and CAN B to wait for receiving the same. Please show some insight regarding the procedure of checking the data which is getting written on the message RAM.

    Thanks in advance.

    Regards

    Sumanta   

  • Hi Sumanth,

    For the transmitter side you need to set the Bit Rate and Enable the interrupt. After you setup the message object for transmit you need to go into a loop to transmit data until the message is received by the receiver side and a transmit interrupt occurs.

    For the receiver side also you need to set the bit rate and enable the interrupt and then setup the message object for receive and go into a loop till data sent is received and an interrupt occurs.

    The message RAM can only be accessed in debug mode. The message RAM base address is 0x1000 above the base address of the CAN peripheral.

    Can you share some details regarding your usage so that i can help better otherwise this may help you debug.

    Thanks and Regards

    Harshmeet Singh

  • Hi Harshmeet,

                            As you have suggested I have implemented the same in my code as below:

    Transmitter side:

    1) set the Bit rate- CANBitRateSet(CANA_BASE, 200000000, 500000) and

        enable the interrupt- CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS),

    2) setup the message object for transmit:

    sTXCANMessage.ui32MsgID = 0x5555;
    sTXCANMessage.ui32MsgIDMask = 0;
    sTXCANMessage.ui32Flags = 0;
    sTXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
    sTXCANMessage.pucMsgData = txMsgData

     

    3) Go into a loop to transmit data until the message is received by the receiver side and a transmit interrupt occurs

    for(i = 0; i < TXCOUNT; i++)
    {
    //
    // Check the error flag to see if errors occurred
    //
    /* if(errorFlag)
    {
    asm(" ESTOP0");
    }
    */
    //
    // Verify that the number of transmitted messages equal the number of
    // messages received before sending a new message
    //
    if(txMsgCount == rxMsgCount)
    {
    //
    // Transmit Message
    //
    CANMessageSet(CANA_BASE, TX_MSG_OBJ_ID, &sTXCANMessage, MSG_OBJ_TYPE_TX);

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

    //
    // Delay 0.25 second before continuing
    //
    DELAY_US(1000 * 250);

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

     

    Receiver side

    1) set the Bit rate- CANBitRateSet(CANB_BASE, 200000000, 500000) and

        enable the interrupt- CANIntEnable(CANB_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS),

    2) setup the message object for transmit:

    sRXCANMessage.ui32MsgID = 0x5555;
    sRXCANMessage.ui32MsgIDMask = 0;
    sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE;
    sRXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
    sRXCANMessage.pucMsgData = rxMsgData

     

    3) Go into a loop to transmit data until the message is received by the received and a transmit interrupt occurs

    __interrupt void canbISR(void)
    {
    uint32_t status;

    //
    // Read the CAN-B interrupt status to find the cause of the interrupt
    //
    status = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);

    //
    // 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 = CANStatusGet(CANA_BASE, CAN_STS_CONTROL);

    //
    // Check to see if an error occurred.
    //
    if(((status & ~(CAN_ES_RXOK)) != 7) &&
    ((status & ~(CAN_ES_RXOK)) != 0))
    {
    //
    // 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 == RX_MSG_OBJ_ID)
    {
    //
    // Get the received message
    //
    CANMessageGet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, true);

    //
    // 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.
    //
    CANIntClear(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
    //
    CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);

    //
    // Acknowledge this interrupt located in group 9
    //
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
    }

     

    With above code data transmission is failing to happened. 

    Please suggest if anything wrong in the source codes.

    Thanks in advance.

    Regards

    Sumanta

  • Hi Sumanta,

    The code you have shared looks correct for the transmitter side looks correct.

    But the receiver side has some problem. Are using CANA to receive from the other boards because of the CAN Transceiver being there or are you connecting external CAN Transceiver to CANB?
    Because i see you setting the Bit Rate of CANB and receiving from CANA on the receiver side. So there is something incorrect over there. Can you take a look at that and correct it.

    And can you also check the GPIO Configuration and initialize according to the CAN Controller you are using. Hope this helps.


    Thanks and Regards
    Harshmeet Singh
  • Hi Harshmeet,

                            The basic block diagram of my present work is as below:

    So at present only a single CAN port from both MCUs are utilised for CAN based data transfer. On running my source code, pulsating positive signals are getting obtained at the following terminals:

    1) CAN bus, 2) Transmitter MCU receiver and 3) Both Transmitter and receiver terminals of Receiver MCU.

    But the issue is with obtaining data at Receiver variable of Watch Window. Please suggest.

    Thanks in advance.

    Regards

    Sumanta

  • Hi Harshmeet,

                           Actually from observations of waveforms in receiver and transmitter terminals of individual MCUs and at the CAN bus, it is confirmed that as both the transmitting and receiving feature of both CAN ports are enabled, so the data getting transmitted from one MCU is appearing at CAN bus which is again received by the receiver terminal of the same MCU and getting stored in the common messagebox. So can you suggest the modifications in the source code so that data from MCU1 gets transmitted and get received in MCU2 which then gets stored in separate message boxes.

    Thanks in advance.

    Regards

    Sumanta 

  • Hi Sumanta,

    When i said "Go into a loop to transmit data until the message is received by the received and a transmit interrupt occurs" the loop has to be in the main and if the data is being transmitted successfully it should get a transmit interrupt.

    So if you are getting the data in the receiver side then are you getting a transmit interrupt? Can you see the data in the Message RAM at transmit side?

    In the receiver side also you have to put a loop in the main to wait for the data to be there and check for a receive interrupt. You need to check if the message box where you are getting the data from is the one you are initializing.

    Check if the data is there in the Message RAM.

    Thanks and Regards,
    Harshmeet Singh