Shop OBEX P1 Docs P2 Docs Learn Events
Generating a time interval in assembly — Parallax Forums

Generating a time interval in assembly

Paul MPaul M Posts: 95
edited 2011-07-22 15:46 in Propeller 1
I have an assembly loop which runs at about 50us per loop. I want to also run a chunk of code every second or so.

The following code snippet sort of works except of course when the value of cnt+_Gate results in an overflow. Using signed maths makes things worse. I suppose I could test for the overflow, set a flag, and then do some tests before comparing cnt_ with cnt......
Or is there a simpler solution?
DAT
         mov     cnt_, cnt               'setup time interval
         add     cnt_, _Gate             '_Gate is initialised elsewhere 
                                          ' "the value of _Gate">>"time to execute entire loop"
loop 

        'do stuff every time round the loop



         'check if interval has elapsed        
         mov   temp, cnt
         cmp   temp, cnt_   wc      'C flag set if cnt_ > temp
if_c     jmp    #over                'interval has not elapsed

         'do other stuff approximately every _Gate ticks
         '
         '
         mov    cnt_ , cnt
         add    cnt_ , _Gate             'set up next interval 

over

        'do yet more stuff
        '
        '
        '
         jmp   #loop

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2011-07-22 03:42
    The counter based solution discussed in assembly language question may help you (including adjustments). As long as you stay within the overrun limit (53.68sec @80MHz) you'll be fine.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-07-22 06:30
    You can used cmps for signed values or, as Marko suggests, you can set one of the cog's counters into free-run mode and use it as a timer. Below are snippets from my DMX receiver object that will extinquish the DMX siganl LED if signal is lost for the period defined by LOS_TIX
    FREE_RUN                long    %11111 << 26                    ' just runs
    
    mov     ctrb, FREE_RUN                  ' set ctrb for LOS timing
                            mov     frqb, #1 
                            mov     phsb, #0
    
    ' Check loss-of-signal timer
    ' -- if time-out, LED extinguished and C flag set
    
    checkidle               cmp     LOS_TIX, phsb           wc, wz  ' check LOS timer
            if_b            andn    outa, ledmask                   ' led off if time-out   
    checkidle_ret           ret
    

    Note that the comparison looks "backward" -- this is required because phsb cannot be used in the destination field of cmp.

    Of course, when signal is detected (a DMX byte has been rx'd), the timer is reset by clearing phsb.
  • Paul MPaul M Posts: 95
    edited 2011-07-22 08:30
    Thanks for the replies. Have implemented the interval using counter B as counter A was already in use.

    @JonnyMac Just out of interest, how do you do what I was trying to do using signed maths - I just couldn't get it to work properly whatever combination of ADD, ADDS, CMP, CMPS etc. that I used?
  • localrogerlocalroger Posts: 3,452
    edited 2011-07-22 09:46
    This can be done with subtraction in such a way that 2's-complement rollover will be eliminated and you don't have to worry about signed or unsigned math:
            mov tmp,cnt
            sub tmp,lastcnt
            cmp tmp,interval_len
    if_c    jmp #notyet
            mov lastcnt, cnt
            ;do interval stuff
    
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-07-22 15:46
    FullDuplexSerial has useful ideas -- this is what I extract from it:
    mov     timer, period
                            add     timer, cnt
    
                            ' code here
    
                            mov     tmp, timer
                            sub     tmp, cnt
                            cmps    tmp, #0         wc
    
            if_nc           ' not done
    
Sign In or Register to comment.