SPIN ZONE
determined by measuring the period from one falling
edge, through the idle period, to the next falling edge. In
the past, I’ve measured pulses with the Propeller counters,
but this time we’ll need to measure the low and high
portions of the signal, and we’ll want to ensure that a
shorted input or disconnected cable does not cause the
values into the system to become corrupted.
The only way to measure the PPM pulse stream with
precision is to use assembly code. I’ll admit that it is a little
involved, but really not too bad when broken down piece
by piece. Let’s jump in.
At the very top, we’re going to start by writing a flag
indicating there is no detected PPM stream, then we’ll
monitor the input for a valid sync pulse:
vexin mov dira, #0
wrlong NO, flagpntr
findsync mov pwidth, #0
mov timer, US_001
waitpne pmask, pmask
add timer, cnt
:loop waitcnt timer, US_001
add pwidth, #1
test pmask, ina wz
if_z jmp #:loop
cmp pwidth, SYNC wc, wz
if_b jmp #vexin
■ FIGURE 5. VEX PPM Stream.
At findsync, the pulse width variable is cleared and a
timer is set up for one microsecond delays with waitcnt.
Then, we wait for the input to be low using waitpne. Note
that this is the only place in the code where we will use a
pin wait instruction; from this point forward, we will
manually scan the input so that we can do it on a timed
interval (one us).
Once a low on the input is detected, the timer is
started and drops into a loop, incrementing the pulse
width measurement every microsecond until the line goes
back high. We scan the PPM input using the test
instruction with a mask for the input pin (pmask) and the
pin input’s register (ina). The test instruction works exactly
like the and instruction but it doesn’t affect the variable in
the destination field. The Z flag is updated with the state
of the PPM input and as long as it remains true (Z = line is
low), the code will loop and increment the pulse
measurement variable. When the input goes high (during
the inter-pulse idle
period), the Z flag
will be cleared and
the code drops
into a comparison
to check the width
of the pulse. If the
pulse we just
measured is not a
valid sync pulse
(for example, we
started the code in
the middle of an
output stream),
jumps back to the top and tries again.
mov pwidth, #0
chwait test pmask, ina wz
if_z jmp #getch1
waitcnt timer, US_001
add pwidth, #1
cmp pwidth, #425 wc, wz
if_b jmp #chwait
jmp #vexin
As before, the pulse width variable is cleared and the
code drops into a small loop that tests the state of the
PPM line. When the line is idle, the Z flag will be cleared
and we drop through the first jump into a one
microsecond delay. The idle pulse width is incremented
and a comparison is done to ensure that we haven’t lost
■ FIGURE 7. Reading the PPM Stream.
■ FIGURE 6. PPM
Input Circuit.
September 2010 17