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.

AM335x - DCANCommandRegSet function

Hi,

The above function does the following:

    /* Wait in loop until busy bit is cleared */
    while(DCANIFBusyStatusGet(baseAdd, regNum));

    /* Clear the DCAN_IFCMD register fields */
    HWREG(baseAdd + DCAN_IFCMD(regNum)) &= ~(DCAN_IFCMD_DMAACTIVE |
                                             DCAN_IFCMD_DATAA |
                                             DCAN_IFCMD_DATAB |
                                             DCAN_IFCMD_TXRQST_NEWDAT |
                                             DCAN_IFCMD_CLRINTPND |
                                             DCAN_IFCMD_CONTROL |
                                             DCAN_IFCMD_ARB |
                                             DCAN_IFCMD_MASK |
                                             DCAN_IFCMD_MESSAGENUMBER |
                                             DCAN_IFCMD_WR_RD);

    /* Wait in loop until busy bit is cleared */
    while(DCANIFBusyStatusGet(baseAdd, regNum));

    /* Set the DCAN_IFCMD register fields represented by cmdFlags */
    HWREG(baseAdd + DCAN_IFCMD(regNum)) |= ((cmdFlags &
                                           (DCAN_IFCMD_DMAACTIVE |
                                            DCAN_IFCMD_DATAA |
                                            DCAN_IFCMD_DATAB |
                                            DCAN_IFCMD_TXRQST_NEWDAT |
                                            DCAN_IFCMD_CLRINTPND |
                                            DCAN_IFCMD_CONTROL |
                                            DCAN_IFCMD_ARB |
                                            DCAN_IFCMD_MASK |
                                            DCAN_IFCMD_WR_RD)) |
                                            (objNum & DCAN_IFCMD_MESSAGENUMBER));

Which in pseudocode can be described as:

    Wait_For_Busy_Bit();
    Clear_ALL_IF_Register_Fields();
    Wait_For_Busy_Bit();
    Set_ALL_IF_Register_Fields(desiredValues);

According to TRF documentation it is safe to write ANYTHING to all the other bits of this register (as the values are ignored). Then why is it required to clear the fields first? Why can't it be just:

    /* Wait in loop until busy bit is cleared */
    while(DCANIFBusyStatusGet(baseAdd, regNum));

    /* Set the DCAN_IFCMD register fields represented by cmdFlags */
    HWREG(baseAdd + DCAN_IFCMD(regNum)) = ((cmdFlags &
                                           (DCAN_IFCMD_DMAACTIVE |
                                            DCAN_IFCMD_DATAA |
                                            DCAN_IFCMD_DATAB |
                                            DCAN_IFCMD_TXRQST_NEWDAT |
                                            DCAN_IFCMD_CLRINTPND |
                                            DCAN_IFCMD_CONTROL |
                                            DCAN_IFCMD_ARB |
                                            DCAN_IFCMD_MASK |
                                            DCAN_IFCMD_WR_RD)) |
                                            (objNum & DCAN_IFCMD_MESSAGENUMBER));

Which in a little better for performance...

Best,
Vasili