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.

TMS320F28379D: F2837x CAN example issue

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Hi

I have a few troubles on F2837x CAN programming. When I read TI's CAN examples, I found a few issues that confuse me:

1. row 212 in can8_ex8_remote_tx.c of can8_ex8_remote_tx example, the following function call sends the data to a can receiver (CANA),

    I think it should send to CANB's remote output channel for a new data replace.

        CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH, rxMsgData);

2. in can.c in driverlib, there is a function CAN_sendRemoteRequestMessage, it gets IF1MCTL to check DLC that is ok, but it sets msgCtrl to IF1CMD, is it a bug?

  • Sorry by sending a wrong image, the correct one is as below:

  • Hi Jiakai,

    Expert is out of office. Please expect the response by 1/8.

    Thanks,

    Susmitha Bumadi

  • Jiakai, 

    in can.c in driverlib, there is a function CAN_sendRemoteRequestMessage, it gets IF1MCTL to check DLC that is ok, but it sets msgCtrl to IF1CMD, is it a bug?

    You are right, this is a bug. It should instead read the following:

    HWREG_BP(base + CAN_O_IF1CMD) = ((uint32_t)CAN_IF1CMD_DIR |
                                         (uint32_t)CAN_IF1CMD_TXRQST |
                                         (objID & CAN_IF1CMD_MSG_NUM_M));

    Thanks.

  • Jiakai, 

    CAN_sendMessage(CANA_BASE, TX_MSG_OBJ_ID, MSG_DATA_LENGTH, rxMsgData);

    This function call should actually be replaced by the following:

    CAN_sendRemoteRequestMessage(CANA_BASE, TX_MSG_OBJ_ID);

    (note that the above API will need to be updated as discussed in the previous post for it to work as expected)

    This way, CAN-A will send the remote request, which when received by CAN-B will trigger an automatic response, leading to a message being transmitted by CAN-B which will be received by CAN-A. 

    Appreciate you pointing out these errors.

    Thanks.

  • Hi Sahil,

    Happy New Year!

    Thank you for your quick reply.

    I'm trying to write a DCAN communication program, now normal input/output message boxes can be sent/received successfully, but the remote request doesn't work. Here are the functions for remote request:

    // Can messageBox type
    #define CAN_MSG_INPUT_TYPE          1   // CAN_MSG_OBJ_TYPE_RX
    #define CAN_MSG_OUTPUT_TYPE         2   // CAN_MSG_OBJ_TYPE_TX
    #define CAN_MSG_REMOTEOUT_TYPE      3   // CAN_MSG_OBJ_TYPE_TX_REMOTE
    #define CAN_MSG_REMOTEINOUT_TYPE    4   // CAN_MSG_OBJ_TYPE_RXTX_REMOTE
    
    struct PST_eCanMsgID_Bits
    {        // bits  description
        Uint32 MsgID:29;    // 0:28
        Uint32 Dir:1;          // 29
        Uint32 Xtd:1;          // 30
        Uint32 MsgVal:1;    // 31
    };
    
    union PST_CanMsgID_Reg
    {
        struct PST_eCanMsgID_Bits ebit;
        Uint32  all;
    };
    
    struct PST_CanMsgCtrl_Bits
    {   // bits  description
        Uint32  DLC:4;          // 0:3 data length
        Uint32  MsgNo:5;        // 4:8 message ID
        Uint32  MsgType:3;      // 9:11 message type: CAN_MSG_INPUT_TYPE, CAN_MSG_OUTPUT_TYPE, CAN_MSG_REMOTEOUT_TYPE and CAN_MSG_REMOTEINOUT_TYPE
        Uint32  rsvd:20;        // 12:31 reserved
    };
    
    union PST_CanMsgCtrl_Reg
    {
        struct PST_CanMsgCtrl_Bits bit;
        Uint32 all;
    };
    
    union PST_CanMD_Reg
    {
        Uint32 MData[2];
        Uint64 MData64;
    };
    
    typedef struct
    {
        union PST_CanMsgID_Reg MSGID;
        union PST_CanMsgCtrl_Reg MSGCTRL;
        union PST_CanMD_Reg MD;
    } PST_MBox;
    
    
    void PS_CanRemReq(PST_MBox* pBox)
    {
        Uint16 mailbox_number; // valid numbers are 1 to 32
        Uint16 loop_count;
    
        mailbox_number = (pBox->MSGCTRL.bit.MsgNo + 1) & CAN_IF1CMD_MSG_NUM_M;
    
        //
        // Wait for busy bit to clear
        //
        loop_count = 20;
        while (((HWREGH(PSK_CanBase + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY) && (loop_count--));
    
        //
        // Read IF message control
        //
    //    msgCtrl = HWREGH(PSK_CanBase + CAN_O_IF1MCTL);
    
        HWREG_BP(PSK_CanBase + CAN_O_IF1CMD) = CAN_IF1CMD_DIR | CAN_IF1CMD_TXRQST | mailbox_number;
    } // end PS_CanRemReq
    
    void PS_CanRemData(PST_MBox* pBox)
    {
        Uint16  loop_count = 20;
        Uint32  cmdReg = CAN_IF1CMD_DIR | ((pBox->MSGCTRL.bit.MsgNo + 1) & CAN_IF1CMD_MSG_NUM_M);
        while ( ((HWREGH(PSK_CanBase + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
                && (loop_count--) );
        //
        // Write the data out to the CAN Data registers.
        //
        switch (pBox->MSGCTRL.bit.DLC) {
        default:
        case 8:
        case 7:
        case 6:
        case 5:
            HWREG_BP(PSK_CanBase + CAN_O_IF1DATB) = pBox->MD.MData[1];
            cmdReg |= CAN_IF1CMD_DATA_B;
        case 4:
        case 3:
        case 2:
        case 1:
            HWREG_BP(PSK_CanBase + CAN_O_IF1DATA) = pBox->MD.MData[0];
            cmdReg |= CAN_IF1CMD_DATA_A;
            break;
        case 0:
            break;
        }
        HWREG_BP(PSK_CanBase + CAN_O_IF1CMD) = cmdReg;
    
    } // end PS_CanRemData
    
    void PS_CanMailBoxInit(Uint16 mailbox_number, Uint32 msgID,
            Uint32 maskID, Uint16 msgLen, Uint16 msgBoxType, Uint16 extension_flag)
    {
        Uint16 loop_count;
        //uint32_t base;
        uint32_t cmdReg = 0UL;
        uint32_t maskReg = 0UL;
        uint32_t arbReg = 0UL;
        uint32_t msgCtrl = 0UL;
    
        assert( mailbox_number < MBOX_MAX );
    
        // CAN module numbers mailboxes 1-32
        mailbox_number++;
    
        // wait for IF1 registers to become available
        loop_count = 20;
        while ( ((HWREGH(PSK_CanBase + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
                && (loop_count--) );
    
        switch (msgBoxType) {
        case CAN_MSG_INPUT_TYPE: // receive
            msgCtrl |= CAN_IF1MCTL_RXIE; // enable receive interrupt
            // bit 1 is mailbox 1, bit 2 is mbox 2, bit 0 is mbox 32!!!
            HWREG_BP(PSK_CanBase + CAN_O_IP_MUX21) |= 1UL << (mailbox_number & 0x01F); // Rx int to INT1
            break;
        case CAN_MSG_OUTPUT_TYPE:
            arbReg = CAN_IF1ARB_DIR;
            break;
        case CAN_MSG_REMOTEINOUT_TYPE:
            arbReg = CAN_IF1ARB_DIR;
            // Set this object to auto answer if a matching identifier is seen.
            msgCtrl = (uint32_t)((uint32_t)CAN_IF1MCTL_RMTEN | (uint32_t)CAN_IF1MCTL_UMASK);
            break;
        case CAN_MSG_REMOTEOUT_TYPE:
            arbReg = CAN_IF1ARB_DIR;
            break;
        default:
            assert( 0 );
            break;
        }
    
        if (extension_flag)
        {
            arbReg |= CAN_IF1ARB_MSGVAL | CAN_IF1ARB_XTD | (CAN_IF1MSK_MSK_M & msgID);
            if (maskID != 0UL)
            {
                maskReg = CAN_IF1MSK_MXTD | (maskID & CAN_IF1MSK_MSK_M);
                msgCtrl |= CAN_IF1MCTL_UMASK;
            }
        }
        else
        {
            arbReg |= CAN_IF1ARB_MSGVAL | ((msgID << CAN_IF1ARB_STD_ID_S) & CAN_IF1ARB_STD_ID_M);
            if (maskID != 0UL)
            {
                maskReg = ((maskID << CAN_IF1ARB_STD_ID_S) & CAN_IF1ARB_STD_ID_M);
                msgCtrl |= CAN_IF1MCTL_UMASK;
            }
        }
    
        msgCtrl |= msgLen & CAN_IF1MCTL_DLC_M; // data length
    //  if (last)
    //  {
    //      msgCtrl |= CAN_IF1MCTL_EOB;
    //  }
    
        // set control arb and mask bits so they get transferred to the message object
        cmdReg = CAN_IF1CMD_DIR | CAN_IF1CMD_MASK | CAN_IF1CMD_ARB | CAN_IF1CMD_CONTROL;
        // set message object number
        cmdReg |= (mailbox_number & CAN_IF1CMD_MSG_NUM_M);
    
        // wait for IF1 registers to become available
        loop_count = 20;
        while ( ((HWREGH(PSK_CanBase + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
                && (loop_count--) );
    
        // Write out the registers to program the message object.
        HWREG_BP(PSK_CanBase + CAN_O_IF1MSK) = maskReg;
        HWREG_BP(PSK_CanBase + CAN_O_IF1ARB) = arbReg;
        HWREG_BP(PSK_CanBase + CAN_O_IF1MCTL) = msgCtrl;
        HWREG_BP(PSK_CanBase + CAN_O_IF1CMD) = cmdReg;
    } // end PSI_CanMailBoxInit
    

    All message boxes are initialized by PS_CanMailBoxInit(), program calls PS_CanRemReq() to send out a remote request, and calls PS_CanRemData() to renew the data of remote message box.

    Could you please take time to check if there are anything wrong in these functions?

    Thank you very much!

    Jiakai

  • Jiakai,

         If this is a new issue, please open a new thread with the appropriate title. In any case, remote communication examples are provided as part of C2000ware Driverlib examples. Please try them. 

    Please download my Application report http://www.ti.com/lit/SPRACE5 and look at the Debug tips provided. Most CAN issues can be resolved by going through this checklist.

  • Hareesh,

    I will download the project and check the code.

    Thanks,