Propagate pulse signal
Hi,
I'm trying to generate a pulse after a delayed time based on an input pulse. Say pin0 is my trigger, and then after 10k counts set pin1 on for 1000 counts, then after 10_000 more counts set pin2 and then set pin3.
I'm trying to do this inside of a loop that generates a quadrature signal on pins 16 through 19.
here is my code
This is not working. I'll appreciate any help
Thanks.
I'm trying to generate a pulse after a delayed time based on an input pulse. Say pin0 is my trigger, and then after 10k counts set pin1 on for 1000 counts, then after 10_000 more counts set pin2 and then set pin3.
I'm trying to do this inside of a loop that generates a quadrature signal on pins 16 through 19.
here is my code
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
VAR
long pause_counts
byte quad_cog
PUB start
stop
set_Hz(82_250)
quad_cog := cognew( @quad_entry, @pause_counts ) + 1
PUB stop
if quad_cog
cogstop( quad_cog~ - 1 )
PUB set_Hz( Hz )
' the update rate is 4x faster than the frequency
pause_counts := ((clkfreq >> 2) + (Hz>>1) ) / Hz
'pause_counts:= clkfreq / Hz
DAT
ORG 0 'Begin at Cog RAM addr 0
{{
This will be run in its own cog, meaning:
- we need our own copy of dira
- we get our own copy of outa
- I need to get the frequency info from the Hub RAM
(address is in the PAR register)
}}
quad_entry
mov quadvalue, all_quad_vals_twice
' mov outa,all_quad_vals_twice
mov dira, pin_mask
add dira, out_mask
add dira, ledout
mov outputcount, #0
mov timestamp,#511
add timestamp,cnt
loop_forever
mov triggerled, #0
mov mytrigger, ina 'Get input all at a time
and mytrigger, #1 'Mask only pin one
mov triggerled, mytrigger
cmp mytrigger, #1 wz 'if triggered reset counter
if_z mov outputcount, #0
add outputcount, #1 'Add to counter
mov MYKoutput, #0
'
cmp waitM, outputcount wc
if_c jmp labelMag 'Magenta
labelretMag
cmp waitY, outputcount wc
if_c jmp labelYel 'Yellow
labelretYel
cmp waitK, outputcount wc
if_c jmp labelBlk 'Black
labelretBlack
rdlong delay_counts,par
waitcnt timestamp, delay_counts
ror quadvalue,#4 'rotate quadrature output
mov outavalue, quadvalue
shr outavalue, #7 'make blanks for first 7 pins
shl outavalue, #7
shl triggerled, #22
add outavalue, triggerled
add outavalue, MYKoutput
mov outa, outavalue
jmp #loop_forever
labelMag
cmp outputcount, waitM100 wc
if_c mov MYKoutput, #%1100010
jmp #labelretMag
labelYel
cmp outputcount, waitY100 wc
if_c mov MYKoutput, #%1010100
jmp #labelretYel
labelBlk
cmp outputcount, waitK100 wc
if_c mov MYKoutput, #%0111000
jmp #labelretBlack
{===== PASM constants and parameters =====}
pin_mask long %1111 << 16
out_mask long %1111110
all_quad_vals_twice long %1001_0101_0110_1010____1001_0101_0110_1010
Delay long 12_000_000
waitM long 10_408
waitM100 long 11_508
waitY long 20_816
waitY100 long 21_916
waitK long 31_224
waitK100 long 32_324
ledout long %1 << 22
{===== PASM scratch variables =====}
' Remember, all RES variables _MUST_ come after all LONG variables
delay_counts res 1
timestamp res 1
quadvalue res 1
outavalue res 1
MYKoutput res 1
outputcount res 1
mytrigger res 1
triggerled res 1
' make sure this whole thing fits inside a single cog
FIT 496
This is not working. I'll appreciate any help
Thanks.

