Shop OBEX P1 Docs P2 Docs Learn Events
Problem with "Pause" — Parallax Forums

Problem with "Pause"

dardar Posts: 15
edited 2012-12-24 11:22 in Propeller 1
Hi, i have a little problem, i want to pause a minute i'm trying to do it using:

clk.PauseSec(60) with "clock" object, but it don't works it pause a few seconds, however if i pause 10 or 20 seconds it works fine.

Can you explain me why it happens?

Now to pause a minute i'm doing with a loop:

repeat 3
clk.PauseSec(20)

But i want to do it correctly, i'm reading now how "waitcnt" works to try to do the correct pause.

Thanks.

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2012-12-24 03:58
    I don't know the clock-object and for me it looks like it is implemented suboptimal - to say it in a gentle way.

    It looks like this pauseSec funktion works with the cnt and does not take into account that cnt wraps around after somewhat around 50 seconds. So if you don't want to fix this object, your workaround is the right thing to do.
  • JonnyMacJonnyMac Posts: 9,108
    edited 2012-12-24 09:57
    It's not necessary to invoke an entire object for mundane processes like an inline pause. I have this method in default template program:
    pub pause(ms) | t
    
    '' Delay program in milliseconds
    
      if (ms < 1)                                                   ' delay must be > 0
        return
      else
        t := cnt - 1776                                             ' sync with system counter
        repeat ms                                                   ' run delay
          waitcnt(t += MS_001)
    


    2^31 milliseconds works out to just under 25 days!

    The pause method is supported by a compile-time constant MS_001, which is defined at the top of my template:
    con
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000                                          ' use 5MHz crystal
    ' _xinfreq = 6_250_000                                          ' use 6.25MHz crystal
    
      CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq
      MS_001   = CLK_FREQ / 1_000
      US_001   = CLK_FREQ / 1_000_000
    


    I've attached the code I use as my template -- it's easy enough to chop out any unused methods.
  • dardar Posts: 15
    edited 2012-12-24 10:05
    so to wait for a minute, i need to do a loop? don't exist other opcion?
    with waitcnt for example to wait a seconds can i use:

    waitcnt(CLK_FREQ cnt)

    and use a loop to wait 60 seconds?

    Thanks for the code, i will look it to learn and understand how it works to do the pause!!!
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-24 10:21
    If you don't want to use Jon's method, you could wait a minute many other ways.

    As you suggest, use a loop of second long waits.
    repeat 60
      waitcnt(clkfreq + cnt)
    

    You could wait one minute this way:
    waitcnt(clkfreq * 60 + cnt)
    

    You'll need to use the loop method to wait longer than the counters reset time. (IIRC, @80MHz the counter rolls over in about 2 minutes 54 seconds.)

    The above waits aren't exact. They'll be off a bit since it take time to execute the code to setup the wait. I believe JonnyMac's code takes this overhead into account (that's why he uses "- 1776").
  • dardar Posts: 15
    edited 2012-12-24 10:24
    Duane Degn wrote: »
    If you don't want to use Jon's method, you could wait a minute many other ways.

    As you suggest, use a loop of second long waits.
    repeat 60
      waitcnt(clkfreq + cnt)
    

    You could wait one minute this way:
    waitcnt(clkfreq * 60 + cnt)
    

    You'll need to use the loop method to wait longer than the counters reset time.

    The above waits aren't exact. They'll be off a bit since it take time to execute the code to setup the wait. I believe JonnyMac's code takes this overhead into account (that's why he uses "- 1776").



    Thanks for the suggestion!, but if i use:
    waitcnt(clkfreq * 60 + cnt)
    

    How i know when is the counters reset time?

    If i want to wait 5 minutes can i use:
    waitcnt(clkfreq * 300+ cnt)
    
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-12-24 10:53
    You can't use clkfreq * 60, as this would be a value bigger than what fits into a 32 bit register (if the clkfreq is 80MHz). There is no warning or errormessage from the Compiler, because it only compiles and does not have any glue about the content of variables. So, you as a programmer have to make sure that you don't exceed the limits of datatypes.

    As I said in my first answer, the limit is somewhere around 50 seconds.

    (2^32-1) / 80_000_000 to be exact.

    That's why you have to break down bigger wait-times into 1s wait-statements or 10s wait-statements.
  • JonnyMacJonnyMac Posts: 9,108
    edited 2012-12-24 11:00
    That's why you have to break down bigger wait-times into 1s wait-statements or 10s wait-statements.


    Even breaking down to milliseconds gives a usable span of delays. To pause four one minute:
    pause(60_000)
    


    I like to use the underscore character where a comma would normally go when writing out a large number.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-24 11:22
    MagIO2 wrote: »
    You can't use clkfreq * 60, as this would be a value bigger than what fits into a 32 bit register

    You're of course right. I should have known that.

    Edit: Apparently I was remembering incorrectly about the roll over time. It's not over two minutes, it's less than one. About 53 seconds.

    32 bits has 4,294,967,295 possible values. Divide this by 80,000,000 (clock cycles in one second at 80MHz) and you get 53 (rounded down to nearest second).
Sign In or Register to comment.