AM2434: GTC timing not correct?

Part Number: AM2434
Other Parts Discussed in Thread: SYSCONFIG

Hello, we use the industrial comms SDK 11.00.00.13.

We also use the GTC to enable a time-measuring between cores. We just noticed when we compare the GTC-measured time with a time measured via two gpios we have like a 17% difference.
E.g. we measured 109 ms via two gpios set right after the start and end measurement of the GTC. The GTC measured 93117 us.

How we do everything:

/* the clock rate to calculate with */
static uint64_t clkRate = 0;
static bool initialized = false;

void implTimeMeasureInitialize()
{
    uint32_t baseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CSL_GTC0_GTC_CFG1_BASE);
    clkRate = HW_RD_REG32((baseAddr + CSL_GTC_CFG1_CNTFID0));
    /* initialization moved to bootloader, since mutliple cores calling this function will cause problems */
    initialized = true;
}

uint64_t implTimeMeasureMicros()
{
    if(initialized)
    {
        return (GTC_getCount64()/(clkRate/1000000));
    }
    else
    {
        return 0;
    }
}

in the bootloader:

uint64_t clkRate = 0;
    /* initialize GTC */
    uint32_t baseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CSL_GTC0_GTC_CFG1_BASE);
    clkRate = HW_RD_REG32((baseAddr + CSL_GTC_CFG1_CNTFID0));
    uint32_t value = 0;
    value = HW_RD_REG32(baseAddr);
    if( (clkRate == 0) || ((value & CSL_GTC_CFG1_CNTCR_EN_MASK) != CSL_GTC_CFG1_CNTCR_EN_MASK))
    {
        GTC_init();
        // just for debuging
        SOC_moduleGetClockFrequency(TISCI_DEV_GTC0, TISCI_DEV_GTC0_GTC_CLK, &clkRate);
    }
    else
    {
        // nothing
    }

measuring:

uint64_t firstVal = 0;
uint64_t secondVal = 0;
uint64_t resultVal = 0;
firstVal = implTimeMeasureMicros();
// set GPIO here
// stuff happens
secondVal = implTimeMeasureMicros();
// unset GPIO here
resultVal = secondVal - firstVal; // <-- this value differs from the scope-measured time of gpio set and unset by 17%

What do we do wrong here?

