Loop not repeating correct number of times, help?
            
                            
                                  in Propeller 1             
        
                    Hello everyone,
I'm trying to fire a light five times. I thought this loop would do that but it only fires twice. Does anyone have any ideas why?
                
                            I'm trying to fire a light five times. I thought this loop would do that but it only fires twice. Does anyone have any ideas why?
                                                org          0
                                              
start                                         or        dira, light                                                               
                                                andn     outa, light               
                                                mov     Count,#5         
                                                
                                         
loop                                         or       outa, Pin                         'toggle light  on                                 
                                                andn     outa, Pin                     ' toggle light off
                                                djnz     Count, #loop

 
                            
Comments
Also, your loop will complete in microseconds. Are you using a scope to count the pulses?
Finally, there's nothing at the end to keep any random code that was loaded with yours from executing. You should either include an instruction that jumps to itself, or a cogstop to kill the cog.
-Phil
Where's your delay?
Where's "Count"?
Where's the rest of the code?
Why would you code this in PASM anyway?
-Phil
dat org 0 entry mov pmask, #1 ' create pin mask shl pmask, #LED mov dira, pmask ' set pin to output mode rdlong delaytix, #0 ' read system freq (tix/second) shr delaytix, #1 ' divide by 2 (1/2s delay) mov count, #CYCLES ' set number of flashes mov timeout, cnt ' start timer add timeout, delaytix loop or outa, pmask ' led on waitcnt timeout, delaytix andn outa, pmask ' led off waitcnt timeout, delaytix djnz count, #loop ' count down cogid cid ' shut down this cog cogstop cid ' cog vars pmask res 1 delaytix res 1 count res 1 timeout res 1 cid res 1org 0 start or dira, light ' configure pin to output andn outa, light ' set pin to input mov Counter, #5 ' counter for LED pulses loop or outa, Pin ' toggle pin on andn outa, Pin ' toggle pin off djnz Counter, #loop1 wz if_z cogstop ID light long %000000_0110000_00000000_00000000 Counter long 0 ID long 0 Pin long |<21If you have a Scope, and an almost-working system, you likely just need some fault analysis...
Change the #5 and see if the pulses change ?
Are the pulses you do get, of expected width & spacing ?
If you add another pin that sets just before the loop, and clears after DJNZ, what time does that take ?
[/quote]
BlinkCounter seems not declared, or loaded anywhere, whilst Counter is loaded but not used ?
If you have a Scope, and an almost-working system, you likely just need some fault analysis...
Change the #5 and see if the pulses change ?
Are the pulses you do get, of expected width & spacing ?
If you add another pin that sets just before the loop, and clears after DJNZ, what time does that take ?
[/quote]
Sorry it was supposed to be counter, if i change the amount of pulses, the firings are still coming up short of the number I want.
Ok that's a start, but short of you likely just need some fault analysis...
Tabulate the Count, and what you see. Is it always -3 ?
Did you add a start-end pin ?
If you trigger on that, what do you now see ?
How sure are you that the assembly routine is even being loaded into a cog?
start or dira, light ' configure pin to output andn outa, light ' set pins to input mov Counter,#5 ' Counter for LED pulses loop or outa, Pin ' turn on LED 1 mov Time, cnt add Time, Delay waitcnt Time, Delay ' wait for 0.5 seconds andn outa, Pin ' turn off LED 1 djnz Counter, #loop ' jump back to loop and decrease counter cogid ID cogstop ID light long %00000000_01100000_00000000_00000000 Counter long 0 ID long 0 Pin long |< 21 Delay long 40_000_000 Time res 1I'm getting two pulses instead of five. Is that what you mean by -3? And what do you mean by start-end pin?
Also, please post the entire program, including the Spin code that starts the PASM cog.
-Phil
If you are fixed on 2, then that tells you what you change and think is the counter, is not the real counter.
See above, this is a pin you set at the code before the loop, and clear after the loop completes.
This should pulse once, and give a scope trigger to see all the other pulses.
yes, or, you could toggle the pin, and use just one delay. The scope toggles should match the loop counter.
It is possible the scope has a trigger offset issue, so another separate way to check counting would help.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR byte datin[3], dp byte light1status, light2status, light3status, light4status word dtemp1, dout1, dtemp2, dout2, dtemp3, dout3, dtemp4, dout4 long Command long pulsecount long cog PUB main ' UM245R communication Lines dira[7..0] := %00000000 ' input byte form UM245R dira[8] := 0 'input, RXF dira[9] := 1 ' output, RD# dira[10] := 0 'input, TXE dira[11] := 1 ' output, WR# 'Digital output communication lines, SN74HC595 dira[12] := 1 ' output, clock dira[13] := 1 ' output, data line 1 dira[14] := 1 ' output, latch 1 dira[15] := 1 ' output, data line 2 dira[16] := 1 ' output, latch 2 dira[17] := 1 'output, data line 3 dira[18] := 1 'output, latch 3 dira[19] := 1 ' output, data line 4 dira[20] := 1 ' output, latch 4 dira[21] := 1 ' output, analog MUX 1 dira[22] := 1 ' output, analog MUX 2 dira[23] := 1 ' output, analog MUX 3 dira[24] := 1 ' output, analog MUX 4 dira[25] := 0 ' input, camera frame exposure signal outa[9] := 1 outa[11] := 0 outa[12] := 0 outa[13] := 0 outa[14] := 0 outa[15] := 0 outa[16] := 0 outa[17] := 0 outa[18] := 0 outa[19] := 0 outa[20] := 0 outa[21] := 0 outa[22] := 0 outa[23] := 0 outa[24] := 0 light1status := 0 light2status := 0 light3status := 0 light4status := 0 ' set 4 LED drive voltage outputs to 0 repeat 16 outa[12] := 1 ' clock it in outa[12] := 0 outa[14] := 1 ' latch it in outa[14] := 0 outa[16] := 1 ' latch it in outa[16] := 0 outa[18] := 1 ' latch it in outa[18] := 0 outa[20] := 1 ' latch it in outa[20] := 0 cog:= cognew(@RR, 0) + 1 repeat repeat dp from 0 to 2 repeat until ina[8]==0 outa[9] := 0 datin[dp] := ina[7..0] outa[9] := 1 'change lightlevel1 if datin[0]==2 dout1 := datin[1] + datin[2]*256 dtemp1 := dout1 repeat 12 if (dtemp1 & %0000100000000000)==%0000100000000000 outa[13] := 1 else outa[13] := 0 outa[12] := 1 ' clock it in outa[12] := 0 dtemp1 <<= 1 ' shift left 1 outa[14]:=1 'latch it in outa[14]:=0 ' turn on light1 elseif datin[0]==3 if light1status==0 outa[21] := 1 light1status := 1 elseif light1status==1 outa[21] := 0 light1status := 0 'change lightlevel2 elseif datin[0]==4 dout2 := datin[1] + datin[2]*256 dtemp2 := dout2 repeat 12 if (dtemp2 & %0000100000000000)==%0000100000000000 outa[15] := 1 else outa[15] := 0 outa[12] := 1 ' clock it in outa[12] := 0 dtemp2 <<= 1 ' shift left 1 outa[16]:=1 ' latch it in outa[16]:=0 ' turn on light2 elseif datin[0]==5 if light2status==0 outa[22] := 1 light2status := 1 elseif light2status==1 outa[22] := 0 light2status := 0 ' change lightlevel3 elseif datin[0]==6 dout3 := datin[1] + datin[2]*256 dtemp3 := dout3 repeat 12 if (dtemp3 & %0000100000000000)==%0000100000000000 outa[17] := 1 else outa[17] := 0 outa[12] := 1 ' clock it in outa[12] := 0 dtemp3 <<= 1 ' shift left 1 outa[18]:=1 ' latch it in outa[18]:=0 ' turn on light3 elseif datin[0]==7 if light3status==0 outa[23] := 1 light3status := 1 elseif light3status==1 outa[23] := 0 light3status := 0 ' change lightlevel4 elseif datin[0]==8 dout4 := datin[1] + datin[2]*256 dtemp4 := dout4 repeat 12 if (dtemp4 & %0000100000000000)==%0000100000000000 outa[19] := 1 else outa[19] := 0 outa[12] := 1 ' clock it in outa[12] := 0 dtemp4 <<= 1 ' shift left 1 outa[20]:=1 ' latch it in outa[20]:=0 ' turn on light4 ' elseif datin[0]==9 'if light4status==0 'outa[24] := 1 'light4status := 1 'elseif light4status==1 'outa[24] := 0 'light4status := 0 ' Run Light Pulsing (Round-Robbin) with Processor 2 elseif datin[0]==10 pulsecount := datin[1] + datin[2]*256 Command:=1 repeat until Command==0 elseif datin[0]==255 reboot DAT org 0 RR or dira, LEDS ' configure Pins as outputs (1) andn outa, LEDS ' set Pins to input state (0) mov BlinkCounter,#10 ' Set Blink counter loop1 or outa, Pin25 ' turn on camera or outa, Pin21 ' turn on LED 1 mov Time, cnt add Time, OnTime waitcnt Time, OnTime ' wait for ___ seconds andn outa, Pin25 ' turn off camera andn outa, Pin21 ' turn off LED 1 mov Time, cnt add Time, Delay waitcnt Time, Delay loop2 or outa, Pin25 ' turn on camera or outa, Pin22 ' turn on LED 2 mov Time, cnt add Time, OnTime waitcnt Time, OnTime ' wait for ___ seconds andn outa, Pin25 ' turn off camera andn outa, Pin22 ' turn off LED 2 mov Time, cnt add Time, Delay waitcnt Time, Delay loop3 or outa, Pin25 ' turn on camera or outa, Pin23 ' turn on LED 3 mov Time, cnt add Time, OnTime waitcnt Time, OnTime ' wait for ___ seconds andn outa, Pin25 ' turn off camera andn outa, Pin23 ' turn off LED 3 mov Time, cnt add Time, Delay waitcnt Time, Delay loop4 or outa, Pin25 ' turn on camera or outa, Pin24 ' turn on LED 4 mov Time, cnt add Time, OnTime waitcnt Time, OnTime ' wait for ___ seconds andn outa, Pin25 ' turn off camera andn outa, Pin24 mov Time, cnt add Time, Delay waitcnt Time, Delay djnz BlinkCounter, #loop1 wz cogid ID if_z cogstop ID LEDS long %00000011_11100000_00000000_00000000 BlinkCounter long 0 ID long 0 Pin21 long |< 21 Pin22 long |< 22 Pin23 long |< 23 Pin24 long |< 24 Pin25 long |< 25 OnTime long 40_000_000 Delay long 20_000_000 Time res 1 'System Counter WorkspaceGo back through starting with the top object and remove any code messing with any I/O that is not controlled by that cog (reading is not a problem, no mater how configured IIRC, all cogs can "see" the state of a pin at any time) do the same for all other cogs you are running. This one has gotten me a couple of times.
You still haven't posted the whole code. If we cannot recreate the issue, we can't do better than stare at the code you have
provided, which isn't where the problem is I suspect.
The djnz instruction works, trust me on that...
Yes, as usual posting the whole program allows the real issue to be quickly identified.
I always get a number less than the amount of pulses I set it for, but never the same amount. For example, if i set it to five, i would get three on the first, two on the second run, four on the third run.
How: Post your entire program -- not just the fragment that you think is problematic. Clearly, there is an issue beyond that else this would have been solved by now. I wrote a program in a couple minutes that worked exactly as you specify. Did you plug that fragment into your framework to see if it worked for you as it did for me?
Again... help us help you. Archive your program and attach it to a message.
Jon, can I amend the Jerry Maguire phrase to "no help us, no help yourself, no help at all"
It looks like you're reading three bytes from a UM245R USB to parallel FIFO module.
The 1st byte seems to be a command to either toggle a light on/off, set a new level, or blink a number of times.
The 2nd and 3rd bytes form a 16-bit word representing the light level or number of times to blink.
I suspect, as Frank Freedman said, that your Spin code and Pasm code are colliding. You start the Pasm code which sets each output high for 1/2 second, and moves on to the next after 1/4 second. While that is going on, your Spin code continues to read the UM245R, and if datin[0] equals 3, 5, 7, or 9 then the Spin code toggles one of the pins to output a high, which the Pasm code running in another cog is then unable to set low. If datin[0] ever equals 10, then your Spin code waits forever.
Remember: A pin is an output if any cog sets it to be an output; a pin is high if any cog that has it set to output also has it set high.
Simplest solution if you just want to see the pins toggle is to comment out everything underneath the cognew, or ensure some other way that the Spin code doesn't interfere with those pins.
Here's a cleaner, simple, version of your code (untested):
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 FIFO_l = 0 FIFO_h = 7 FIFO_RXF = 8 FIFO_RD = 9 FIFO_TXE = 10 FIFO_WR = 11 CLOCK = 12 DATA1 = 13 LATCH1 = 14 DATA2 = 15 LATCH2 = 16 DATA3 = 17 LATCH3 = 18 DATA4 = 19 LATCH4 = 20 MUX1 = 21 MUX2 = 22 MUX3 = 23 MUX4 = 24 CAMERA = 25 VAR long Command long pulsecount word dtemp1, dout1, dtemp2, dout2, dtemp3, dout3, dtemp4, dout4 byte datin[3], dp byte light1status, light2status, light3status, light4status byte cog PUB main ' UM245R communication Lines outa[FIFO_RD] := 1 dira[FIFO_RD] := 1 ' output, RD# dira[FIFO_WR] := 1 ' output, WR# ' Digital output communication lines, SN74HC595 dira[12..20]~~ ' set Clock, data lines and latches to output ' set 4 LED drive voltage outputs to 0 dira[21..24]~~ ' set analog muxs to output repeat 16 outa[CLOCK] := 1 ' clock it in outa[CLOCK] := 0 outa[LATCH1] := outa[LATCH2] := outa[LATCH3] := outa[LATCH4] := 1 outa[LATCH1] := outa[LATCH2] := outa[LATCH3] := outa[LATCH4] := 0 cog := cognew(@RR, 0) + 1 repeat repeat dp from 0 to 2 repeat until ina[FIFO_RXF] == 0 outa[FIFO_RD] := 0 datin[dp] := ina[FIFO_h..FIFO_l] outa[FIFO_RD] := 1 case datin[0] 2: dtemp1 := dout1 := datin[2] << 8 | datin[1] ' change lightlevel1 repeat 12 outa[DATA1] := dtemp1 & $800 outa[CLOCK] := 1 outa[CLOCK] := 0 dtemp1 <<= 1 outa[LATCH1] := 1 outa[LATCH1] := 0 3: outa[MUX1] := light1status := !light1status ' toggle light1status, set MUX1 to new status 4: dtemp2 := dout2 := datin[2] << 8 | datin[1] ' change lightlevel2 repeat 12 outa[DATA2] := dtemp2 & $800 outa[CLOCK] := 1 outa[CLOCK] := 0 dtemp2 <<= 1 outa[LATCH2] := 1 outa[LATCH2] := 0 5: outa[MUX2] := light2status := !light2status ' toggle light2status, set MUX2 to new status 6: dtemp3 := dout3 := datin[2] << 8 | datin[1] ' change lightlevel3 repeat 12 outa[DATA3] := dtemp2 & $800 outa[CLOCK] := 1 outa[CLOCK] := 0 dtemp3 <<= 1 outa[LATCH3] := 1 outa[LATCH3] := 0 7: outa[MUX3] := light3status := !light3status ' toggle light3status, set MUX3 to new status 8: dtemp4 := dout4 := datin[2] << 8 | datin[1] ' change lightlevel4 repeat 12 outa[DATA4] := dtemp2 & $800 outa[CLOCK] := 1 outa[CLOCK] := 0 dtemp4 <<= 1 outa[LATCH4] := 1 outa[LATCH4] := 0 9: outa[MUX4] := light4status := !light4status ' toggle light4status, set MUX4 to new status 10: pulsecount := datin[2] << 8 | datin[1] ' Run Light Pulsing (Round-Robbin) with Processor 2 command := 1 repeat until command == 0 255: reboot '======================================================================================= DAT org 0 RR or dira, LEDS ' configure Pins as outputs (1) andn outa, LEDS ' set Pins to input state (0) mov BlinkCounter,#10 ' Set Blink counter loop1 or outa, camera_mask ' turn on camera or outa, mux1_mask ' turn on LED 1 mov Time, OnTime add Time, cnt waitcnt Time, Delay ' wait for ___ seconds andn outa, camera_mask ' turn off camera andn outa, mux1_mask ' turn off LED 1 waitcnt Time, #0 ' wait delay loop2 or outa, camera_mask ' turn on camera or outa, mux2_mask ' turn on LED 2 mov Time, OnTime add Time, cnt waitcnt Time, Delay ' wait for ___ seconds andn outa, camera_mask ' turn off camera andn outa, mux2_mask ' turn off LED 2 waitcnt Time, #0 ' wait delay loop3 or outa, camera_mask ' turn on camera or outa, mux3_mask ' turn on LED 3 mov Time, OnTime add Time, cnt waitcnt Time, Delay ' wait for ___ seconds andn outa, camera_mask ' turn off camera andn outa, mux3_mask ' turn off LED 3 waitcnt Time, #0 loop4 or outa, camera_mask ' turn on camera or outa, mux4_mask ' turn on LED 4 mov Time, cnt add Time, OnTime waitcnt Time, Delay ' wait for ___ seconds andn outa, camera_mask ' turn off camera andn outa, mux4_mask waitcnt Time, #0 end djnz BlinkCounter, #loop1 cogid ID cogstop ID '======================================================================================= LEDS long |< MUX1 | |< MUX2 | |< MUX3 | |< MUX4 | |< CAMERA mux1_mask long |< MUX1 mux2_mask long |< MUX2 mux3_mask long |< MUX3 mux4_mask long |< MUX4 camera_mask long |< CAMERA OnTime long 40_000_000 Delay long 20_000_000 Time res 1 'System Counter Workspace BlinkCounter res 1 ID res 1Thanks for your help. I posted the full code on the 14th, I didn't know how to archive the program and attach it to a message, so I just posted it in code tags. I was able to figure it out and the solution is below.
Although, the pins are being shared on Spin and assembly, I am only firing the pins in assembly. The Spin code was there for troubleshooting. I didn't think it was a conflict between PASM and Spin because I imagine that issue would look like a value stays high for too long (LED stays on for multiple cycles), so if this were the issue, I would expect to have seen high values that stayed high for longer than the intended duration, not values heading low prematurely. Great idea though that really got me thinking!
I was able to fix the problem. The PASM was firing zero voltage pulses before the non-zero voltage values were set from the external source. I feel foolish for not noticing this sooner. The decrementing variable was working correctly. To fix this, I placed the cognew command after all the light levels were set. Thank you all again for your help.
Wow, Chris. I really appreciate the effort you put in. I was able to solve the problem (see above). Although, now I want to test your code to just to see if it works. Thanks again for your help and I'll update you a bit later.