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.

RM46L852: Trouble updating data in CAN message object

Part Number: RM46L852
Other Parts Discussed in Thread: HALCOGEN

Hi.

I am having trouble updating a CAN message object. The application I am prototyping on will require a lot more then 64 CAN messages, so I will have to dynamically change the content of message objects.

I have used HALCoGen to generate code, then written a modified version of CanTransmit, see code snippet below. The ID and DLC are correct, but on the CAN-bus no data is present.

What am I missing?

uint32 ExtCanTransmit(canBASE_t *node, uint32 messageBox, uint16 msgBoxArbitVal, uint8 dlc, const uint8 * data)

{

uint32 i;

uint32 success = 0U;

uint32 regIndex = (messageBox - 1U) >> 5U;

uint32 bitIndex = 1U << ((messageBox - 1U) & 0x1FU);

// Check input arguments

if (messageBox > 64U || msgBoxArbitVal > 0x7FFU || dlc > 8U) {

// Error! \todo add ASSERT

return 0;

}

 

/** - Check for pending message:

* - pending message, return 0

* - no pending message, start new transmission

*/

if ((node->TXRQx[regIndex] & bitIndex) != 0U) {

success = 0U;

}

else {

// Is interface register free?

if ((node->IF1STAT & 0x80U) == 0U) {

// IF1 is free

node->IF1CMD = 0xB7U; // Dir = write, access arbitration bits, control bits, data A and data B.

node->IF1ARB &= 0xE0000000U; // Keep the MsgVal,Xtd and Dir setting.

node->IF1ARB |= ((uint32)(msgBoxArbitVal & 0x7FFU) << 18U); // Copy passed value into the arbitration register.

node->IF1MCTL &= 0xFFFFFFF0U; // Keep everything except DLC.

node->IF1MCTL |= ((uint32)dlc & 0x0000000FU); // Copy DLC.

// Copy TX data

for (i = 0U; i < dlc; i++) {

node->IF1DATx[i] = *data;

data++;

}

// Copy TX data into message box

node->IF1NO = (uint8) messageBox;

success = 1U;

}

else {

// No interface register free, try again later.

success = 0U;

}

}

return success;

}

  • Hi Michael,

    Please use
    while ((node->IF1STAT & 0x80U) ==0x80U) { }

    to Wait instead of the statement you used:

    if ((node->IF1STAT & 0x80U) == 0U) {....}

    If the data transferring between IFx register and MSG RAM is in progress, your code in this {...} will be ignored.

    Regards,
    QJ
  • Hi QJ,

    Thank you for your reply. Unfortunately that don't solve my problem. The code after my if-statement is executed, since the CAN message is sent on the bus. The ID and DLC are correct. But the TX data content is missing.

    Generally I like to avoid underterministic loops, I prefer "run to completion" and if the interface register (in this case) is occupied I simply try again next kernel tick.

    There must be something else I am missing that makes the data go away.

    When I insert this code, the ID is not updated but the TX data works:

     

    node->IF1CMD = 0x87U;

    for (i = 0U; i < 8U; i++)

    {

    node->IF1DATx[i] = *data;

    data++;

    }

    node->IF1NO = (uint8) messageBox;

    But since I also want to update the ID (arbitration info) I tried:

    node->IF1CMD = 0xB7U; // Dir = write, access arbitration bits, control bits, data A and data B.

    node->IF1ARB &= 0xE0000000U; // Keep the MsgVal,Xtd and Dir setting.

    node->IF1ARB |= ((uint32)(msgBoxArbitVal & 0x7FFU) << 18U); // Copy passed value into the arbitration register.

    node->IF1MCTL &= 0xFFFFFFF0U; // Keep everything except DLC.

    node->IF1MCTL |= ((uint32)dlc & 0x0000000FU); // Copy DLC.

    // Copy TX data

    for (i = 0U; i < 8; i++) {

    node->IF1DATx[i] = *data;

    data++;

    }

    // Copy TX data into message box

    node->IF1NO = (uint8) messageBox;

     

    But then the TX data don't get on the CAN bus.

  • Hi again,

    This issue is now resolved. I missed that the "Dir" bit in the arbitration register was set to 0 since the last message to get initialized was a receive message.

    With the following code snippet, all works as expected:

    // IF1 is free
    node->IF1CMD = 0xB7U; // Dir = write, access arbitration bits, control bits, data A and data B.
    node->IF1ARB = 0xA0000000U | ((uint32)(msgBoxArbitVal & 0x7FFU) << 18U); // Copy passed value into the arbitration register. Set MsgVal and Dir.
    node->IF1MCTL &= 0x00000080U; // Keep EoB.
    node->IF1MCTL |= (0x00008100U | ((uint32)dlc & 0x0000000FU)); // Copy DLC and set NewDat and TxRqst.

    for (i = 0U; i < dlc; i++) {
    node->IF1DATx[i] = *(data + i); // Copy TX data
    }

    node->IF1NO = (uint8) messageBox; // Copy TX data into message box

    success = 1U;