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.

How to enable D_CAN1?

Other Parts Discussed in Thread: AM3874

I managed make the D_CAN0 work s just fine. But I'm having trouble making D_CAN1 work. So far I have add resources for d_can1 in devices.c and called ti814x_d_can_init() for instance1. The loopback test works fine on dcan1, however when I connect the dcan port to a CAN device, it didn't work. (I did moved the jumpers to5-6 and 7-8 on CAN_SEL).

Has anyone ever made dcan1 work? Any comment/suggestion would be appreciated. 

Jiewen

  • Hi Jiewen,

    On DM8148 D_CAN1 is not working with some hardware limitations, will be added to Erratum.

    Regards

    AnilKumar

    Please mark this Forum post as answered via the Verify Answer button below if it helps answer your question.  Thanks!

  • Hi AnilKumar,

    Thank you for your information. Is there a plan to make it work? We have a project is going to need both CAN modules on DM814x. 

    Regards,

    Jiewen

  • Hi AnilKumar,

    I'd like to know more on the nature of this limitation and whether it is just with the Mistral DM8148 EVM or the processor itself. 

    Thanks.

    Jiewen



  • I would also like to know the answer to this question. Our design requires both DCAN channels - this is a major reason why we picked Centaurus.

    Thanks,

    Kevin

  • Hi Kevin,

    TI814x have 2 DCAN modules, hardware have the problem to brought out D_CAN1.

    Even though we fix the erratam, TI814X Catalog daughter card have only one transceiver so at a time we can use single D_CAN instance.

    Thanks

    AnilKumar

  • Hi,

    What is a status of this issue? I cannot find anything in Errata, but the document is quite old. Is DCAN1 available on 2nd silicon revision? If not, is there any workaround? I would like to bring DCAN1 up on custom AM3874 board.

    Greg

  • We have a custom DM8148 board with two DCAN transceivers. With some kernel modifications, both DCAN0 and DCAN1 are working.

    Regards,

    Jiewen

     

  • Hi Jiewen,

    That is great news! Could you, please, share the sourcecode for this board's kernel (or only files related to DCAN1 port)? Or at least drive me what should I change? I am assuming, I need to add new device to devices.c file, setup clock source and enable EDMA channel for DCAN1. It looks like quite a big task, so your help would be very appreciated.

    Thanks,

    Greg

  • Hi,

    I made changes in devices.c file and added second instance of DCAN port. I am trying now without DMA support. I can see both ports under ifconfig, I am able to configure and start/stop ports using canconfig tool without any problems, but I cannot send any packets on any of them (candump does not show anything whenever I try to send something to the device). If I remove initialization of dcan1, dcan0 port works fine. Could anyone help with this issue?

    Thanks,

    Greg

  • Sorry for responding  late. 

    I remember, I did reset on both device at once. I modified #define TI814X_D_CAN_RAMINIT_START(n) as (0x03<<n), and called d_can_hw_raminit(0) once in ti814x_d_can_init().

    Hope this helps.

    Jiewen

     

  • I found the problem (it was bug in my configuration) and I was able to enable both DCAN ports.

  • Hi,

    I am returning, because it may help somebody on this topic and I am also looking for some explanation. I made the DCAN ports working, but I observe strange behaviour. I am not able to make them running after power sequence or POR reset (e. g. cansequence stalls). However, if I do warm reset (using processor's RESET pin), both ports work very well.

    I tried to solve this issue. First I thought that d_can_hw_raminit function in devices.c has a bug, because it does not wait until raminit is finished (RAMINIT_DONE bits have to be set, according to the manual). But these never happens! (Is it the bug that TI engineer mentioned here? Or another one?).

    So I left it and started to search deeply in the driver. After some tries I found out that adding very small delay (1us or actually any other) on the beginning of d_can_init function solves my issue. Both DCAN ports started to work properly, even after power sequence. I tried to find out the place after which delay is required, and it took me up to d_can_open function. If I do delay just before calling this function, fix does not work, but if I do that just after entrance to this function, it started to work. The only explanation I can imagine is that call to this function (from kernel/net/core/dev.c) actually switches the context from user to kernel space.

    Does anybody know why is that? Why it can fix problem?

  • hello,i have same question with you,but i used  D_CAN0.I have add resource for D_CAN0  and  called d_can_init(0).it have can0 device when i use ifconfig command and the loopback test work fine too,however it has no wave from the export pin. can you share you code,my email is 453404825@qq.com?

  • Hi,

    Actually, this fix worked for a while. As our kernel is still after development, we broke this again. The only explanation is there is a race condition somewhere in the driver code. Thus, possibly most of users do not suffer because SDK code is lucky enough. I managed to make it working again for some time by setting D_CAN_CTL_ABO bit during DCAN initialization, but again, after changes in different places of kernel, it stopped working again. My last try at the moment is to add small delay (100 us) in d_can_platform.c, just after clocks are being enabled:

        priv->ick = clk_get(&pdev->dev, pdata->ick_name);
        if (IS_ERR(priv->ick)) {
            dev_err(&pdev->dev, "%s is not found\n", pdata->ick_name);
            ret = -ENODEV;
            goto exit_free_fck;
        }
        clk_enable(priv->ick);

        udelay(100);

        /* get the platform data */
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!mem) {
            ret = -ENODEV;
            dev_err(&pdev->dev, "No mem resource\n");
            goto exit_free_clks;
        }

    This works for now in my code, but again, I treat it as a blind shot until somebody from TI confirms that this is a real cause of the issue. TI guys, is there anyone familiar enough with DCAN?

  • Hi,

    For enyone who may have similar issue: I have found the root cause. Actually, there is a race condition in d_can.c file. The interrupt are enabled and then netif_start_queue is done. Since after power-up sequence the status of can bus is not reliable, sometimes interrupt about bus state change before working thread is actually started. This causing that they are not properly served and ending up in driver hang (previous interrupt condition was not yet cleared, so there is no new interrupt reports). The fix is simply to start kernel thread _before_ initialisation is done and interrupts are enabled. Patch in the attachment.

    Regrads,

    Greg

    2068.patch.diff
    --- drivers/net/can/d_can/d_can.c.orig	2013-10-03 16:16:47.285421060 +0100
    +++ drivers/net/can/d_can/d_can.c	2013-10-03 15:37:23.894951077 +0100
    @@ -1262,12 +1262,12 @@ static int d_can_open(struct net_device
     		goto exit_free_irq;
     	}
     
    -	/* start the d_can controller */
    -	d_can_start(ndev);
    -
         napi_enable(&priv->napi);
         netif_start_queue(ndev);
     
    +	/* start the d_can controller */
    +	d_can_start(ndev);
    +
     	return 0;
     exit_free_irq:
     	free_irq(ndev->irq, ndev);