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.

Using CAN on DRV8301-LS12-KIT

Other Parts Discussed in Thread: HALCOGEN

Hello, we are trying to add CAN communications to the supplied TMS570LS12 foc_encoder_speed solution. I generated a CAN example using HALCogen, and that runs fine on the kit, but when I bring that code into the foc_encoder_speed codeset, it does not work - all I get is frame timing errors on the other end. There does not seem to be any pin muxing that needs to be setup for the CAN, so I suspect a clock setup difference. Comparing the two sets of code, there are some differences, but nothing obvious affecting VCLKA1. Here is my CAN init:

    canREG1->CTL = (uint32)0x00000000U
                 | (uint32)0x00000000U
                 | (uint32)((uint32)0x00000005U  << 10U)
                 | (uint32)0x00020043U;

    canREG1->ES |= 0xFFFFFFFFU;

    canREG1->INTMUXx[0U] = 0
    canREG1->INTMUXx[1U] = 0;
   
    canREG1->ABOTR = (uint32)0U;

    while ((canREG1->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */

    canREG1->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF1ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)0x581U & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF1MCTL = 0x00001080U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
    canREG1->IF1CMD  = (uint8) 0xF8U;
    canREG1->IF1NO   = 1U;

    while ((canREG1->IF2STAT & 0x80U) ==0x80U)
    {
    } /* Wait */

    canREG1->IF2MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF2ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)0x600U & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF2MCTL = 0x00001080U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)8U;
    canREG1->IF2CMD  = (uint8) 0xF8U;
    canREG1->IF2NO   = 2U;

    while ((canREG1->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    canREG1->IF1CMD  = 0x87U;

    while ((canREG1->IF2STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    canREG1->IF2CMD = 0x17U;

     canREG1->BTR = (uint32)((uint32)0U << 16U) |
                   (uint32)((uint32)(3U - 1U) << 12U) |
                   (uint32)((uint32)((5U + 3U) - 1U) << 8U) |
                   (uint32)((uint32)(3U - 1U) << 6U) |
                   (uint32)14U;

   canREG1->TIOC =  (uint32)((uint32)1U  << 18U )
                   | (uint32)((uint32)0U  << 17U )
                   | (uint32)((uint32)0U  << 16U )               
                   | (uint32)((uint32)1U  << 3U ) 
                   | (uint32)((uint32)1U  << 2U )   
                   | (uint32)((uint32)1U << 1U );
                  
    canREG1->RIOC =  (uint32)((uint32)1U  << 18U )   
                   | (uint32)((uint32)0U  << 17U ) 
                   | (uint32)((uint32)0U  << 16U )  
                   | (uint32)((uint32)1U  << 3U ) 
                   | (uint32)((uint32)0U  << 2U )
                   | (uint32)((uint32)0U <<1U );       

    /** - Leave configuration and initialization mode  */
    canREG1->CTL &= ~(uint32)(0x00000041U);

Any suggestions on what clock setup changes I would need to make to get CAN up an running?

Thanks,

Chuck

  • Hi Chuck,
    The CAN bit timing is derived from VCLKA1. Can you please find out the VCLKA1 frequency you have? By default, the VCLKA1 is the same as VCLK. The VCLK is derived from the PLL clock. Please first find the PLL setting by looking at the PLLCTL1 and PLLCTL2 registers in the SYS module from your HalCoGen example. Then find out the PLLCTL1 and PLLCTL2 register settings from foc_encoder_speed. Are they the same? You will need to adjust the CAN bit timing according to the new VCLKA1.

    You can also set the SYSPC1 register in the SYS module to 0x1 to enable the ECLK to observe the internal clock. After you enable ECLK it will be by default divided by 8 from VCLK. You can find the ECLK frequency between your HalCoGen example vs. the foc_encoder_speed. If the CPU is halted in debug and you want to observe the ECLK, make sure you set bit23 ECPCOS in the ECPCNTL register in the SYS module. You can also change the ECLK frequency via the ECPDIV field in the same register.
  • Thanks Charles - that was immensely helpful. The difference turned out to be the value in PLLCTL1, leading to a multiplication factor of 120 in the DRV software vs. 135 in the HALCoGen CAN example. This resulted in a VCLKA1 of 80 Mhz for DRV vs. 90 MHz in the example. I adjusted the BTR value and CAN is now working with the DRV software. Thanks again!
  • Glad your problem is resolved.