PDA

View Full Version : Help with spin to assembly conversion



swampie777
03-31-2009, 01:41 AM
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

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

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

Mike Green
03-31-2009, 01:57 AM
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.

swampie777
03-31-2009, 02:01 AM
Thanks!

swampie777
03-31-2009, 07:27 AM
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 Green
03-31-2009, 07:37 AM
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

swampie777
03-31-2009, 11:16 PM
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 Green
03-31-2009, 11:47 PM
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_fool
03-31-2009, 11:48 PM
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_fool
03-31-2009, 11:52 PM
Sorry Mike. I didn't see your reply. Ilike yours better and that is exactly what I use.

swampie777
04-02-2009, 01:00 AM
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 Green
04-02-2009, 02:34 AM
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.