Shop OBEX P1 Docs P2 Docs Learn Events
POSEDGE detection code. — Parallax Forums

POSEDGE detection code.

StephenMooreStephenMoore Posts: 188
edited 2012-05-28 16:42 in Propeller 1
I am trying to measure the number of pulses coming into pina between the toggling of pinb.

I want to continuously read out the pulse total in a separate cog. Here is the scenario:
''Counter used as a pulse counter
CON


  POSEDGE = 0100000
        
PUB Start(countAddr, pulsePin, disablePin) 


pina := pulsePin
pinb := disablePin


cognew(@entry, countAddr)


DAT
                        org
                        
entry                   mov     frqa, #1                     'increment for each edge seen
                        movs    ctra, pina                   'setup encoder pin
                        movi    ctra, ctra_                  'establish mode and start counter 
                        
:loop                   test    ina, pinb      wz            'check state of stepper drive enable pin                        
              if_z      jmp     #:loop                       
                        mov     phsa, #0                     'zero out pulse counter
                                                         
:count                  test    ina, pinb      wz
                        wrlong  phsa, par                    'send the current value back
              if_nz     jmp     #:count
                        jmp     #:loop
                        
ctra_                   long      POSEDGE<< 26               'mode
pina                    long      1
pinb                    long      1
addr                    res       1

I am passing the address of my display variable in countAddr when I call Start(countAddr, pulsePin, disablePin). However, the code fails and I can not figure out why.

Any suggestions would be welcome.

Sincerely,