best regards
Felix Heil

  • Hi,

    Could you try using this method?

    Please check if GTC is available in the SysConfig GUI of your application, if yes, follow this method.
    RE: AM62P: GTC_init() locks up on M4F 

    If its not there, let me know, I can then suggest another way to measure time via GTC.

    Regards,

    Vaibhav

  • Hey Vaibhav,

    so it is available in SysCfg, but since to some general limitations of SysCfg (only one overall static driver configuration) we dropped using SysCfg and did write our own API for most of the sdk-driver configurations which works dynamically at runtime, depending on the used hardware, so we can use one firmware for multiple hardware-variants. 

    So we did everything manually.
    But of course I looked into SysCfg and how it would initialize the GTC. But all it does is calling GTC_init. And there is no more text at SysCfg explaining anything:

    Also for the GTC it was crucial that not multiple cores call the init, we once had problems with this: MCU-PLUS-SDK-AM243X: Usage of GTC - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    But looking at the link you provided it seems we do not much different here. We read the clock-rate from CSL_GTC_CFG1_CNTFID0. Should we instead read the clock rate from line 11 in the second code snippet, so by SOC_moduleGetClockFrequency(TISCI_DEV_GTC0, TISCI_DEV_GTC0_GTC_CLK, &clkRate); ? I used that only for debugging to check if the value is comparable to the ony from the GTC-register.

    Also the calculation is a bit different.... but I noticed I needed to use the value 1000000 to get it into microseconds. that may be wrong?

    Best regards

    Felix

  • Hi Felix,

    I would suggest referring the file C:\ti\mcu_plus_sdk_am64x_11_02_00_24\source\drivers\gtc\v0\gtc.c, it will be the same path except for AM243 MCU+ SDK.

    I am checking the init flow for you and will update in sometime.

    Regards,

    Vaibhav

  • Hi Felix,

    I would like you to avoid doing integer math truncation before delta computation. I would like you to compute the delta first, sort of (EndTime - StartTime) and then this (value * 1000000)/clkRate will give you precise time in microseconds.

    Let me know if this fixes the 17% deviation you are seeing.

    Regards,

    Vaibhav

  • hey Vaibhav, 

    a small update: the calculation is not the problem. 
    We noticed in the bootloader the clock for MAIN_PLL2_HSDIV5_CLKOUT is 225 MHz. We do write this value then in the GTC register and use it in the application. But in the application we notice that MAIN_PLL2_HSDIV5_CLKOUT is set to 200 MHz. 
    If we do hard-code to use 200 MHz for the calculation it works like perfectly exact. But we want to make it dynamic so it adapts to the clock-settings correctly. 
    So somewhere in between some instance modifiy that value but we do not know or see where currently. We are investigating this. 
    Do have maybe an idea what could modify this value? Is the RBL involved in this? or maybe the SysFw?

    Best regards

    Felix

  • Hey Vaibhav, 
    so we investigated further. We think that the problem is the divisor, which is 9 or 8, depending on which time we check it:
    200 MHz:

    225 MHz:


    I also saw that part of the sdk-documentation:
    AM243x MCU+ SDK: Getting SDK 10.00 PLL Updates on older SDKs
    unfortunately it's not explained what exactly changed or how the flow with those PLLs work. We also tried to check that in the TRM, so how the RBL/Initialization works, but it only says that the ROM Code sets some PLLs and nothing more:


    The boot process also mentions the DMSC sets some PLLs and later the R5F sets those:

    But where does the R5F configure the MAIN Domain PLLs? we couldn't find this part. Is it the HFCS0, which is used for the clock of the sdk?
    Is there somewhere more information?
    Could it also be that the PRU_ICSSG1, which also uses the PLL2, configures something when loaded?
    We really think it's the divisor. But no clue who changes it at which point. We are not doing something manually here.

    Also we tried to use SOC_moduleGetClockFrequency to get the correct frequency in our application, so after the bootloader. But we do this pretty early before any system initialization (because we want to use exactly this counter for measurement) and somehow exactly at this point our application freezes. If we remove that call it works fine. 

    Best regards
    Felix

  • Hi Felix,

    We noticed in the bootloader the clock for MAIN_PLL2_HSDIV5_CLKOUT is 225 MHz. We do write this value then in the GTC register and use it in the application. But in the application we notice that MAIN_PLL2_HSDIV5_CLKOUT is set to 200 MHz.

    I would like to reproduce this. Could you tell me if I run by the AM243/am64x TI EVM and do a SoC Initialization using Default SBL OSPI, then in the bootloader I am expected to see 225 MHz and at an R5 Application, I expect to see 200 MHz.

    Please confirm the above, also let me know if you are using SOC_moduleGetClockFrequency to get the clock frequency?

    Looking forward to your response.

    Regards,

    Vaibhav

  • Hey Vaibhav, 
    We are not using the Default SBL OSPI but our own bootloader. Also since we do not use SysCfg the initialization uses different functions, but we kept it pretty the same as SysCfg would do under the hood. I'm always comparing our driver-api with what SysCfg does after an SDK-update and it looks the same. 
    So I would assume - except our special firmware slot-handling - it works nearly the same as the default SBL OSPI. 
    We use the same bootloader also for the evm. 

    But another colleague also worked on this topic and he said, that it seems that when loading the PRU-code, there is another change of the frequency done hidden somewhere. We are investigating this, but this seems to be the problem. So it may only occur if you also load any icss-fwhal related code into the PRU. This seems to be the case for all supported pru-firmwares for all protocols: EtherCAT, Profinet and Ethernet/IP. 

    Our way is to set the FID-register of the GTC inside the Bootloader with the aquired frequency via SOC_moduleGetClockFrequency but in our application we just read that register back. And here it starts to differ at some point. which urrently seems to be exactly after loading the PRU-code. 

    Best regards

    Felix

  • Hi Felix,

    I understood your concern.

    I am checking on with another expert if they have some inputs related to PRU-code.

    Regards,

    Vaibhav