Shop OBEX P1 Docs P2 Docs Learn Events
Help with spin to assembly conversion — Parallax Forums

Help with spin to assembly conversion

swampie777swampie777 Posts: 33
edited 2009-04-01 18:34 in Propeller 1
I am trying to read ( get timming width of) a single pulse. When I did this in spin code the results were 5 time the o-scope width. I went to assembly:

CON
·_clkmode = xtall + pll16x
·_xinfreq = 5_000_000

Var

·Long xxx1

obj

·· num : "Numbers"
·· TV : "TV_Terminal

PUB Main

· cognew(@pulse,@xxx1)
· waitcnt(2_000_000 + cnt)

· Num.Init
· TV.Start(12)
· TV.Str(Num.ToStr(xxx1,Num#DDEC))

· TV.Out(13)
·
repeat

DAT

············· org 0

pulse······ mov· Mem,PAR
:loop······ waitpeq %0,25
············· waitpne %0,25
············· mov······xx1,cnt
··············waitpeq %0,25
············· mov yy1,cnt
············· sub· yy1,xx1
············· wrlong Mem,yy1
············· jmp···· :loop



xx1·· res· 1
yy1·· res· 1
Mem· res· 1

This does not work. Any comments?

Thanks

[noparse][[/noparse]edit, I added a subject for you. Bean]

Post Edited By Moderator (Bean (Hitt Consulting)) : 3/30/2009 6:13:07 PM GMT

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-03-30 17:57
    You've got the WRLONG backwards. The destination field is actually the address of the value and the source field is actually the hub address. Try "wrlong yy1,PAR". You don't need the separate register Mem. You can use PAR directly.
  • swampie777swampie777 Posts: 33
    edited 2009-03-30 18:01
    Thanks!
  • swampie777swampie777 Posts: 33
    edited 2009-03-30 23:27
    I made the suggested change. still no.

    I also put in a pin change in the assembly ( hooked to an LED) and it does not get toggled.

    I don't think the cognew is launching it.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-03-30 23:37
    The WAITPNE and WAITPEQ are all wrong as well. Look at the descriptions of these instructions in the Propeller Manual.· The operands are bitmasks for the I/O pins to be used.· You can optionally use an immediate bitmask for the source field, but not for the destination field.

    It would also help for you to explain what you're trying to do. For example, what edge do you intend to use for the leading edge and trailing edge of your pulse?· Is this a single pulse or do you have several coming in?· If several, how close together are they?

    Also consider that the cog counters may give you a better result since they can time a pulse to the nearest clock pulse, but need help from an assembler or Spin routine for set up and to read the count before the next one comes in.

    Post Edited (Mike Green) : 3/30/2009 11:42:31 PM GMT
  • swampie777swampie777 Posts: 33
    edited 2009-03-31 15:16
    I want to measure individual pulses from rising edge to falling edge. I have a few devices that put data out as a square wave, some the positive pulse is the issue, on others the duty cycle is important. On one device I want to measure individual pulses from a group of pulses and do statistics on the group from the results.

    Thanks for your timely help!

    Swampie777
  • Mike GreenMike Green Posts: 23,101
    edited 2009-03-31 15:47
    Here's one example to measure the width of a single positive going pulse:
    CON
     _clkmode = xtall + pll16x
     _xinfreq = 5_000_000
     
    Var 
     Long xxx1
     
    obj
       num : "Numbers"
       TV : "TV_Terminal
     
    PUB Main
      cognew(@pulse,@xxx1)
      Num.Init
      TV.Start(12)
      repeat
        xxx1 := -1   ' Set result to invalid pulse width
        repeat while xxx1 == -1   ' Wait for valid pulse width to be measured
        TV.Str(Num.ToStr(xxx1,Num#DDEC))
        TV.Out(13)
    
    DAT
                org        0
    pulse    waitpeq  zero,mask     ' Wait for initial logic zero (no pulse)
    :loop    waitpne  zero,mask     ' Wait for leading edge of pulse
                mov      xx1,cnt          ' Save starting time
                waitpeq  zero,mask     ' Wait for trailing edge of pulse
                mov      yy1,cnt          ' Compute width of pulse
                sub       yy1,xx1
                wrlong  yy1,PAR         ' Update pulse width
                jmp      #:loop
    zero      long     0
    mask    long      |< 25            ' Assume pin is I/O 25
    xx1       res       1
    yy1       res       1
    
    
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-03-31 15:48
    Look for the R/C receiver packages in OBEX. They measue the 1ms-2ms pulses for the servos. It can be done with spin or asm depending on pulse width and repetition rate.

    Donald
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-03-31 15:52
    Sorry Mike. I didn't see your reply. Ilike yours better and that is exactly what I use.
  • swampie777swampie777 Posts: 33
    edited 2009-04-01 17:00
    Mike;

    The suggestions you made were incorporated. Additionally, I modified the first repeat do do 11 values.

    91808 -0.0426%
    91890 0.0467%
    91861 0.0151%
    91844 -0.0034%
    91841 -0.0066%
    91843 -0.0045%
    91844 -0.0034%
    91873 0.0282%
    91844 -0.0034%
    91841 -0.0066%
    91829 -0.0197%

    1010318

    91847.09091

    This was for a 1.148 ms pulse. I'm now curious as to how to further stabilize the counters.
    I believe that more accuracy is possible.

    Thanks for your help!
  • Mike GreenMike Green Posts: 23,101
    edited 2009-04-01 18:34
    You've got a systematic error of about 30 PPM which is well within the specification of most crystals.· You've also got some variation from one reading to the next that's on the order of 3 PPM which could be accounted for by the jitter in the PLL used for the system clock.· You're not going to do much better without using an external clock source that's more stable than the readings you want.
Sign In or Register to comment.