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.

TMS570LS3137: CAN TX ID : Difficulties to change CAN messageBox ID for TX

Part Number: TMS570LS3137
Other Parts Discussed in Thread: HALCOGEN

Hello !

I'm trying to manage CAN bus with several modules, which have a proper ModID (100, 110, 120...).
There are 9 packet types for each module (ID 100 to 108 for module 1, 110 to 118 for module 2).
Five of the packet IDs are for messages from master to module, and the remaining four are module to master.

I used HalCoGen (TMS570+FreeRTOS) to configure messageBoxes with masks for RX. With the help of the RTM and this forum, I manage to get CAN ID for RX (function below).


But I have some difficulties with the TX ID. I understand I need to edit IFxCMD to set Arb in order to change IFxARB, but I think I doing it wrong, since the ID is not changed.


Here's my TX function, is there someone who could help me ?

uint32_t canTransmitID(canBASE_t *node, uint32_t messageBox, const uint8_t *data, uint32_t msgBoxID)
{
    uint32_t i;
    uint32_t success  = 0U;
    uint32_t regIndex = (messageBox - 1U) >> 5U;
    uint32_t bitIndex = 1U << ((messageBox - 1U) & 0x1FU);

    /** - Check for pending message:
    *     - pending message, return 0
    *     - no pending message, start new transmission
    */
    if (node->TXRQx[regIndex] & bitIndex)
    {
        return success;
    }

    /** - Wait until IF1 is ready for use */
    while (node->IF1STAT & 0x80);

    /** - Copy TX data into IF1 */
    for (i = 0U; i < 8U; i++)
    {
#ifdef __little_endian__
        node->IF1DATx[i] = *data++;
#else
        node->IF1DATx[s_canByteOrder[i]] = *data++;
#endif
    }

    node->IF1CMD |= 0x200000U;

    node->IF1ARB &= 0xE0000000U;
    node->IF1ARB |= (msgBoxID & 0x1FFFFFFFU);

    /** - Copy TX data into message box */
    node->IF1NO = messageBox;

    success = 1U;
    return success;
}

uint32_t canGetID(canBASE_t *node, uint32_t messageBox)
{
    uint32_t   msgBoxID  = 0U;

    /** - Wait until IF2 is ready for use */
    while (node->IF2STAT & 0x80);

    /** - Configure IF2 for
    *     - Message direction - Read
    *     - Data Read
    *     - Clears NewDat bit in the message object.
    */
    node->IF2CMD = 0x20U;

    /** - Copy data into IF2 */
    node->IF2NO = messageBox;

    /** - Wait until data are copied into IF2 */
    while (node->IF2STAT & 0x80);

    /* Read Message Box ID from Arbitration register. */
    msgBoxID = (node->IF2ARB & 0x1FFFFFFFU);

    return msgBoxID;

}


Thanks,
Regards,
Jean-Marie

  • Hi Jean-Marie,

    I wonder if the write to the 1F1ARB is being blocked because the register is privilege protected while the RTOS operates in user mode. Please note that the IFxCMD and IFxARB are privileged protected registers. You need to be in system mode to write these registers. Are you using xTaskCreate(). If yes, please use "xTaskCreateRestricted()" instead to create a task that operates in system mode.
  • Hi Charles,

    Thank you for your answer.

    Yes I use xTaskCreate(). I don't know xTaskCreateRestricted(), I will do some research to use it.


    In my case, the TX function is called in the interrupt "canMessageNotification" for the moment.

  • Hello again,

    So, I tried xTaskCreateRestricted, but with no success. I made a privileged task, but TX ID doesn't change. I'm not comfortable with the MPU, so I may not have correctly configured the task (code is below).

    Maybe my use of the CAN registers is wrong in the function canTransmitID (the code is in the first post of the topic, in red). Am I rightfully using IFxCMD ?

    Thanks,

    static portSTACK_TYPE xTaskStack[ 128 ];
    char cSendMsgCANArray[ 512 ];

    static const xTaskParameters xTaskDefinition =
    {
        vSendMsgCAN,
        "SendMsgCAN",
        128,   
        NULL,
        ( 1UL | portPRIVILEGE_BIT ),
        xTaskStack,
        {
            { cSendMsgCANArray, 512, MPU_PRIV_RW_USER_RW_EXEC }
        }
    };

    /* SendMsgCAN */
    void vSendMsgCAN(void *pvParameters)
    {
        const portTickType xDelay1s = pdMS_TO_TICKS(1001);
        uint8_t i = 0;
        for(;;)
        {
            tx_numMsg[0] = i;
            tx_numMsg[1] = i+1;
            tx_numMsg[2] = i+2;
            tx_numMsg[3] = i+3;
            dataGlobal.UelMin++;

            canTransmitID(canREG2, canMESSAGE_BOX1, tx_numMsg, i);

            i = (i+1)%240;

            vTaskDelay(xDelay1s);
        }
    }


    in main() :
    xTaskCreateRestricted( &xTaskDefinition, NULL );

  • So, I have my solution !


    I had two problems in my code.

    First, I was doing node->IF1CMD |= 0x200000U; instead of node->IF1CMD |= 0x20U;

    I tought IF1CMD was the command register (32bits) but it's just the 2 command bytes.

    Second, I was doing node->IF1ARB &= 0xE0000000U; instead of node->IF1ARB = 0xE0000000U;

    I didn't initialize the ARB register in write mode (bit Dir).

    Thank you for your time.

  • Glad your problem is resolved. Sorry, I didn't catch the mistake by reading your code.