Comments
You could use a WAITPNE to wait for the trigger on pin 0, then a WAITCNT to wait for the 10K system clocks to go by, turn on pin 1, use a WAITCNT to wait for the 1K system clocks, turn off pin 1, use WAITCNT to wait for another 10K system clocks, then turn on pins 2 and 3, then use WAITPEQ to make sure the trigger is turned off and go back to wait for a new trigger. We're talking about maybe 15-20 instructions here. It's simple and straightforward.
That sounds good, the thing is that the counts are not propeller chip counts, but counts of my quadrature signal that I'm generating based on a specific frequency. That is why I am placing the code inside of the loop that generates these counts. So these 10k counts are not necessarily the system counts.
This is a perfect application example for using the PropRTOS I entered in the Prop contest. Take a read through that, and on understanding it, I can then help you get this going very easily.
Cheers,
Peter (pjv)
You'd have a JMPRET in your quadrature counting code (JMPRET saveLoc,nextLoc). "saveLoc" is an uninitialized long variable in the cog. "nextLoc" is another long variable initialized to the address of the beginning of your pulse handling routine.
handler jmpret nextLoc,saveLoc ' return to quadrature code test pin0Mask,ina wc if_nc jmp #handler ' wait for pin 0 to go high mov counter,const10000 nextLp1 jmpret nextLoc,saveLoc djnz counter,nextLp1 ' wait for 10000 counts or outa,#%0010 ' turn on pin 1 mov counter,const1000 nextLp2 jmpret nextLoc,saveLoc djnz counter,nextLp2 ' wait for 1000 counts andn outa,#%0010 ' turn off pin 1 mov counter,const10000 nextLp3 jmpret nextLoc,saveLoc djnz counter,nextLp3 ' wait for 10000 counts or outa,#%1100 ' turn on pins 2 and 3 nextLp4 jmpret nextLoc,saveLoc test pin0Mask,ina wc if_c jmp #nextLp4 ' wait for pin 0 to go low andn outa,#%1100 ' turn off pins 2 and 3 jmp #handler ' start all over againThis will need some initialization in the main routine, but you should get the idea.
Here's the code:
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long pause_counts byte quad_cog PUB start stop set_Hz(36_696) quad_cog := cognew( @quad_entry, @pause_counts ) + 1 PUB stop if quad_cog cogstop( quad_cog~ - 1 ) PUB set_Hz( Hz ) ' the update rate is 4x faster than the frequency pause_counts := ((clkfreq >> 2) + (Hz>>1) ) / Hz 'pause_counts:= clkfreq / Hz DAT ORG 0 'Begin at Cog RAM addr 0 {{ This will be run in its own cog, meaning: - we need our own copy of dira - we get our own copy of outa - I need to get the frequency info from the Hub RAM (address is in the PAR register) }} quad_entry mov outa,all_quad_vals_twice mov outmask, pin_mask or outmask, #%1111110 mov dira,outmask mov timestamp,#511 add timestamp,cnt mov quadvalue, all_quad_vals_twice loop_forever nextLoc mov outMYK, #%0000000 rdlong delay_counts,par waitcnt timestamp, delay_counts rol quadvalue,#4 mov outvalue, quadvalue or outvalue, outMYK mov outa, outvalue jmp #loop_forever handler jmpret nextLoc,saveLoc ' return to quadrature code test pin0Mask,ina wc if_nc jmp #handler ' wait for pin 0 to go high mov counter,const10000 nextLp1 jmpret nextLoc,saveLoc djnz counter,nextLp1 ' wait for 10000 counts or outMYK,#%1100010 ' turn on pin 1 mov counter,const1000 nextLp2 jmpret nextLoc,saveLoc djnz counter,nextLp2 ' wait for 1000 counts andn outMYK,#%1100010 ' turn off pin 1 mov counter,const10000 nextLp3 jmpret nextLoc,saveLoc djnz counter,nextLp3 ' wait for 10000 counts or outMYK,#%0011100 ' turn on pins 2 and 3 nextLp4 jmpret nextLoc,saveLoc test pin0Mask,ina wc if_c jmp #nextLp4 ' wait for pin 0 to go low andn outMYK,#%0011100 ' turn off pins 2 and 3 jmp #handler ' start all over again {===== PASM constants and parameters =====} pin_mask long %1111 << 16 all_quad_vals_twice long %1001_0101_0110_1010____1001_0101_0110_1010 Delay long 12_000_000 pin0Mask long %0001 const1000 long 1000 const10000 long 10_000 {===== PASM scratch variables =====} ' Remember, all RES variables _MUST_ come after all LONG variables delay_counts res 1 timestamp res 1 saveLoc res 1 counter res 1 quadvalue res 1 outvalue res 1 outmask res 1 outMYK res 1 ' make sure this whole thing fits inside a single cog FIT 496Thanks for your help.
You also need a "JMPRET saveLoc,nextLoc" somewhere in your quadrature counting code. Reread the 2nd paragraph in my earlier message.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long pause_counts byte quad_cog PUB start stop set_Hz(36_696) quad_cog := cognew( @quad_entry, @pause_counts ) + 1 PUB stop if quad_cog cogstop( quad_cog~ - 1 ) PUB set_Hz( Hz ) ' the update rate is 4x faster than the frequency pause_counts := ((clkfreq >> 2) + (Hz>>1) ) / Hz 'pause_counts:= clkfreq / Hz DAT ORG 0 'Begin at Cog RAM addr 0 {{ This will be run in its own cog, meaning: - we need our own copy of dira - we get our own copy of outa - I need to get the frequency info from the Hub RAM (address is in the PAR register) }} quad_entry mov outa,all_quad_vals_twice mov outmask, pin_mask or outmask, #%1111110 mov dira,outmask mov timestamp,#511 add timestamp,cnt mov quadvalue, all_quad_vals_twice loop_forever mov outMYK, #%111111 mov nextLoc, #handler jmpret saveLoc, nextLoc rdlong delay_counts,par waitcnt timestamp, delay_counts rol quadvalue,#4 mov outvalue, quadvalue or outvalue, outMYK mov outa, outvalue jmp #loop_forever handler jmpret nextLoc,saveLoc ' return to quadrature code test pin0Mask,ina wc if_c jmp #handler ' wait for pin 0 to go high mov counter,const10000 nextLp1 jmpret nextLoc,saveLoc djnz counter,nextLp1 ' wait for 10000 counts or outMYK,#%1100010 ' turn on pin 1 mov counter,const1000 nextLp2 jmpret nextLoc,saveLoc djnz counter,nextLp2 ' wait for 1000 counts andn outMYK,#%1100010 ' turn off pin 1 mov counter,const10000 nextLp3 jmpret nextLoc,saveLoc djnz counter,nextLp3 ' wait for 10000 counts or outMYK,#%0011100 ' turn on pins 2 and 3 nextLp4 jmpret nextLoc,saveLoc test pin0Mask,ina wc if_nc jmp #nextLp4 ' wait for pin 0 to go low andn outMYK,#%0011100 ' turn off pins 2 and 3 jmp #handler ' start all over again {===== PASM constants and parameters =====} pin_mask long %1111 << 16 all_quad_vals_twice long %1001_0101_0110_1010____1001_0101_0110_1010 Delay long 12_000_000 pin0Mask long %0001 const1000 long 1000 const10000 long 10_000 {===== PASM scratch variables =====} ' Remember, all RES variables _MUST_ come after all LONG variables delay_counts res 1 timestamp res 1 saveLoc res 1 nextLoc res 1 counter res 1 quadvalue res 1 outvalue res 1 outmask res 1 outMYK res 1 ' make sure this whole thing fits inside a single cog FIT 496I also tried creating another file with just waitcnt, but I can't get it to run with the following sintax
waitcnt (<countstowait> * clkfreq / <frequency> + cnt) this doesn't wait, here is my code:
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long pause_counts long waitcount byte mycogID PUB start stop setHz(45_250) mycogID := cognew( checkpins,0) PUB stop if mycogID cogstop( mycogID~ - 1 ) PUB setHz(Hz) pause_counts := Hz waitcount := clkfreq / (2 ) checkpins PRI checkpins | camming, Time DIRA := %111_0000000000000_111_111_0' << 20 outa := %000000 Time := cnt repeat if ina[noparse][[/noparse]0]==0 camming := 0 waitpne(%0000, %0001, 0) if ina[noparse][[/noparse]0]==1 AND camming == 0 sendcam camming := 1 PRI sendcam outa:=1 outa:=1 outa:=1 outa:=0 outa:=0 outa[noparse][[/noparse]6]:=0 'Time := Time + 10808 * clkfreq / pause_counts waitcnt(10_708 * clkfreq / pause_counts + cnt) waitcnt(10_708 * clkfreq / pause_counts + cnt) outa[noparse][[/noparse]20]:=0 outa:= 1 outa:= 0 waitcnt(clkfreq / 5 + cnt) outa[noparse][[/noparse]20]:=1 outa:=0 outa:=1 waitcnt(10_708* clkfreq / pause_counts + cnt) waitcnt(10_708 * clkfreq / pause_counts + cnt) outa[noparse][[/noparse]21]:=0 outa:=1 outa:=0 waitcnt(clkfreq / 5 + cnt) outa[noparse][[/noparse]21]:=1 outa:=0 outa:=1 waitcnt(10_708 * clkfreq / pause_counts + cnt) waitcnt(10_708 * clkfreq / pause_counts + cnt) outa[noparse][[/noparse]22]:=0 outa[noparse][[/noparse]6]:=1 outa:=0 waitcnt(clkfreq / 5 + cnt) outa[noparse][[/noparse]22]:=1 outa[noparse][[/noparse]6]:=0 outa:=1 'waitpeq(%0000, %0001, 0)Thanks for any help.
Please take a little time to try to understand what this code does. I know that JMPRET is an unusual instruction for most people, particularly when used this way, but it will be worth your time to try to understand what's going on here.
The problem you're running into with CLKFREQ is overflow during the multiplication. 10_000 * CLKFREQ is much larger than 32 bits. You may need parentheses like: 10808 * (clkfreq / pause_counts)