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.

About AM335x DM Timer

Guru 15510 points
Other Parts Discussed in Thread: AM3352, AM3356, ADS1158

Hi,

We are having a problem with AM3352.

We are using Linux date command to capture time.
It sometimes capture future time(131072 sec) suddenly.

We search about the Linux date command and foud that it read the value from
DM Timer 1 TCRR register of AM335x.
This problem occures when Timer1 is in posted-mode.

The following is my question:
It seems that this problem is due to TCRR register value.
Is there any problem with  DM Timer 1 TCRR register?
For example, if when CPU load is large and capturing the time value frequently,
TCRR register's value will be decreased a few hundreds of count from the current TCRR value automatically
which is not usual.

best regards,
g.f.

  • This issue has been discussed on multiple forums (beagle and L-O list) and patch fixing this has already been merged.

    Link to Patch (v3.2) - http://arago-project.org/git/projects/?p=linux-am33x.git;a=commit;h=506c079b8421c901cbf81ebd4c8c27f1315dc769

    Reference to discussion threads - http://osdir.com/ml/beagleboard/2013-05/msg00119.html

    Thanks,

    Vaibhav

  • Hi Vaibhav,

    Thank you the response.

    May I ask a few  more question?
    When we setup clock source for DM timer from CLKSEL_TIMER1MS_CLK_Register as follow,
    the issue won't occur either posted mode or non-poseted mode.

    CLKSEL_TIMER1MS_CLK Register = SEL2 : Select CLK_32KHz clock

    The issue occurs when the clock source was setup to SEL5(external xtal)
    and when posted-mode is used.

    Is this issue related to posted mode and input clock source of Timer?

    This issue isn't reflected in the AM335x errata sheet.
    When will it be reflected in the sheet?

    best regards,
    g.f.

  • Hi Vaibhav,

    Is there any information for my question?
    Please give me an advise.

    best regards,
    g.f.

  • Hi all,

    I'm working on a custom board and this problem always happens. Few minutes after system boots, its date starts to jump forward 2^17 seconds.
    The "hwclock" command is ok, but "date"  command is not.
    I applied the kernel patch, but no difference.
    Help!
    Thank's
    Andre
  • The following advisory will be added to the AM335x Silicon Errata in the next few weeks.  Please read this and apply the workaround to see if this resolves your issue with the DMTIMER.

    Regards,
    Paul

    ****************************************************

    AM335x Silicon Errata (SPRZ360)

    Advisory 1.0.TBD          OSC0 and OSC1: Noise Immunity is improved when Crystal Circuit is connected directly to PCB Digital Ground

    Revision(s) Affected:     2.1, 2.0, 1.0

    Details:                         AM335x Data Sheet revisions F and earlier has specified OSC0 crystal circuit grounds only be connected to VSS_OSC in both ZCE and ZCZ packages, and OSC1 crystal circuit grounds only be connected to VSS_RTC in the ZCZ package.  The VSS_OSC and VSS_RTC terminals are connected to the VSS terminals inside AM335x which connects the crystal circuit to the PCB digital ground, but this ground connection is a higher impedance connection than a direct connection to the PCB digital ground.

    The higher impedance connection through AM335x to the PCB digital ground makes it easier for electrical noise to couple into the crystal circuit.  If the noise is large enough, it is possible the oscillator output may produce clock glitches to various internal logic circuits.  These clock glitches may cause unexpected behavior.

    Workaround:                 Connect the VSS_OSC and VSS_RTC terminals and respective crystal circuit component grounds directly to the nearest PCB digital ground, making it harder for noise to couple into the crystal circuit.

  • Thank's Paul!

    I removed the crystal and clock worked well! But hwclock doesn't moves anymore...

    I don't know why my circuit would have so much noise... I can't see an noise at oscilloscope and I copied schematics and layout from Bealgebone...

    Here is a picture from my layout:

    Y3 is the crystal.

    Other question: why can't it be fixed by software?

    Thank's

    Andre

  • I did not understand your comment "I removed the crystal and clock worked well! But hwclock doesn't moves anymore...".  Why did you remove the crystal.  The workaround only required you to add a short wire from each of the VSS_OSC and VSS_RTC net to the nearest PCB digital ground.  You were not expected to disconnect anything.

    Some people have found changing the DMTIMER clock source from the OSC1 (32.768KHz) reference clock source to the OSC0 (24MHz) reference clock source as improved the issue.  This occurs because it is easier to couple noise into the 32.768KHz crystal circuit than the 24MHz crystal circuit for a couple of reasons.

    The first reason is related to the signal changing very slowly.  Since the 32.768KHz signal slowly transitions through switching threshold of the AM335x input buffer there is a higher probability that a noise event will occur as the signal transitions though the switching threshold.  If the noise coupled into the crystal circuit is large enough it can cause the signal to cross the switching threshold multiple times as the signal slowly transitions though the switching threshold.   If this occurs, OSC1 may generate a glitch on the internal clock.

    Another reason is related to the resonate impedance of a 32.768KHz crystal circuit which can be several thousand ohms where the resonate impedance of a 24MHz crystal circuit is less than 50 ohms.   It is easier for noise to couple into the higher impedance 32.768KHZ circuit than the 24MHz circuit.  In most of these cases, customers have changed the DMTIMER1 clock source to the OSC0 (24MHz) reference clcok and resolved their problem.  Connecting the 32.768KHz crystal circuit directly to the PCB digital ground may have resolved their issue, but they did not want to change their PCB design.  It is important to note, the software solution is only valid when the OSC1 (32.768 KHz) reference clock is not being used to source other IP modules (like RTC).

    As mentioned in the Advisory, noise coupling is system dependent   In your system the noise may be high enough to also couple into the 24MHz crystal circuit.  If so, you will not be able to resolve the issue by just changing the clock source to the DMTIMER.

    Regards,
    Paul

  • Thank's!

    I removed the crystal just for testing. hwclock is stopped, but system date is ok. I will be more careful with ground in the next PCB layout.

    Regards, 

    Andre

  • Dear Sir,

    I am using Beaglebone and running TI SDK for beaglebone.

    I want to configure a software time interrupt at every 3 sec in beaglebone. For this purpose i had written a kernel module and checking the software with insmod command in my beaglebone.

    I am facing the problem that timer interrupt occurs only once during first time insmod (inserting module) in kernel. But, code is such that interrupt have to occur at every 3 seconds. The autoreload feature is enabled in the timer setting configuration.

    I request you to let me the issue creating such problem.

    Please find the contents of .c file as below:

    #include <linux/module.h>		
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/clk.h>
    #include <linux/irq.h>
    #include <linux/interrupt.h>
    #include <asm/io.h>
    #include <mach/dmtimer.h>
    #include <linux/types.h>

    // opaque pointer to timer object
    static struct omap_dm_timer *timer_ptr;

    // the IRQ # for our gp timer
    static int32_t timer_irq;

    // do some kernel module documentation
    MODULE_AUTHOR("Ajay");
    MODULE_DESCRIPTION("AM335x GP Timer Module");
    MODULE_LICENSE("GPL");



    /* The interrupt handler.
    This is pretty basic, we only get an interrupt when the timer overflows,
    We are just going to print a really obnoxious message each time
    */
    static irqreturn_t timer_irq_handler(int irq, void *dev_id)
    {
    // keep track of how many calls we had
    static int32_t irq_counter = 0;

    // reset the timer interrupt status
    omap_dm_timer_write_status(timer_ptr, OMAP_TIMER_INT_OVERFLOW);
    omap_dm_timer_read_status(timer_ptr); // YES, you really need to do this 'wasteful' read

    // print obnoxious text
    printk("Meow Meow Meow %d\n", irq_counter ++);

    // tell the kernel it's handled
    return IRQ_HANDLED;
    }



    // Initialize the kernel module
    static int __init gptimer_test_init(void)
    {
    int ret = 0;
    struct clk *gt_fclk;
    uint32_t gt_rate;


    printk("gptimer test: starting moudle init\n");

    // request a timer (we are asking for ANY open timer, see dmtimer.c for details on how this works)
    timer_ptr = omap_dm_timer_request();
    if(timer_ptr == NULL){
    // oops, no timers available
    printk("gptimer test: No more gp timers available, bailing out\n");
    return -1;
    }

    // set the clock source to system clock
    omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK);

    // set prescalar to 1:1
    omap_dm_timer_set_prescaler(timer_ptr, 0);

    // figure out what IRQ our timer triggers
    timer_irq = omap_dm_timer_get_irq(timer_ptr);

    // install our IRQ handler for our timer
    ret = request_irq(timer_irq, timer_irq_handler, IRQF_DISABLED | IRQF_TIMER , "gptimer test", timer_irq_handler);
    if(ret){
    printk("gptimer test: request_irq failed (on irq %d), bailing out\n", timer_irq);
    return ret;
    }

    // get clock rate in Hz
    gt_fclk = omap_dm_timer_get_fclk(timer_ptr);
    gt_rate = clk_get_rate(gt_fclk);

    // set preload, and autoreload
    // we set it to the clock rate in order to get 1 overflow every 3 seconds
    omap_dm_timer_set_load(timer_ptr, 1, 0xFFFFFFFF - (3 * gt_rate));

    // setup timer to trigger our IRQ on the overflow event
    omap_dm_timer_set_int_enable(timer_ptr, OMAP_TIMER_INT_OVERFLOW);

    // start the timer!
    omap_dm_timer_start(timer_ptr);

    // done!
    printk("gptimer test: GP Timer initialized and started (%lu Hz, IRQ %d)\n", (long unsigned)gt_rate, timer_irq);

    // return sucsess
    return 0;
    }

    // Cleanup after ourselfs
    static void __exit gptimer_test_exit(void)
    {
    printk("gptimer test: cleanup called\n");

    // stop the timer
    omap_dm_timer_stop(timer_ptr);

    // release the IRQ handler
    free_irq(timer_irq, timer_irq_handler);

    // release the timer
    omap_dm_timer_free(timer_ptr);
    }

    // provide the kernel with the entry/exit routines
    module_init(gptimer_test_init);
    module_exit(gptimer_test_exit);
  • Hi Peaves,

     

    What may be other drawbacks, aside from noise, when removing the 32.768KHz crystal? Also for clarrification, the software solution works for the RTC, but not if other modules also needed the OSC1(32.768KHz)? It works if its only one module or if you want to use the RTC, don't remove the crystal?

     

    Regards,

    Katie V

  • I'm not sure if I understand your questions.

    If you configure any circuits in AM335x to use the 32.768 kHz oscillator (OSC1) it will be necessary to connect a 32.768 kHz crystal circuit or 32.768 kHz CMOS oscillator to OSC1.  For this use case refer to the 'OSC1 Internal Oscillator Clock Source' or 'OSC1 LVCMOS Digital Clock Source' sections in the AM335x Data Sheet.

    If you do not have any circuits in AM335x configured to use OSC1, it is not necessary to connect anything to the OSC1 terminals.  For this use case refer to the 'OSC1 Not Used' section in the AM335x Data Sheet.

    Regards,
    Paul

  • For the 'OSC1 Not Used' section, customer has the following after they remove OSC1:  (ZCZ package)

    The circuit that our board has after we remove the 32khz crystal is two 18pf caps one each to VSS_RTC from RTC_XALIN and RTC_XALOUT:

    RTC_XALIN --- 18pf --- VSS_RTC --- 18pf --- RTC_XALOUT

    I am curious what effect the two 18pf caps would make on the circuit. 

    We do not have the VSS_RTC tied to ground.  I measure less than .2ohms to digital ground on VSS_RTC.  How important is it that VSS_RTC be tied to ground if no crystal is used? 

    They were seeing some of the issues mentioned above with the 32Khz crystal but after further requirements reviewed did not need to use the features the 32Khz adds.   All issues have now gone away with the 32Khz removed and the workaround did not fix the issue mentioned above.   Therefore trying to understand the implications of not modifying the pcb.

     

  • This should not be an issue.  However, I'm would like to know why they plan to install the two 18pf capacitors when they do not plan to install the crystal.

    Regards,
    Paul

  • Thanks, yes the capacitors were more for existing boards.

    Just wanted to also make sure the comment below is OK since they are using the ZCZ package:

    "We do not have the VSS_RTC tied to ground.  I measure less than .2ohms to digital ground on VSS_RTC.  How important is it that VSS_RTC be tied to ground if no crystal is used?"

  • Hi everybody,

    we are facing similar problems on a custom board equipped with AM3356 (ZCZ).

    We have a GSM module close to the processor. Its noise couples into OSC0 and OSC1 circuits. We wired both of them to digital gound but it seems this make the things even worse. So we are considering the use of active oscillators. It seems other customers adopted this solution: http://e2e.ti.com/support/arm/sitara_arm/f/791/p/268225/1118480.aspx#1118480.

    Our system must support suspend to RAM so we need to turn on and off OSC0 (24 MHz) oscillation. In case of an active oscillator, how to handle this? Is it enough change linux suspend code to control external active oscillator via dedicated GPIO line?

    Thanks in advance.

  • The answer to Marty's question in the next-to-last post:

    The figure 'OSC1 (ZCE Package) Not Used Schematic' in the data sheet shows the VSS_RTC connected to ground.  This is the recommendation when you know OSC1 is not going to be use, but it should be okay to leave this terminal not connected in your case where you decided OSC1 wasn't being used after you built the board.

     

    The answer to Andrea's question in the previous post:

    The GSM transmitter creates a very strong RF field that can couple into other circuits.  The crystal circuits are susceptible to strong external noise sources because these resonate circuits produce sinusoidal signals which are input to AM335x.  These signals cross through the threshold of the input buffer very slowly which allows external noise sources to generate multiple transitions as they transition through the input threshold.  Multiple transitions on the rising/falling edges may generate clock glitches inside AM335x.  Using an 1.8 volt LVCMOS digital clock source with rise/fall times less than 5ns may be a good solution to your problem because fast transitions through the input threshold makes it difficult for noise to generate multiple transitions on the input signal. 

    OSC0 is required.  However, a clock source for OSC1 may not be required if you have not configured any of the AM335x internal circuits to use OSC1.

    You will need to leave the oscillator running since this processor does not have a clock request output signal that would turn on the oscillator when resuming from a sleep state.

     

    Regards,
    Paul

  • Pauls,

    thank you very much for these helpful hints.

    Regards,

    Andrea

  • Paul,

    thank you very much for these helpful hints.

    Regards,

    Andrea

  • Paul,

    I would like to ask you one more thing about Advisory 1.0.30. In case crystals come with metallic package, what do you suggest to do? Leave it floating or connect it to digital ground?

  • I do not know the answer to this question.  This may be a question for the crystal vendor.

    In general it is normally better to ground any floating nodes so they do not build-up any electrical potential when exposed to electrical noise.

    I would connect it to ground via a zero ohm resistor to allow either option.

    Regards,
    Paul 

  • Dear Vaibhav/Paul

    We are working on a product, based on AM335X platform which uses Timer4 interface to drive SOC of ADS1158 ADC (TI).

     

    GPMC_ADVN_ALE/TIMER4/GPIO2_2 (PIN R7) is used as TIMER4

     

    I confirm all the require pin-mux is fine by “cat /sys/kernel/debug/omap_mux/”.

     

    Right now we are facing 2 issues as explained below in detail:

     

    1)      Unable to configure the TIMER4 pin output default as High (This is  in need because we have an invert logic on SOC, which will make LOW towards ADS1158). Since timer4 output is LOW, SOC is asserted all the time when timer is not in use even before driver initialization started which will result in DRDY interrupts triggered.

    How to configure the TIMER4 output to default as HIGH?

     

    2)      Even though we continued with TIMER4 default as LOW, whenever we  initialize and start the timer with some counter value, the timer never get triggered. Below is the code that I followed for timer init.

     

    /* ads1158_timer4_init - Timer4 Initialisation
     *
     * Initialize the Timer4 & Pulse timer
     *
     * Returns: 0 on success
     *          -1 on failure
     */
    static int ads1158_timer4_init(struct ads1158_state *st)
    {
            struct clk *clk_fclk;
            int ret;
            u16 tmp;

            printk("%s : called :\n",__func__);

            /* request the timer4 */
            st->pwm_timer = omap_dm_timer_request_specific(DMTIMER_4);
            if (st->pwm_timer == NULL) {
                    // oops, no timers available
                    dev_err(&(st->spi->dev), "dmtimer-4 test: No more DM timers-4 available, failing out\n");
                    return -1;
            } else {
                    printk("%s : dmtimer-4 requested successful:\n",__func__);
            }
            dm_timer4_adc = st->pwm_timer;

            // set prescalar to 1:1
            omap_dm_timer_set_prescaler(st->pwm_timer, 0);

    --         st->irq_num = omap_dm_timer_get_irq(st->pwm_timer);
            printk("st->irq_num : %d\n", st->irq_num);

            ret = request_irq(st->irq_num, timer4_interrupt_handler,
                               IRQF_SHARED, "ads1158_pwm_timer", st);
            if (ret) {
                    dev_err(&(st->spi->dev), ": Failed to request interrupt line\n");
                    goto err1;
            }
            clk_fclk = omap_dm_timer_get_fclk(st->pwm_timer);
            st->fclk_khz = (clk_get_rate(clk_fclk)) / 1000;
            printk ("Timer4 operating frequency = %ld KHz\n", st->fclk_khz);


           // we set it to the clock rate in order to get 1 overflow every 20 mili seconds
            omap_dm_timer_set_load(st->pwm_timer, 1, 0xFFFFFFFF - (20 * st->fclk_khz));

            // setup timer to trigger our IRQ on the overflow event
            omap_dm_timer_set_int_enable(st->pwm_timer, OMAP_TIMER_INT_OVERFLOW);

            omap_dm_timer_start(st->pwm_timer);

     

             return;
    err1:
            omap_dm_timer_free(st->pwm_

    timer);

            return ret;
    }

    RESULT:

    There is no status change happening when we probe at TIMER4 output. Are we missing anything?

     

    Please Help us in this regard, it’s very urgent.

    Some sample module to use timer4 as output which will run for 16 ms(HIGH) On time and 4 ms Off(LOW) time will help us.

     

    Appreciate you quick response.

  • Hi,

    Shouldn't you set the timer source at some point during the initialization?

    int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)

    Best regards,
    Miroslav

  • Dear g.f

    There's something I want to ask Mr/ Ms g.f.  May I ask you a few questions?
    This problem sometimes occurs on my customer board. (131072sec jump)
    But I have not been able to reproduce this issue with EVM.
    We believe this problem is caused by external noise(Errata: Advisory 1.0.30 "OSC0 and OSC1").
    However, it is necessary to clarify this 131072sec jump to my customer.
    In case of Advisory 1.0.30, I think to be a random jump. I wonder why it is every 131072sec jump.
    So, I'd like some information from you.


    1)Please let me know your condition of this problem.
    From your post, I'm understanding as follows. Is my understanding correct?

    32kHz Extenal Clock source& Posted Mode:           NG (131072sec jump)
    32kHz Extenal Clock source& None-Posted Mode: OK (no problem)
    24MHz Clock source(from DPLL) & Posted Mode:          OK (no problem)
    24MHz Clock source(from DPLL) & None-Posted Mode: OK (no problem)


    2)
    You said TCRR register's value was decreased a few hundreds of count from the current TCRR value.
    Is my understanding correct?

    I checked linux code. If TCRR register's value is decreased, the Linux "date" becomes 131072sec jump.
    Because the overflow occurs. (32.768kHz & 32bit counter = 131072sec)
    I think, if (1) and (2) are yes, the cause of 131072sec jump is the combination of Advisory 1.0.30 and Advisory 1.0.39.

    I'll be grateful if you can reply to me.

    Best Rerads,
    Taka