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.

F28377S DCan mailbox



Hi,

I'm trying to wrap my head around the DCAN module of F28377S compared to the ECAN module of F28035. I'm trying to see the best way to register a message object for transmission but access it at runtime to change the associated CAN ID and CAN DATA. Since it's for TX, there's no need for filtering. I'd just wait for transmission interrupt, fetch data ready to be sent and fill in ID + Data. From the driverlib API, it seems the only available access to configure an object and send it is to use CANMessageSet. This seems a bit overweight to set an ID and some data. Should I just write my own wrapper or is there a reason why this is done like this?

CANDataRegWrite could be used to fill in data but looking at the comments, I don't think that's a good idea...

Any input will be appreciated!

Regards,

  • mosin,

    as you have already noticed, DCAN is very different to ECAN. Probably the biggest difference is the way of interaction between the MCU and the CAN-Communication controller. Let me just summarize, what I feel as the biggest difference.

    For ECAN it was pretty simple to access CAN registers from the MCU-side: just read/write to the correct register address. However, this technique could be dangerous, if the developer does not care about potential access conflicts between the CAN-Communication Controller and the MCU.

    For DCAN, the situation is different. Here, all accesses from MCU to CAN - registers are performed via interface registers IFx. A hardware logic takes care that potential collisions between CAN-CC and the new data/command in IFx are resolved.

    Function CANMessageSet is using this IF-Register-approach, whereas function CANDataRegWrite is a pure dump of values directly into CAN-registers. Of course you could try to use CANDataRegWrite at the beginning, but I'd highly recommend not to use it in a running system, because of the missing interface technique.

    Regards
  • Thanks for the info Frank.

    Is there a reason why there are no structure defined to access the registers like some of the other peripherals or just like all registers on F28035? I mean, it's not that I can't do it, but it's an error prone process that will take time... It is a lot more convenient than using HW_REG().

    Anyway, I'm still wondering if it's recommended to add utils around the IF register to be able to change ID and DATA of a message object. If I check the busy bit, I don't see why it would be bad...

    Regards,

  • Hi mosin,

    structure/union:
    especially in automotive environments or in safety related applications, where the rules of MISRA-C must be followed, the usage of union's is not allowed. This may be one reason why TI moved to a more Hardware Abstraction Layer based support of register initialization, such as HW_REG() for the latest devices.

    IFx-Register use:
    Of course you are free to program whatever you like to have as support functions. If you check the busy-bit and it says "not -busy" you could start a direct access to CAN-registers. However, what happens if between checking the busy-bit and your next code the CAN-CC gets suddenly active? For example, it could receive a message just at this very moment. Of course this will not happen every time but there is a small probability that it will happen one day. Then you are trapped. So my recommendation is to always use the interface register approach with DCAN.

    Regards
  • Hi Frank,

    I understand your point. That's what I meant by adding my support functions but going through IF registers. Let's see if I'm getting it right :

    // Write out the registers to program the message object.
    HWREGH(ui32Base + CAN_O_IF1CMD+2) = ui32CmdMaskReg >> 16;
    HWREG(ui32Base + CAN_O_IF1MSK) = ui32MaskReg;
    HWREG(ui32Base + CAN_O_IF1ARB) = ui32ArbReg;
    HWREG(ui32Base + CAN_O_IF1MCTL) = ui32MsgCtrl;
    
    // Transfer the message object to the message object specifiec by ui32ObjID.
    HWREGH(ui32Base + CAN_O_IF1CMD) = ui32ObjID & CAN_IF1CMD_MSG_NUM_M;

    The four registers used and wrote in the four first lines can be changed at all time. The last line, where it writes the object ID number in the IF1CMD register will trigger the transfer from IF register to Message RAM.

    So, let's say during initialization, I setup a message object with fixed configuration : DIR = TX, Interrupt Enabled, Extended ID is used, no filtering. I write the registers accordingly and write the object ID in the IF1CMD to configure the RAM object. At runtime, when TX is done, I want to change message ID and DATA. I setup the IF1ARB register with the ID and I set the IF1DATA register with my data. In the end, I just write the object number in the IF1CMD register.

    Hum.. I'll probably have to rewrite all desired settings though... Maybe I'll have to get my hands dirty a little before I grasp all concepts around that.

    Anyway, thanks for your comments Frank!