sm

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-05-28 01:07
    The register ina cannot be used as a destination register, but only in the source position. Also, pinb has to be a bitmask, i.e. 1 << disablePin.

    -Phil
  • AribaAriba Posts: 2,690
    edited 2012-05-28 10:53
    Also the definition and setting of the POSEDGE mode is wrong. If you use MOVI you must not shift it by 26 first, instead you can write the mode+pll bits direct in the movi instruction.

    Here is a corrected (but untested) version. For sure you need to pass some values to the Start methode to try it.
    ''Counter used as a pulse counter
    CON
    
      POSEDGE = %01010_000
            
    PUB Start(countAddr, pulsePin, disablePin) 
     pina := pulsePin
     pinb := disablePin
     maskb := 1<<disablePin
    
     cognew(@entry, countAddr)
    
    
    DAT
                            org     0
                            
    entry                   mov     frqa, #1                     'increment for each edge seen
                            movs    ctra, pina                   'setup encoder pin
                            movi    ctra, #POSEDGE               'establish mode and start counter 
                            
    :loop                   test    maskb, ina     wz            'check state of stepper drive enable pin                        
                  if_z      jmp     #:loop                       
                            mov     phsa, #0                     'zero out pulse counter
                                                             
    :count                  test    maskb, ina     wz
                  if_nz     jmp     #:count
                            wrlong  phsa, par                    'write the measured value
                            jmp     #:loop
                            
    pina                    long      0
    pinb                    long      0
    maskb                   long      0
    addr                    res       1
    

    Andy
  • StephenMooreStephenMoore Posts: 188
    edited 2012-05-28 11:59
    Thank you for your help: those were some pretty dumb errors.

    The code still doesn't update the phsa value with the pulse inputs from pina so I added some debug features.

    ''Counter used as a pulse counter
    CON
      POSEDGE = 010000
    VAR
            long          value        
    PUB Start(countAddr, pulsePin, disablePin) 
    
    
    'pina := pulsePin
    led  := 8
    pina := 9
    pinb :=  disablePin
    maskb := 1 << pinb
    maskled := 1 << led
    
    
    cognew(@entry, countAddr)
    
    
    
    
    DAT
                            org
                            
    entry
                            or      dira, maskled
                            mov     frqa, #1                     'increment for each edge seen
                            movs    ctra, pina                   'setup encoder pin
                            movi    ctra, #POSEDGE               'establish mode and start counter
                              
                            
    :loop                   test    maskb, ina      wz            'check state of stepper drive enable pin (pinb goes low to start)                       
                  if_z      jmp     #:loop
                            mov     phsa, #0                     'zero out pulse counter                              
                            mov     time, cnt
                            add     time, delay
    
    
    :count                  test    maskb, ina      wz
                            xor     outa, maskled
                            waitcnt time, delay                        
                            wrlong  phsa, par                    'send the current value back
                  if_nz     jmp     #:count
                   
                            jmp     #:loop
    
    
    pina                    long      0
    pinb                    long      0
    maskb                   long      0
    delay                   long      $400000
    led                     long      0
    maskled                 long      0
    time                    res       1
    

    Other than that the logic seems ok. That is pinb On/Off starts the led blinking but the posedge counter does not count the led pusles.

    The wrlong works fine as I can read and display from the calling cog values I force into the phsa register.

    I appreciate your help and am a little concerned why after all the effort I put into learning PASM very little of it sticks with me.

    Sincerely,

    sm
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-05-28 12:13
    The movs to ctra requires a pin number. You had that part right the first time. I'm not sure what this is all about:
    led  := 1 << 8
    pina := led << 1
    

    pina, in this case, evaluates to 512, which is not a valid pin number.

    -Phil
  • StephenMooreStephenMoore Posts: 188
    edited 2012-05-28 12:16
    An error. I updated the above code but am still getting errors.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-05-28 14:46
    I have now scrubbed the code from every error I can see... can anyone else find where it is broken?

    The program is supposed to pulse pin 8 (led) which is used to provide input to pin 9 (pina), which it does. The counter is supposed to simply count the pulse leading edges and write the number out continuously, which it does not.

    ''Counter used as a pulse counter
    CON
    
    
      POSEDGE = 010000
                    
    PUB Start(countAddr, pulsePin, disablePin) 
    
    
    'pina := pulsePin
    led  := 8
    pina := led + 1
    pinb :=  disablePin
    maskb   := 1 << pinb
    maskled := 1 << led
    
    
    cognew(@entry, countAddr)
    
    
    
    
    DAT
                            org
                            
    entry
                            or      dira, maskled
    
    
                            movs    ctra, pina                  'setup encoder pin
                            movi    ctra, #POSEDGE               'establish mode and start counter
                           
                            mov     frqa, #1                     'increment for each edge seen
                              
                            
    :loop                   test    maskb, ina      wz            'check state of stepper drive enable pin (pinb goes low to start)                       
                  if_z      jmp     #:loop
                            mov     phsa, #0                     'zero out pulse counter                              
                            mov     time, cnt
                            add     time, delay
    
    
    :count                  test    maskb, ina      wz
                            xor     outa, maskled
                            waitcnt time, delay                       
                            wrlong  phsa, par                    'send the current value back
                  if_nz     jmp     #:count
                   
                            jmp     #:loop
    
    
    pina                    long      0
    pinb                    long      0
    maskb                   long      0
    delay                   long      $400000
    led                     long      0
    maskled                 long      0
    time                    res       1
    

    I hope that your Memorial Day is a good one.
  • AribaAriba Posts: 2,690
    edited 2012-05-28 16:21
    There was another problem in the code with reading phsa. You can read it only at the src position, so I have to copy it first into the shadow register which is then written to the hub variable.

    The following code works on my Quickstart board. It has a testcode which calls the Start methode and generates some test patterns at the pins:
    CON
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
    
    OBJ
      ser :  "FullDuplexSerial"
    
    VAR
      long  value      
    
    PUB Main
      ser.start(31,30,0,115200)
      Start(@value, 0, 1)              'clock at pin0, disable at pin 1
      ctra := %00100<<26 + 0
      frqa := 1<<31 / (clkfreq/2000)   'output testclock 1000Hz at pin 0
      dira[1..0] := %11   
      repeat
        outa[1] := 1
        waitcnt(clkfreq/10 + cnt)      'enable 100ms
        outa[1] := 0
        ser.dec(value)
        ser.tx(13)
    
        outa[1] := 1
        waitcnt(clkfreq + cnt)         'enable 1s
        outa[1] := 0
        ser.dec(value)
        ser.tx(13)
    
    
    ''Counter used as a pulse counter
    CON
    
      POSEDGE = %01010_000
            
    PUB Start(countAddr, pulsePin, disablePin) 
     pina := pulsePin
     pinb := disablePin
     maskb := 1<<disablePin
    
     cognew(@entry, countAddr)
    
    
    DAT
                            org     0
                            
    entry                   mov     frqa, #1                     'increment for each edge seen
                            movs    ctra, pina                   'setup encoder pin
                            movi    ctra, #POSEDGE               'establish mode and start counter
                            
    :loop                   test    maskb, ina     wz            'check state of stepper drive enable pin                        
                  if_z      jmp     #:loop                       
                            mov     phsa, #0                     'zero out pulse counter
                                                             
    :count                  test    maskb, ina     wz
                  if_nz     jmp     #:count
                            mov     phsa, phsa                   'copy phsa to shadow register
                            wrlong  phsa, par                    'write the measured value
                            jmp     #:loop
                            
    pina                    long      0
    pinb                    long      0
    maskb                   long      0
    ledmsk                  long      1<<16
    

    Andy
  • StephenMooreStephenMoore Posts: 188
    edited 2012-05-28 16:42
    Ariba!

    That's it. I can not express to you how many times I have gone over this code and failed to make it work right. This business of shadow registers is covered only vaguely in the manual.

    I thank you sir for your help. And thanks to Mr. Pilgrim for looking at too.

    I wish there were a way to payback but I always seem to be on the receiving end.

    Regards,

    sm
Sign In or Register to comment.