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.

DMTimer using Starterware Bootloader - 1Ghz vs 720Mhz

Other Parts Discussed in Thread: AM3358

Background:

I'm using the bare metal starterware as an example for my custom board using the AM3358 with an external 24Mhz crystal on OSC0. 

I'm using a 1ms timer (DMTimer 4and an adjustable ms timer (DMTimer 6).

The RTC 32kHz external crystal is not populated on my board, so I have the timer set to use the OSC0 24Mhz clock.

For example with my 1ms timer, I have it set to auto-reload with a value of 0xFFFFA23F. 

When the booloader runs, the BootMaxOppGet function detects deviceVersion "DEVICE_VERSION_2_1" and oppSupport "EFUSE_OPPNT_1000" (1Ghz).

Problem:

When my Bootloader runs, the processor gets set to 1Ghz and my timers are not accurate. (they are too fast)

Possible Solution:

If I force the bootloader support to be "EFUSE_OPP120_720" (720Mhz), all my timers are fine.

However, I'd like to run the processor at 1Ghz.

How can I calculate the correct timer values for 1Ghz when the calculations should be based in both cases on the 24Mhz clock according to the manual? 

  • Moving this to the Starterware forum.
  • J Burke,

    The change in MPU frequency is completely unrelated to the timers. They work off of different PLLs. The Peripheral PLL (which clocks the timers) should remain in the same configuration regardless of whether the MPU PLL is 720MHz or 1GHz.

    What are the values of your peripheral PLL registers? Are they the same in both cases?

    Regards,
    Lali
  • For the timers, I am selecting to use the 24Mhz system clock (CLK_M_OSC) and not the PER PLL generated 32.768KHz clock (CLK_32KHZ).

    Doesn't the peripheral PLL only generate the 32KHz Clock and not the 24MHz?

    The code I have to initialize the Peripheral PLL is the same in both cases. (The default "PerPLLInit" function from the Starterware bootloader example)

    The MPU PLL is the only code that is being changed. Is the "System clock" effected by changing from 720Mhz to 1Ghz?

  • J Burke,

    Which release are you using? I wanted to reference the BL code. Thanks.

    Lali

  • SW Version 2.00.01.01

  • What is the value of the CLKSEL register? could you check to see that  you are indeed using CLK_M_OSC?

    If you take a look at pg 1150 of the TRM http://www.ti.com/lit/ug/spruh73m/spruh73m.pdf (fig 8-17), CLK_M_OSC is a direct output of the system clock oscillator, so the timer freq won't be affected by the MPU PLL changes. 

    Also, how are you measuring the accuracy of the timers?

    Lali

  • Yes, I am definitely using the CLK_M_OSC. The timers are very accurate and calculated based on 24Mhz clock. They work perfectly when running at 720Mhz.

    I don't have the 32Khz external crystal populated on my board anyway, so I don't think I can use that.

    Here's my setup code for the timers:

    /* Clear CLKSEL field of CM_DPLL_CLKSEL_TIMER4_CLK register. */
    HWREG(SOC_CM_DPLL_REGS + CM_DPLL_CLKSEL_TIMER4_CLK) &=
    ~(CM_DPLL_CLKSEL_TIMER4_CLK_CLKSEL);

    /* Writing to the CLKSEL field of CM_DPLL_CLKSEL_TIMER4_CLK register. */
    HWREG(SOC_CM_DPLL_REGS + CM_DPLL_CLKSEL_TIMER4_CLK) |=
    CM_DPLL_CLKSEL_TIMER4_CLK_CLKSEL_CLK_M_OSC; //24Mhz system clock

    /* Waiting for the CLKSEL field to reflect the written value. */
    while((HWREG(SOC_CM_DPLL_REGS + CM_DPLL_CLKSEL_TIMER4_CLK) &
    CM_DPLL_CLKSEL_TIMER4_CLK_CLKSEL) !=
    CM_DPLL_CLKSEL_TIMER4_CLK_CLKSEL_CLK_M_OSC);

    /* Writing to MODULEMODE field of CM_PER_TIMER4_CLKCTRL register. */
    HWREG(SOC_CM_PER_REGS + CM_PER_TIMER4_CLKCTRL) |=
    CM_PER_TIMER4_CLKCTRL_MODULEMODE_ENABLE;

    /* Waiting for the MODULEMODE field to reflect the written value. */
    while((HWREG(SOC_CM_PER_REGS + CM_PER_TIMER4_CLKCTRL) &
    CM_PER_TIMER4_CLKCTRL_MODULEMODE) != CM_PER_TIMER4_CLKCTRL_MODULEMODE_ENABLE);

    /*
    ** Waiting for the CLKACTIVITY_TIMER4_GCLK field of CM_PER_L4LS_CLKSTCTRL
    ** register to be set.
    */
    while(!(HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKSTCTRL) &
    (CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK |
    CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_TIMER4_GCLK)));

  • In response to your other question about how I am measuring accuracy:

    I have an external RTC IC (not the AM335x RTC) that I am using to compare the values. On my LCD I print both the RTC seconds and the number of seconds calculated using my ms timer.
  • While the above reply is being digested, just a heads-up that there is a newer version of Starterware (v 2.1.1.1) in the Processor SDK RTOS release for AM335x. Not that it may make a difference to your query, but just for FYI.

    Lali

  • Thanks, but we need a bare metal solution. Maybe it will lend some clues though -- I'll download it too.
  • There is a Starterware package in that installation that has bare metal examples.

    Lali

  • J Burke,

    How much faster is it running with the 1GHz (when compared to the external RTC)?
    You are using the AM335x Starter Kit evm?

    Lali
  • J Burke,

    I have some questions to better understand your setup:

    - Are you using the AM335x Starter Kit?

    - How did you get the reload value of 0xFFFFA23F?

    - Assuming you are using DMtimer4, what is the value of CM_DPLL_CLKSEL_TIMER4_CLK register location 0x44E00510?

    - Are you looking for a 1 second timing interval?

    If you use the interval calculation equation on page 4340 of the AM335x TRM:

    Timer Interval = (FFFF FFFFh – TLDR + 1) × timer Clock period × Clock Divider (PS)

    Where:

    Timer Clock period = 1/ timer Clock frequency

    PS = 2(PTV + 1). Since PRE is 0, we can use PS =1 according to Table 20-7.

    Timer value = (0xFFFFFFFF - 0xFFFFA23F +1) * (1/24000000) * 1

    So, based on this and the reload value that you used, you would get a 1ms interval. Did you use 24MHz and not 24KHz in the equation?

    Hoping to get some clarity on your problem in order to better assist.

    Lali

  • I'll try to reply in more detail when I get in front of a computer.

  • - Are you using the AM335x Starter Kit?

    No, as stated in my original post, I am using a custom board. 

    This board design was based partially on the starter kit as a reference.

    - How did you get the reload value of 0xFFFFA23F?

    Using the equation you mention from the manual for a 1ms timer.

    In my original post I mention "For example with my 1ms timer, I have it set to auto-reload with a value of 0xFFFFA23F"

    - Assuming you are using DMtimer4, what is the value of CM_DPLL_CLKSEL_TIMER4_CLK register location 0x44E00510?

    I'm not in front of the board at the moment, but if you're getting at what clock source I'm using, it's most definitely the 24Mhz OSC. The other option of the RTC is not possible and causes the chip to completely lock up because I do not have the external 32kHz populated on my board.

    - Are you looking for a 1 second timing interval?

    No, 1ms. I'm increment a 1 second tick using this timer only so I can compare to my external RTC for accuracy check.

    I'm also using another timer that is configurable my the user (calculations on refill value done at runtime) -- but that's not important right now.

    For some quick clarity on my problem:

    Board works great when running with bootloader set to 720Mhz. All timers (1ms, 33ms, etc) 100% accurate. 

    Bootloader set to 1Ghz, all timers run too fast. (seems almost double number of timer interrupts)

    This makes no sense based on the manual saying 24Mhz unaffected by this change. Any ideas?

  • J. Burke,

    Thanks for the responses.

    I spoke a some colleagues here and they mentioned an errata on the AM335x Starter kit. Its advisory 2.2.2 in http://processors.wiki.ti.com/images/d/d9/AM335x_StarterKit_rev1_2_errata.pdf

    VDDS_OSC should be connected to DGND.

    Did you take this into consideration during the board design?

    Lali

  • Thank you for your suggestion. I did look up this capacitor and VDDS_OCS is decoupled to DGND. (not decoupled to GND_OSC0)

    Is there something else I should look at? 

  • I was looking at the defines used for the Core PLL Init function. I noticed that in bl_platform.h the there's a comment relating to these defines:

    /*
    **Setting the CORE PLL values at OPP100:
    ** OSCIN = 24MHz, Fdpll = 2GHz
    ** HSDM4 = 200MHz, HSDM5 = 250MHz
    ** HSDM6 = 500MHz
    */
    #define COREPLL_M 1000
    #define COREPLL_N 23
    #define COREPLL_HSD_M4 10
    #define COREPLL_HSD_M5 8
    #define COREPLL_HSD_M6 4

    Does this mean these values should be changed when running running at OPP NITRO 1000Mhz - 1.325v? Rather than something like OPP100 600Mhz - 1.1v?
  • The CORE PLL stays the same. What's probably not evident in the comment is that it refers to the CORE OPP, which stays at OPP100 regardless of the MPU frequency. When you change the MPU, you are changing the MPU OPP from OPP100 to OPP NITRO.

    Back on the grounding question, there is possibly another related errata 1.0.30 in the AM335x silicon errata "OSC0 and OSC1 Noise Immunity Improved When Crystal Circuit is Connected Directly to PCB Digital Ground". Ensure that you have VSS_OSC and VSS_RTC connected to DGND to avoid noise affecting the crystal circuits.

    Regards,
    James
  • VSS_RTC has always been connected to DGND in our design.

    We did just try connecting GND_OSC0 to the DGND as well.

    No change in behavior of the timers.
  • Thanks for all your support through e-mail as well. 

    It appears that the answer is to be sure to disable the timer before clearing the overflow interrupt. 

    For starterware:

    /* Stop the timer */
    DMTimerDisable(SOC_DMTIMER_6_REGS);

    /* Clear the status of the interrupt flags */
    DMTimerIntStatusClear(SOC_DMTIMER_6_REGS, DMTIMER_INT_OVF_EN_FLAG);

    /* Start the timer */
    DMTimerEnable(SOC_DMTIMER_6_REGS);