Shop OBEX P1 Docs P2 Docs Learn Events
PASM pin test timeout question — Parallax Forums

PASM pin test timeout question

Duane DegnDuane Degn Posts: 10,588
edited 2011-01-16 17:04 in Propeller 1
I'm working on a universal remote program using Nick's MagicIR. I'm still relatively new to PASM but I think I understand most of Nick's code. The exception is this part:
              mov       timeoutCurrent, cnt             ' prepare for calculating timeout
              add       timeoutCurrent, timeoutMax      ' start with cnt and add max timeout
 
pauseloop     cmp       timeoutCurrent, cnt     wc      ' if current timout has exceeded the system clock, set the C flag
    if_c      jmp       #exit                           ' current timeout exceeded, jump to exit
 
              test      Pin, ina                wc      ' no worries on timeout anymore, just check for a state change on ina
    if_c      jmp       #pauseloop                      ' if there's no statechange, jump back to pauseloop    
 
{later}
timeoutMax                      long            10_120_000  ' how many ticks until I give up on new signals
 

The way I see it, this should work except when the system clock is within timoutMax cycles from the roll over. In these cases I'd think the timeout would occur immediately since the first time timeoutCurrent and cnt are compared cnt would be larger than timeoutCurrent.

Another possible problem is if timeoutCurrent is closer to the roll over point than the time the loop takes (e.g. timeoutCurrent = ($FFFFFFFF - $4) with a loop that takes 12 clock cycles it is unlikely that cnt would often (if ever) be larger that timeout Current). In this (very unlikely) case the loop may never end since timeoutCurrent could be larger than cnt every time it is checked.

Am I not understanding this? I'd like to prevent a rare lockup of my code.

Is there a beter way to monitor a pin with a timeout?

Duane

PS While the code above is Nick's, it might not look the same. I changed most (if not all) variable names to match my convention.

Comments

  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-01-15 14:09
    You might want to look at the code in FullDuplexSerial -- it does bit timing based on a delta from a known cnt starting point; that will give you the correct math.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-01-15 14:22
    Jon, Thanks for answering. I was afraid I'd have to delve into FullDuplex. I know it has a timeout on one of its rxcheck methods. The last couple of times I've looked at FullDuplexSerial I've been a bit overwhelmed. It's a bit more advanced than your Spin Zones (which I love) have prepared me for. But if you say so, I'll do it.

    Off to make my brain hurt (in a good way).

    Thanks again for all your help. As I've mentioned before, I'm a big fan of your articles.

    As I remember, you wrote about timing on the Prop, though I think it was in Spin. I'll have to reread that article too.

    Just to be clear, the code I posted will have problems at certain times in the system clocks cycle?

    Duane
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-01-15 14:26
    Duane Degn wrote:
    Just to be clear, the code I posted will have problems at certain times in the system clocks cycle?
    Yes, it will have problems at roll-over.

    -Phil
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 14:31
    Hi Phil Pilgrim (PhiPi).

    I ve be used that code to ---> And that give me info why some times this code in ViewPort shows strange things.


    Yes, it will have problems at roll-over.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-01-15 14:51
    Here's the correct way to do it:
                  mov       timeoutCurrent, cnt             ' prepare for calculating timeout
     
    pauseloop     mov       timeoutDelta, cnt               'Get current time.
                  sub       timeoutDelta, timeoutCurrent    'Compute elapsed time.
                  cmp       timeoutDelta, timeoutMax  wc    'If elapsed time has met or exceeded timeoutMax, clear carry.
        if_nc     jmp       #exit                           ' current timeout exceeded, jump to exit
     
                  test      Pin, ina                wc      ' no worries on timeout anymore, just check for a state change on ina
        if_c      jmp       #pauseloop                      ' if there's no statechange, jump back to pauseloop    
     
    {later}
    timeoutMax                      long            10_120_000  ' how many ticks until I give up on new signals
    

    -Phil
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 14:54
    Hi Phil Pilgrim (PhiPi).

    BIG Thanks

    Here's the correct way to do it:
                  mov       timeoutCurrent, cnt             ' prepare for calculating timeout
     
    pauseloop     mov       timeoutDelta, cnt               'Get current time.
                  sub       timeoutDelta, timeoutCurrent    'Compute elapsed time.
                  cmp       timeoutDelta, timeoutMax  wc    'If elapsed time has met or exceeded timeoutMax, clear carry.
        if_nc     jmp       #exit                           ' current timeout exceeded, jump to exit
     
                  test      Pin, ina                wc      ' no worries on timeout anymore, just check for a state change on ina
        if_c      jmp       #pauseloop                      ' if there's no statechange, jump back to pauseloop    
     
    {later}
    timeoutMax                      long            10_120_000  ' how many ticks until I give up on new signals
    

    -Phil
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-01-15 15:18
    Phil,

    Where's the fun in that?

    I think I'd have figured it out in a couple of hours. (Actually I think I was getting close.) Here's an example in FullDuplexSerial (I want Jon to know I did my homework).
    receive                 jmpret  rxcode,txcode         'run a chunk of transmit code, then return
                            test    rxtxmode,#%001  wz    'wait for start bit on rx pin
                            test    rxmask,ina      wc
            if_z_eq_c       jmp     #receive
                            mov     rxbits,#9             'ready to receive byte
                            mov     rxcnt,bitticks
                            shr     rxcnt,#1
                            add     rxcnt,cnt                          
    :bit                    add     rxcnt,bitticks        'ready next bit period
    :wait                   jmpret  rxcode,txcode         'run a chuck of transmit code, then return
                            mov     t1,rxcnt              'check if bit receive period done
                            sub     t1,cnt
                            cmps    t1,#0           wc
            if_nc           jmp     #:wait
                            test    rxmask,ina      wc    'receive bit on rx pin
                            rcr     rxdata,#1
                            djnz    rxbits,#:bit
    
    I think what you wrote is hidden in there. You sure make it look easy.

    Now I'll have to make my brain hurt some other way.

    A big thanks from me too.

    This lots of fun.

    Duane
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-01-15 22:52
    I want Jon to know I did my homework

    Sorry... I would normally have posted a snippet for you to try but I was on my way out the door and I was hoping to point you in a helpful direction. Phil is the man -- listen to him by all means! ;)
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-01-16 17:04
    Jon,

    Not a problem at all. I'm often amazed at how helpful people (yourself included) are on this forum. I've seen you give very detailed answers many times. I often learn a lot from these posts.

    I was pleased that my most resent perusal of FullDuplexSerial wasn't near as intimidating as I thought it'd be.

    Yes, Phil is the man. He's another one I've learned a lot from.

    My thanks to both of you.

    Duane
Sign In or Register to comment.