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.

TDA2x: How do I use a DCAN module on Linux?

Hi,

I'm using a TDA2x custom board. (Vision SDK 3.07)

I checked that there is a DCAN module in VisionSDK to use CAN.

And I proceeded with the following work to use the DCAN module in Linux mode. (DCAN will run on the IPU core.)

1) Change to DCAN_INCLUDE=YES
2) Change IPU_PRIMARY_CORE from IPU2 to IPU1_0
3) Change System_dcanInit() function call from IPU1_1 to IPU1_0

Strangely, DCAN SRC_FILE.MK shows "SRCS_ipu1_0 += $ (DCAN_SRCS)"
But, System_dcanInit() is called from IPU1_1. (links_fw\src\rtos\links_ipu\system\system_ipu1_1.c)

4) Build apps

Build's ok... 
But run the app IPU1 falls into an infinite loop.

I added some debug message and Problems arise with the function "PlatformDcanMessageRamInit(0)"
Unable to escape from while() inside function "PlatformDcanMessageRamInit(0).

So I also checked the register value.

"ti_components/drivers/pdk_01_10_03_07/packages/ti/drv/stw_lld/platform/src/tda2xx/platform_tda2xx.c" PlatformDcanMessageRamInit func show following line.

==========================================================================================================================

HW_WR_FIELD32((uint32_t) SOC_CTRL_MODULE_CORE_CORE_REGISTERS_BASE + CTRL_CORE_CONTROL_IO_2,
              CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_START,
              CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_START_CLEAR);
            /* Set the start bit so that pulse is generated
             * when run second time.
             * CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_START_SET
             * causes Init pulse to happen and SW not needed to write */
// 0001 0000 0001
HW_WR_FIELD32((uint32_t) SOC_CTRL_MODULE_CORE_CORE_REGISTERS_BASE + CTRL_CORE_CONTROL_IO_2,
              CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_START,
              CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_START_SET);
// 0001 0000 0001
status = ((uint32_t) 0x1 << CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_DONE_SHIFT) & CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_DONE_MASK;
// 0001 0000 0001
// status != (0001 0000 0001 & 0001 0000 1001)
while (status != ((status & HW_RD_REG32(SOC_CTRL_MODULE_CORE_CORE_REGISTERS_BASE +CTRL_CORE_CONTROL_IO_2))))
{
    ;
}

            /* Write one to clear done bit */
HW_WR_FIELD32((uint32_t) SOC_CTRL_MODULE_CORE_CORE_REGISTERS_BASE + CTRL_CORE_CONTROL_IO_2,
                CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_DONE,
                CTRL_CORE_CONTROL_IO_2_DCAN1_RAMINIT_DONE_CLEAR);


==========================================================================================================================

If I'm right, isn't it right to get out of while()?

I don't know.

Please help me to use the DCAN module on Linux.

Best regards,
Lee.