ASM WAITPEQ help?
Steel
Posts: 313
Sorry for the questions...unfortunately, I am not completely confident in my coding skills and need to rely on support right now.
Below I have simple code that uses WAITPEQ in both ASM and SPIN.
When I run this program with the ASM WAITPEQ commented out (and running the SPIN WAITPEQ), it works fine.· When I run the program with the SPIN WAITPEQ commented out (and running the ASM WAITPEQ), the rest of the program does not run.
Just to understand the program, I am monitoring PIN1.· When PIN1 goes high, I toggle PIN4 high and low 5 times.
It works when I use WAITPEQ in SPIN, but it is not working when I use the WAITPEQ in ASM.
Any help would be greatly appreciated.
Shaun
con
· _clkmode = xtal1 + pll16x
· _xinfreq = 5_000_000
pub Toggle_Main
···
WAITPEQ(%1, %1,0)
cognew (@Toggle, 0)
dat
······················· org······ 0
Toggle
············· WAITPEQ·· %1, #%1·
············· mov···· Counter, #5
············· mov···· dira,·· #10·············· 'Set Pin to output
············· mov···· Time,·· cnt··············· 'Place the value of cnt into Time
············· add···· Time,·· #9
·························
············
:loop
············· waitcnt Time,·· Delay············· 'Set Pin high
············· xor···· outa,·· #10··············· 'Toggle Pin
············· waitcnt Time,·· Delay············· 'Set Pin Low
············· xor···· outa,·· #10·············· 'Toggle Pin
············· DJNZ··· Counter, #:loop
············· jmp······ #Done
·············
·Done
············· mov······ outa, #00
············· jmp······ #Done············
·············
·············
Pin···· long··········· $10
Delay·· long··········· 1_000_000
Time··················· res 1
Counter················ res 1
Below I have simple code that uses WAITPEQ in both ASM and SPIN.
When I run this program with the ASM WAITPEQ commented out (and running the SPIN WAITPEQ), it works fine.· When I run the program with the SPIN WAITPEQ commented out (and running the ASM WAITPEQ), the rest of the program does not run.
Just to understand the program, I am monitoring PIN1.· When PIN1 goes high, I toggle PIN4 high and low 5 times.
It works when I use WAITPEQ in SPIN, but it is not working when I use the WAITPEQ in ASM.
Any help would be greatly appreciated.
Shaun
con
· _clkmode = xtal1 + pll16x
· _xinfreq = 5_000_000
pub Toggle_Main
···
WAITPEQ(%1, %1,0)
cognew (@Toggle, 0)
dat
······················· org······ 0
Toggle
············· WAITPEQ·· %1, #%1·
············· mov···· Counter, #5
············· mov···· dira,·· #10·············· 'Set Pin to output
············· mov···· Time,·· cnt··············· 'Place the value of cnt into Time
············· add···· Time,·· #9
·························
············
:loop
············· waitcnt Time,·· Delay············· 'Set Pin high
············· xor···· outa,·· #10··············· 'Toggle Pin
············· waitcnt Time,·· Delay············· 'Set Pin Low
············· xor···· outa,·· #10·············· 'Toggle Pin
············· DJNZ··· Counter, #:loop
············· jmp······ #Done
·············
·Done
············· mov······ outa, #00
············· jmp······ #Done············
·············
·············
Pin···· long··········· $10
Delay·· long··········· 1_000_000
Time··················· res 1
Counter················ res 1
Comments
WAITPEQ #%1, #%1
As both are literals.
Graham
You can't have a literal value in the destination field. The %1 means memory location 1. The easiest way to do this is to have another location, like "PinMask long %1" and then use "WAITPEQ PinMask,PinMask".· This will cause the cog to pause until pin zero is a logic one.· If you want some other pin, change PinMask.
Even when I assign Pinmask as a long = %1, and put in the 'WAITPEQ PinMask, PinMask' it still doesn't function correctly.
I have verified that it works in SPIN, but for some reason it is not functioning in ASM...
The below code can be verified by putting an oscope on Pin4, and toggling pin1 from low to high...
_______________________________________________________________________
Toggle
mov Counter, #5
mov dira, #10 'Set Pin to output
mov Time, cnt 'Place the value of cnt into Time
add Time, #9 'Add 9 to time
WAITPEQ PinMask, PinMask
:loop
waitcnt Time, Delay 'Set Pin high
xor outa, #10 'Toggle Pin
waitcnt Time, Delay 'Set Pin Low
xor outa, #10 'Toggle Pin
DJNZ Counter, #:loop
jmp #Done
Done
mov outa, #00
jmp #Done
Delay long 1_000_000
PinMask long %1
Time res 1
Counter res 1
______________________________________________________________
The problem is that I am able to get WAITPEQ in Spin to work.· When I have it in spin, the output is correct (See first picture· -· Top trace is me changing the state of Pin0 from Low to High, bottom trace is monitoring the output pin.)
When I put....
·______________________________
······· WAITPEQ· pinmask, pinmask
········ ....output code here.....···
······· Pinmask·· long·· %1
· _____________________________
....I am not changing any of the output code...The only change is putting in the WAITPEQ command.· The output code never executes (output pin toggling 5 times) with the ASM WAITPEQ.· See second picture.· The only thing that I am changing is where the WAITPEQ is...SPIN vs ASM.
Post Edited (Steel) : 7/13/2007 4:12:23 PM GMT
Another complication is that separate cogs have their own DIRA and OUTA registers. They're OR'd together among cogs to set the actual state of the I/O pin. Your Spin code and the assembly routine run in different cogs, so this affects what you're seeing.
In any event, WAITPEQ works in assembly the same way it works in Spin. What would be the "port" parameter is ignored in both Spin and assembly and the mask and compare state values work the same way. The example I wrote waits until the I/O pins marked by the mask (PinMask) are all one bits. To work properly, the direction register has to have those pins set as inputs (direction bit == zero) and no other cog can have those pins set as outputs.
Try it this way:
WAITPEQ PinMask, PinMask
mov Time, cnt 'Place the value of cnt into Time
add Time, #9 'Add 9 to time
Andy
here's the code I've been working with, its a little messy, but I'll leave it so you maybe can get an idea of what I was tryin to do
http://forums.parallax.com/showthread.php?134454-Need-waitpeq-examples&p=1035440&viewfull=1#post1035440
I don't see how the Z flag is used at all in this routine.
baaaad!
1. Not a good idea to hijack the thread of someone else
2. The code you posted ..... brrrrr
You should not use direct addresses in your instructions. This is simply not maintainable code! You uncomment one line of code and have to shift all the direct addresses manually. If you constantly use labels the compiler takes care of that! If I counted right 18 is exactly where you placed the label diraval. Is this intended?
If I see it right you want to reuse a register after it's no longer needed, but you want to avoid using that label?!
Then you should know that you can set as many labels for one memory location as you want:
label1
label2
label3 long 1234
All 3 labels point to the same long! So, please use meaningfull labels also for the temporary registers - something like tmpcalc1
Mike,
The statement that "no other cog can have those pins set as outputs" is not entirely correct. In the attached bit of code, I am using a separate cog for timing generation. The cog using WAITPNE and WAITPEQ monitors the pin to determine when the chip select is high and then when the chip select has gone low to begin sampling on an MCP3201 ADC.
Better to say watch out for where you set pins to output highs on the cog executing the WAITPXX since logic highs rule in the ORed scheme of prop I/O. If a WAITPEQ is looking for a low (maskbit=0), it will wait until the pin goes low to continue and if the cog waiting set the pin high prior to the WAITPEQ running, it will wait forever as the pins are now permanently unequal and there is no way to clear the pin to low. For WAITPNE, if the test is set to look for a high bit (maskbit=1), if the pin is low, passes through, but if the input gets set high on the pin in question prior to the WAITPNE executing, again the cog will wait forever since now they are always equal.
As I understand it and it worked for me,
Frank
Ohhhh, that's a good point. SHpin is timer B's pin, which I literally have a wire looping from it to SHsensePin, Its 50% duty @ ~10 microsecond period
Is that a rule here? This is a 5 year old thread, how am I hijacking anything? If you would have posted this question to a new thread, would you have told me to "try using the forum search before asking questions"?
Its just keeping information aggregated, google already has this page linked in their database, people may have quoted this page on blogs, code, etc...
Hmm, no, that wasn't intended. I didn't know those longs were in registers... are they really? Why isn't that on the stack? (or doesn't the propeller work like that!???)
good to know, thanks.
yeah... I'm just learning Assembly for the first time because I want to use the propeller (I don't know spin either, though I'm getting familiar with the function and register vocabulary, etc..
Its not C!
"... would you have told me to "try using the forum search before asking questions"? ... My feeling is that nobody here would have said something like this! There are a lot of questions that come again and again and I can't remember a thread where someone has been blamed for not using the forum search - at least not in the same way as they do this in other forums. Most propable reaction would be to answer the thread pointing you the other thread where this question has been asked before.
The propeller does not have registers like other microprocessor designs. The propeller only has COG-RAM! Each COG-RAM can be anyting, a variable that contains a value, a variable that contains a pointer inside COG-RAM, a variable that contains a pointer to HUB-RAM ... you can do calculations with each COG-RAM long ...
In other words all the COG-RAM that is not occupied by code can be used as a register for storing whatever you need to store.
mov x,y
long 10
both will occupy one long in the COG-RAM in the order you use them in your program.
A technique I often use is to have an initialization-routine which by nature only runs once and then I reuse those COG-RAM positions for doing temporal calculations or for keeping loop-counters .... And then it makes sense to use the multi-label feature to write readable, self-explanatory code. For example:
"good to know, thanks." - you're welcome!