What are the values of Pin and light, and where are they defined? Can you post your entire program, please?
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
Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
Light goes on for 50 billionths of a second and then light goes off. Seriously?
Where's your delay?
Where's "Count"?
Where's the rest of the code?
Why would you code this in PASM anyway?
You're not revealing all of your code so there's no way to tell if you have problems beyond -- as Peter points out -- the output is being toggled so fast you'd need to have a 'scope on it to see the changes. Here's one that works with an LED. I ran it on a PAB. The LED and CYCLES constants are defined in the top part of the program, before the cognew(@entry, 0) call.
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 1
Jon McPhalen
Hollywood, CA
It's Jon or JonnyMac -- please do not call me Jonny.
Thank you for your responses. I am using a oscilloscope and even when I added 0.5 sec delays I got fewer pulses then expected.
org 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 |<21
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 am using a oscilloscope and even when I added 0.5 sec delays I got fewer pulses then expected.
djnz BlinkCounter, #loop1 wz
Counter long 0
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]
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.
And presumably the djnz Counter,#loop1 jumps to loop? And you've got a cogID ID in there so the cogstop knows what to stop? People around here are generally quite willing to help, but it does require you post the entire, actual code.
How sure are you that the assembly routine is even being loaded into a cog?
Sorry for not posting the whole code. I thought it would just complicate the question. I appreciate the help.
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 1
Sorry for not posting the whole code. I thought it would just complicate the question. I appreciate the help.
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 1
I think you need to put another delay after you turn off the LED. Otherwise, it just loops around and turns it back on immediately so you won't see the blink.
You have a half-second delay now between on and off, but none between off and back on again. So you're still not going to "see" any pulses without a scope.
Also, please post the entire program, including the Spin code that starts the PASM cog.
-Phil
Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
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.
I think you need to put another delay after you turn off the LED. Otherwise, it just loops around and turns it back on immediately so you won't see the blink.
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.
Ya gotta remember that all cogs have access to the I/O pins. If the last posted code was current, it looks like you have cogs overlapping each other in the pin functions. And unlike TTL logic, highs rule in these outputs; each cog access to an I/O pin is an OR logic function so if any one cog says output, it's output. And if any cog on that pin has said it's an output and asserts a high, that cog rules and the pin will be output high.
Go 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.
Ordnung ist das halbe Leben
I gave up on that half long ago.........
Sorry for not posting the whole code. I thought it would just complicate the question. I appreciate the help.
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.
Mark_T, it looks like dayoade did post all of his code in his last post. I believe Frank is correct that the Spin cog and the Pasm cog are driving some of the same pins. The Spin code contains the following lines:
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
and the Pasm code contains
RR or dira, LEDS ' configure Pins as outputs (1)
...
LEDS long %00000011_11100000_00000000_00000000
So both cogs are driving ins 21 to 24. If one of the cogs writes a 1 to the output pin the other cog will have no control on that pin. The LED should be moved to separate pins, or the cogs need to coordinate their outputs on each common pin so they are fighting against each other.
I'm getting two pulses instead of five. Is that what you mean by -3?
Do you always get 2, no matter if you preset 5,7,13 etc ?
If you are fixed on 2, then that tells you what you change and think is the counter, is not the real counter.
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.
This thread has shown there are people willing to help you -- if you'll let them. I live in Hollywood and work around the movie business, so I'm going to paraphrase Jerry Maguire from the movie of that name: Help us help you.
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 McPhalen
Hollywood, CA
It's Jon or JonnyMac -- please do not call me Jonny.
ahem - I have learned to avoid responding to these problems that are described so vaguely as clearly the OP can't be bothered describing anything in detail or posting the code in detail, or how the test was performed and measured, or whether he tried the suggestions etc. Perhaps he is too busy on social media to type more than one line each time and paste some code while awaiting a complete solution.
Jon, can I amend the Jerry Maguire phrase to "no help us, no help yourself, no help at all"
While it's not the full version of the test code, it looks like the complete version of the code that the test code was derived from. It's clearly not the easiest to read, but I enjoy puzzles and managed to unscramble it enough to make sense of it.
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 1
ChrisGadd, I don't have near the hours on this chip that the heaters, JonnyMac and others have, but I also like the challenge. Makes me learn more. Also sorta habitual from my past with 16 years as a tech trainer. Even get em right occasionally. But the OP would do well to pull the latest copy of GEAR, and experiment with it. It seems to do a good job of simulation. And maybe use Dr. Anandakrishnan's TDD concept to incrementally coding the stages of his project to be able to tell when his latest addition has stepped on what may have worked before.
Ordnung ist das halbe Leben
I gave up on that half long ago.........
This thread has shown there are people willing to help you -- if you'll let them. I live in Hollywood and work around the movie business, so I'm going to paraphrase Jerry Maguire from the movie of that name: Help us help you.
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.
Thanks 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.
Ya gotta remember that all cogs have access to the I/O pins. If the last posted code was current, it looks like you have cogs overlapping each other in the pin functions. And unlike TTL logic, highs rule in these outputs; each cog access to an I/O pin is an OR logic function so if any one cog says output, it's output. And if any cog on that pin has said it's an output and asserts a high, that cog rules and the pin will be output high.
Go 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.
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.
While it's not the full version of the test code, it looks like the complete version of the code that the test code was derived from. It's clearly not the easiest to read, but I enjoy puzzles and managed to unscramble it enough to make sense of it.
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)
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.
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?
Tachyon Forth - compact, fast, forthwright and interactive
P2 --- The LOT --- TAQOZ INTRO & LINKS --- P2 SHORTFORM DATASHEET --- TAQOZ RELOADED - 64kB binary with room to spare
P1 --- Latest Tachyon with EASYFILE --- Tachyon Forth News Blog --- More
Brisbane, Australia
-Phil
Hollywood, CA
It's Jon or JonnyMac -- please do not call me Jonny.
If the grass is greener on the other side...it's time to water your lawn.
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]
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?
Hollywood, CA
It's Jon or JonnyMac -- please do not call me Jonny.
I'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.
Go 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.
I gave up on that half long ago.........
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.
Hollywood, CA
It's Jon or JonnyMac -- please do not call me Jonny.
Jon, can I amend the Jerry Maguire phrase to "no help us, no help yourself, no help at all"
Tachyon Forth - compact, fast, forthwright and interactive
P2 --- The LOT --- TAQOZ INTRO & LINKS --- P2 SHORTFORM DATASHEET --- TAQOZ RELOADED - 64kB binary with room to spare
P1 --- Latest Tachyon with EASYFILE --- Tachyon Forth News Blog --- More
Brisbane, Australia
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):
I gave up on that half long ago.........
Thanks 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.