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.

TMS320F28388D: Is it possible to send CAN frames with different IDs with a single Mailbox configured?

Part Number: TMS320F28388D


Hello,

I declare a single mailbox as output (extended mode with IT TXIE): 

with id_base = frame ID: 0x18FF50E5 and SC_CAN_NUMMAILBOX_TX = num Mailbox: 1

Then I want to send two consecutive frames via the same num Mailbox but with a different frame ID: the first ID = 0x18FF50E5 the second with ID 0x18FF51E5 .

Both frames have the same ID:

I wanted to use the CAN_sendMessage_updateDLC function because the two frames have two different DLCs.

I tried to make my own function from this one: CAN_sendMessage_updateMsgIdMsgDLC to add the identifier as an argument, writing it to the CAN_IF1ARB register: 

The ID has the desired address: 0x18FF51E5 But the frame actually output retains the initial address inserted viia CAN_setupMessageObject

So, is it possible to transmit CAN frames with different IDs with a single Mailbox configured as output?

Thanks for your help.

Eric

  • Eric, 

    Will get back to you on this by tomorrow. 

    Thanks.

  • Hi Sahi,

    ok I'm waiting your feedback.

    Regards,

    Eric

  • Eric, 

    I tried to make my own function from this one: CAN_sendMessage_updateMsgIdMsgDLC to add the identifier as an argument, writing it to the CAN_IF1ARB register

    The process of writing to any message object involves updating the arbitration register AND then writing to the command register (CAN_IF1CMD) with Dir bit set to 1. 

    So, is it possible to transmit CAN frames with different IDs with a single Mailbox configured as output?

    It is possible. I can provide you with a validated function for this by Wednesday, 21st February. 

    Thanks. 

  • Hi Sahil,

    thank you for your reply.

    The process of writing to any message object involves updating the arbitration register AND then writing to the command register (CAN_IF1CMD) with Dir bit set to 1. 

    it seems to me that's what I'm doing, but probably badly:  

    static void CAN_sendMessage_updateMsgIdMsgDLC(uint32_t base, uint32_t objID,
                                                  SC_CAN_frame_type_t msgType, uint32_t msgID,
                                                  uint16_t msgLen, const uint8_t *msgData)
    {
        uint32_t arbReg = 0U;
        uint32_t msgCtrl = 0U;
    
        //
        // Check the arguments.
        //
        ASSERT(CAN_isBaseValid(base));
        ASSERT((objID <= 32U) && (objID > 0U));
        ASSERT(msgLen <= 8U);
    
        //
        // Set IF command to read message object control value
        //
        // Set up the request for data from the message object.
        // Transfer the message object to the IF register.
        //
        HWREG_BP(base + CAN_O_IF1CMD) = ((uint32_t)CAN_IF1CMD_CONTROL |
                                         (objID & CAN_IF1CMD_MSG_NUM_M));
    
        //
        // Wait for busy bit to clear
        //
        while((HWREGH(base + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
        {
        }
    
        //
        // Read IF message control
        //
        msgCtrl = HWREGH(base + CAN_O_IF1MCTL);
    
        //------
        // Modif EF add "ID"
        //-----
        
        arbReg = CAN_IF1ARB_DIR; // Sens Tx
        //
        // Set values based on Extended Frame or Standard Frame
        //
        if(msgType == SC_CAN_FRAME_TYPE_DATA_EXT)
        {
            //
            // Set the 29 bit version of the Identifier for this message
            // object. Mark the message as valid and set the extended ID bit.
            //
            arbReg |= (msgID & CAN_IF1ARB_ID_M) | CAN_IF1ARB_MSGVAL |
                      CAN_IF1ARB_XTD;
        }
        else
        {
            //
            // Set the 11 bit version of the Identifier for this message
            // object. The lower 18 bits are set to zero. Mark the message as
            // valid.
            //
            arbReg |= ((msgID << CAN_IF1ARB_STD_ID_S) & CAN_IF1ARB_STD_ID_M) |
                      CAN_IF1ARB_MSGVAL;
        }
        HWREG_BP(base + CAN_O_IF1ARB) = arbReg;
        // End Modif EF of add "ID"
        //-----
    
        //
        // Update to the new data length
        //
        msgCtrl &= ~CAN_IF1MCTL_DLC_M;
        msgCtrl |= (msgLen & CAN_IF1MCTL_DLC_M);
    
        //
        // Write out to the register to program the message object
        //
        HWREG_BP(base + CAN_O_IF1MCTL) = msgCtrl;
    
        //
        // Transfer data to message object RAM
        //
        HWREG_BP(base + CAN_O_IF1CMD) =
            (CAN_IF1CMD_CONTROL | CAN_IF1CMD_DIR | (objID & CAN_IF1CMD_MSG_NUM_M));
    
        //
        // Wait for busy bit to clear
        //
        while((HWREGH(base + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
        {
        }
    
        //
        // Set IF command to read message object control value
        //
        // Set up the request for data from the message object.
        // Transfer the message object to the IF register.
        //
        HWREG_BP(base + CAN_O_IF1CMD) = ((uint32_t)CAN_IF1CMD_CONTROL |
                                         (objID & CAN_IF1CMD_MSG_NUM_M));
    
        //
        // Wait for busy bit to clear
        //
        while((HWREGH(base + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
        {
        }
    
        //
        // Read IF message control
        //
        msgCtrl = HWREGH(base + CAN_O_IF1MCTL);
    
        //
        // Check provided DLC size with actual Message DLC size
        //
        ASSERT((msgCtrl & CAN_IF1MCTL_DLC_M) == msgLen);
    
        //
        // Write the data out to the CAN Data registers.
        //
        CAN_writeDataReg(msgData, (base + CAN_O_IF1DATA),
                         (msgCtrl & CAN_IF1MCTL_DLC_M));
    
        //
        //  Set Data to be transferred from IF
        //
        if(msgLen > 0U)
        {
            msgCtrl = CAN_IF1CMD_DATA_B | CAN_IF1CMD_DATA_A;
        }
        else
        {
            msgCtrl = 0U;
        }
    
        //
        // Set Direction to write
        //
        // Set Tx Request Bit
        //
        // Transfer the message object to the message object specified by
        // objID.
        //
    
        HWREG_BP(base + CAN_O_IF1CMD) = (msgCtrl | (uint32_t)CAN_IF1CMD_DIR |
                                         (uint32_t)CAN_IF1CMD_TXRQST |
                                         (objID & CAN_IF1CMD_MSG_NUM_M));
    }
    

    OK to receive your function on Wednesday 21, thank you.

    Regards,

    Eric 

  • Eric, 

    I have modified your function and have been able to validate it. 

    static void CAN_sendMessage_updateMsgIdMsgDLC(uint32_t base, uint32_t objID,
                                                  SC_CAN_frame_type_t msgType, uint32_t msgID,
                                                  uint16_t msgLen, const uint8_t *msgData)
    {
        uint32_t arbReg = 0U;
        uint32_t msgCtrl = 0U;
    
        //
        // Check the arguments.
        //
        ASSERT(CAN_isBaseValid(base));
        ASSERT((objID <= 32U) && (objID > 0U));
        ASSERT(msgLen <= 8U);
    
        //
        // Set IF command to read message object control value
        //
        // Set up the request for data from the message object.
        // Transfer the message object to the IF register.
        //
        HWREG_BP(base + CAN_O_IF1CMD) = ((uint32_t)CAN_IF1CMD_CONTROL |
                                         (objID & CAN_IF1CMD_MSG_NUM_M));
    
        //
        // Wait for busy bit to clear
        //
        while((HWREGH(base + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
        {
        }
    
        //
        // Read IF message control
        //
        msgCtrl = HWREGH(base + CAN_O_IF1MCTL);
    
        //------
        // Modif EF add "ID"
        //-----
        
        arbReg = CAN_IF1ARB_DIR; // Sens Tx
        //
        // Set values based on Extended Frame or Standard Frame
        //
        if(msgType == SC_CAN_FRAME_TYPE_DATA_EXT)
        {
            //
            // Set the 29 bit version of the Identifier for this message
            // object. Mark the message as valid and set the extended ID bit.
            //
            arbReg |= (msgID & CAN_IF1ARB_ID_M) | CAN_IF1ARB_MSGVAL |
                      CAN_IF1ARB_XTD;
        }
        else
        {
            //
            // Set the 11 bit version of the Identifier for this message
            // object. The lower 18 bits are set to zero. Mark the message as
            // valid.
            //
            arbReg |= ((msgID << CAN_IF1ARB_STD_ID_S) & CAN_IF1ARB_STD_ID_M) |
                      CAN_IF1ARB_MSGVAL;
        }
        HWREG_BP(base + CAN_O_IF1ARB) = arbReg;
        // End Modif EF of add "ID"
        //-----
    
        //
        // Update to the new data length
        //
        msgCtrl &= ~CAN_IF1MCTL_DLC_M;
        msgCtrl |= (msgLen & CAN_IF1MCTL_DLC_M);
    
        //
        // Write out to the register to program the message object
        //
        HWREG_BP(base + CAN_O_IF1MCTL) = msgCtrl;
    
        //
        // Transfer data to message object RAM
        //
        HWREG_BP(base + CAN_O_IF1CMD) =
            (CAN_IF1CMD_CONTROL | CAN_IF1CMD_DIR | CAN_IF1CMD_ARB | (objID & CAN_IF1CMD_MSG_NUM_M));                // Set bit to transfer arbitration bits to message object
    
        //
        // Wait for busy bit to clear
        //
        while((HWREGH(base + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
        {
        }
    
        //
        // Set IF command to read message object control value
        //
        // Set up the request for data from the message object.
        // Transfer the message object to the IF register.
        //
        HWREG_BP(base + CAN_O_IF1CMD) = ((uint32_t)CAN_IF1CMD_CONTROL |
                                         (objID & CAN_IF1CMD_MSG_NUM_M));
    
        //
        // Wait for busy bit to clear
        //
        while((HWREGH(base + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
        {
        }
    
        //
        // Read IF message control
        //
        msgCtrl = HWREGH(base + CAN_O_IF1MCTL);
    
        //
        // Check provided DLC size with actual Message DLC size
        //
        ASSERT((msgCtrl & CAN_IF1MCTL_DLC_M) == msgLen);
    
        //
        // Write the data out to the CAN Data registers.
        //
        CAN_writeDataReg(msgData, (base + CAN_O_IF1DATA),
                         (msgCtrl & CAN_IF1MCTL_DLC_M));
    
        //
        //  Set Data to be transferred from IF
        //
        if(msgLen > 0U)
        {
            msgCtrl = CAN_IF1CMD_DATA_B | CAN_IF1CMD_DATA_A;
        }
        else
        {
            msgCtrl = 0U;
        }
    
        //
        // Set Direction to write
        //
        // Set Tx Request Bit
        //
        // Transfer the message object to the message object specified by
        // objID.
        //
    
        HWREG_BP(base + CAN_O_IF1CMD) = (msgCtrl | (uint32_t)CAN_IF1CMD_DIR |
                                         (uint32_t)CAN_IF1CMD_TXRQST |
                                         (objID & CAN_IF1CMD_MSG_NUM_M));
    }

    Please let me know if you run into any issues using this function. 

    Thanks. 

  • Hello Sahil,

    thank you very much for your help, and sorry to reply so late, I was out of office last week.

    Your modification has corrected my problem!

    Best Regards,

    Eric