WAITPEQ questions [ WAITPEQ now working ]
Chip Gracey would know, and some others should be able to explain what's happening internally during a Propeller instruction.
1. For the WAITPEQ instruction, does any document explain the operations during each of the '5+' system clocks (version 1.0 manual)??
2. And, does this imply that every 5 clocks these operations REPEAT??
ViewPort indicates proper values on the I/O lines, yet my use of WAITPEQ doesn't work. Just hangs (the 'pause'?), never a match. Works for single-bit compares, but not for multiple bits.
Wonder what I'm doing wrong?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Post Edited (Harley) : 6/20/2009 12:07:33 AM GMT
1. For the WAITPEQ instruction, does any document explain the operations during each of the '5+' system clocks (version 1.0 manual)??
2. And, does this imply that every 5 clocks these operations REPEAT??
ViewPort indicates proper values on the I/O lines, yet my use of WAITPEQ doesn't work. Just hangs (the 'pause'?), never a match. Works for single-bit compares, but not for multiple bits.
Wonder what I'm doing wrong?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Post Edited (Harley) : 6/20/2009 12:07:33 AM GMT
Comments
Can you post your code?
BTW, the 5+ means that if the condition is already met when the instruction executes, it takes five clocks. Beyond that one clock is added for however long it takes to get a match. So the granularity is one clock, not five.
-Phil
how should we say what you are doing wrong without seeing a single line of code ?
If the foum-members shall be able to give an answer you have to prive detailed information about your code
best thing is to attache your complete code and add a comment to the lines of code where the waitpeq does not work
best regards
Stefan
BAbusRd andn OUTA,INTR1msk ' set A21/pin 26 to LO level or DIRA,INTR1msk ' set /INTR pin to output wrlong zed0,PAR ' ensure PAR clear on entry ??? andn DIRA,BAbusMask or DIRA,TestMsk2 ' also set A20/pin 25 to Output andn OUTA,TestMsk2 ' and LO level :loop 'xor OUTA,TestMsk2 ' added for visual view in VP andn OUTA,TestMsk2 rdlong BAcomp,PAR wz ' test if valid BP + BM1 value (noon-zero) if_z jmp #:loop ' wasn't, continue to loop or OUTA,TestMsk2 ' TEMP test use nop ' stretch for viewing; ViewPort cannot display events during nop ' first several hundred nanoseconds after trigger nop nop ' 8 x 50 nsec/ = 400 nsec HI nop nop nop waitpne BM1mask,BM1mask ' wait for BM1 at LO level andn OUTA,TestMsk2 waitpeq BM1mask,BM1mask ' wait for BM1 at hi level or OUTA,TestMsk2 ' set HI A20/pin 25 (VP pos sync) ' nop ' 2* x 50 nsec/ = 100* nsec HI ???? [img]http://forums.parallax.com/images/smilies/tongue.gif[/img]eqWait xor OUTA,TestMsk2 ' added for visual view in VP mov INAtemp,INA ' get, and INAtemp,BAbusMask ' mask, xor INAtemp,BAcomp wz,nr ' and compare if_nz jmp #[img]http://forums.parallax.com/images/smilies/tongue.gif[/img]eqWait ' I TRIED TO MAKE A WAITPEQ TYPE INSTRUCTION HERE ' waitpeq BAcomp,BAbusMask ' wait for breakpoint match andn OUTA,TestMsk2 ' TEST or OUTA,TestMsk2 ' TEMP ' ' or OUTA,INTR1msk ' output pos. pulse on A21/pin 26 to Pod wrlong zed0,PAR ' clear PAR after a BP event ' andn OUTA,INTR1msk ' return to LO level andn OUTA,TestMsk2 ' TEMP jmp #:loop ' loop forever ' PASM instructions take 4 system clocks, except RDLONG, WRLONG (7..22) and WAITPEQ (6+) ' Initialized data for 'BAbusRd' BM1mask long |<16 ' mask for BM1 (A16) event $0001_0000 'BAbusMask long $0001_FFFF ' BM1 + 16 Z80 addr bits mask BAbusMask long $0001_001F ' BM1 + 16 Z80 addr bits mask TEST TestMsk2 long |<20 ' temp VP 'marker for this cog TEST INTR1msk long |<21 ' mask for 'INTR' on A21/pin 26 zed0 long 0 ' to clear a 32-bit register (PAR) ' Unitialized data for 'BAbusRd' BAcomp RES 1 ' SBPt 'breakpoint' value to compare w/BAbus value INAtemp res 1
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
That's what I'd expect, except I've yet to get WAITPEQ to work with other than a single bit compare. Not what's needed, for sure. I have 3 cogs in two Props that I've been hoping to get operational, but this one instruction has been a terrible struggle.
Thanks for the opinion, Mike.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Btw, I also never got multiple bit match to work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Visit the home of pPropQL: propeller.wikispaces.com/pPropQL
pPropQL020: propeller.wikispaces.com/pPropQL
OMU for the pPropQL/020 propeller.wikispaces.com/OMU
I wasn't too concerned whether it was 5 or 6 clock times, though closer to 0 clocks would be desirable, of course, as I'm trying to replace some TTL functions in firmware.
Good (really BAD!!!) to hear that others have had problems with multiple bit matching. There must be some sort of unwritten 'trick' for this instruction to work properly. I wish Chip & company would provide a good example of how to really use this neat instruction, exactly what I need. hint, hint.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Rereading your comment, if the first 4 clocks are involved with setting up the condition, how does the instruction take into account the following INx values if the first doesn't match? It seems it would have to at least again read INx and mask it to compare with a desired match, no?
It seems it has to evaluate the INx value over and over each time, not just the first INx value seen on entry to WAITPEQ
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
-Phil
From Chip's comment, it appears that the whole sequence would have to repeat to get Mask anded with INx, then State compared against that result which would change over and over, else is a static INx state. So internally it would have to appear to 'jump' back to Chips step 0) from 3) if no match, thus my program always hanging up in the WAITPEQ instruction. Or am I understanding what has to be happening?
I sure would like to get this one pesky, but valuable instruction operational.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Are you sure that the value being read into BAcomp is long-aligned in the hub? If it's declared as a word, it might not be. Moreover, even it it is a long-aligned word, you'll be getting extra garbage in the 16 msbs.
Don't forget the the two lsbs of par are always zero.
-Phil
BAcomp is long aligned. I've used PASD to single-step through this cog many, many times to ensure such items are proper. And PAR contains the proper value. That is what gets me; seems everything is proper, but wish there were a way to 'peek inside' WAITPEQ and see what's not right.
Unless this cog's code, listed above several messages, has a subtle error, it seems it should work OK. I'm not giving up as I'm certain there are some who DO have working WAITPEQ. Hanno's ViewPort makes use of it, for one.
Thanks for providing some ideas and clues, Phil.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
If you do not get anywhere, I posted code about a year ago that scans and stores the 32 I/O pins each clock cycle - uses 4 cogs interleaved. I think Jazzed Propalyzer may now do a better job. The link is in his signature.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, SixBladeProp, website (Multiple propeller pcbs)
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
-Phil
Bit 16 is a 'strobe' for the lower 16 bits, 0000...FFFF, and the compare value is the result of a 0000..FFFF value ORed with a bit 16 ONE before passing it into this cog. So only when bit 16 is a ONE is it a valid time to compare. I've read the WAITPEQ asm instruction a jillion times and still cannot understand why it doesn't seem to want to work with multiple bits. I thought maybe it was an endian problem, but looking with PASD it all looks proper. So why doesn't it work. I'm losing hair over this dilemna. I'm at the age when baldness is acceptable, but don't want to go that way.
I read the messages in your 'WAITPEQ Timing, Setup & Hold Times, etc.' posting. Interesting, but was hoping for some 'light' on my problem.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Post Edited (Harley) : 6/18/2009 4:50:28 PM GMT
Harley, what are some typical values for BAcomp that are causing trouble?
-Phil
Right now the hardware test circuit is only running in a loop from 0004h .. 0014h. That was why I had a 'test' mask of 0001_001F. Full mask is 0001_FFFF.
But unless BAcomp is 0001_0000, no comparison occurs. That single bit only operation.
1. I wonder what the purpose of the Z-flag is using WAITPEQ? Seems this would occur if 'pause' state on exit the istruction had the Statebits of Zeros corresponding to ONEs of Mask bits. A known state, any way, prior to entry of the WAITPEQ
2. From all comments, it appears all the hardware exists to do a comparison of State and Mask ANDed INx each clock cycle in/during the pause state. True? Cool, if so.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
1. 'Seems like it would always exit with Z set if wz was specified, since the compare has to be "equal" at that point.
2. Yes.
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 6/18/2009 8:35:39 PM GMT
Yes, this is a buffered Z80 M1 signal (BM1), so when valid (= ONE) is when the address of an instruction is valid.
Strange how Hanno's ViewPort can capture and display all these lines and validate the actual addressing on the lower 16 lines.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
-Phil
I've removed (hopefully) all my 'test' code so this should be easier on the eyes/mind. Why might this hang at the WAITPEQ?
BAcomp is a 16 bit value ORed with bit 16 a ONE. The ':loop' waits for a 0001_0000 .. 0001_FFFF value to be passed from SPIN. Then the 'fun' should begin; that is a match should occur. With this Mask only 0001_0000 .. 0001_001F are monitored for testing.
What am I not doing right? ViewPort sees the correct values on the lower 17 lines!!
BAbusRd andn OUTA,INTR1msk ' set A21/pin 26 to LO level or DIRA,INTR1msk ' set /INTR pin to output wrlong zed0,PAR ' ensure PAR clear on entry ??? andn DIRA,BAbusMask :loop 'xor OUTA,TestMsk2 ' added for visual view in VP andn OUTA,TestMsk2 rdlong BAcomp,PAR wz ' test if valid BP + BM1 value (noon-zero) if_z jmp #:loop ' wasn't, continue to loop waitpeq BAcomp,BAbusMask ' wait for breakpoint match ' ' or OUTA,INTR1msk ' output pos. pulse on A21/pin 26 to Pod wrlong zed0,PAR ' clear PAR after a BP event ' andn OUTA,INTR1msk ' return to LO level jmp #:loop ' loop forever ' PASM instructions take 4 system clocks, except RDLONG, WRLONG (7..22) and WAITPEQ (6+) ' Initialized data for 'BAbusRd' BM1mask long |<16 ' mask for BM1 (A16) event $0001_0000 'BAbusMask long $0001_FFFF ' BM1 + 16 Z80 addr bits mask BAbusMask long $0001_001F ' BM1 + 16 Z80 addr bits mask TEST INTR1msk long |<21 ' mask for 'INTR' on A21/pin 26 zed0 long 0 ' to clear a 32-bit register (PAR) ' Unitialized data for 'BAbusRd' BAcomp RES 1 ' SBPt 'breakpoint' value to compare w/BAbus value
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
Can you show us the program that feeds values, via par, to the code you've posted above?
-Phil
I thought I mentioned the range of EPROM values, the lower 16 bits; they are 0004 .. 0014 in the test circuit. None of those ever match with what's passed in PAR. Using PASD I can step through this cog's instructions and see what's being picked up via PAR and stored in BAcomp. That is working fine. And, YES, BM1 is /M1 inverted; that is seen via ViewPort. That's been OK for many moons.
Here's the Spin code. Prop#1 send commands and data to this, Prop#2.
'******************************* '* Control_2Prop2 v 0.1 * mod 3:25 pm 18 Jun.2009 '* (C) 2007 h.a.s. designn * '******************************* ViewPort = v 4.1.1 , PASD = v 0.3 latest versions CON _clkmode = xinput + pll16x _xinfreq = 5_000_000 ' ext. clock @ 5 MHz on pin 30 from Prop#1, PLL=16x Prop_Tx = 22 ' Data to Prop1, pin 27/A22 Prop_Rx = 23 ' Data from Prop1, pin 28/A23 Prop_Baud = 115_200 ' for Prop1 <=> Prop2 communications ' maskF0 = $0000_00F0 ' 2nd lsb nybl mask WHERE USED ??? BM1 = 1 << 16 ' Kuroneko code time = $1FB ' Kuroneko code VAR long stack[noparse][[/noparse]250], rxpin, txpin, c, rxbyte, rxcheck, txbyte long PodCntl, SBPt, CmdP2, CmdVP, id, dataReg, statReg, keyReg, AdDaStReg long triggermask, triggerstate, NyblReg, BAbusReg, n, Prop2Reg, INTRPT, BAid long storage ' Kuroneko code OBJ PropSer : "FullDuplexSerial" ' for Prop1/Prop2 serial communications vp : "Conduit" ' transfers ViewPort data to/from PC - ver 2.0 qs : "QuickSample" ' VP captures INA, variables, +1 cog @ 20 MHz ' dbg : "PasDebug" '<== use for PASD debugger (MUST include .binary file) '************************************************************************************** ' Prop#2: handles BAbus address comparator, interrupt 'logic', other Pod i/f signals. ' Connects to Prop1 via rx/tx pins, and both Props connect to a 'Pod' board. '****email lc/37cc594a***************************************************************** PUB Main|frame[noparse][[/noparse]400] vp.register(qs.sampleINA(@frame,1)) '1 cog samples INA at 20 MHz = NEW VP commands vp.config(string("var:io,PodCntl,SBPt,CmdP2,CmdVP,id")) ' VARs to display vp.config(string("lsa:view=io,timescale=500ns,trigger=io[noparse][[/noparse]16]r")) ' init lsa.display vp.config(string("edit:SBPt(mode=text),CmdVP(mode=text)")) ' VARs to edit vp.config(string("start:lsa")) vp.share(@PodCntl,@id) 'share memory from 'PodCntl' to 'id' END of VP init <<=== PropSer.start(Prop_Rx, Prop_Tx, %0000, Prop_Baud) ' sets comm w/Prop1 id := cognew(@CntlP2,@CmdP2) ' sets up Control pg#2 'logic' for CntlP2; CmdP2@PAR ' id := cognew(@entry,@CmdP2) ' this sets up Control pg#2 'logic' for PASD id := cognew(@BAbusRd,@SBPt) ' SBPt value @ PAR for BAbusRd ' id := cognew(@entry,@SBPt) ' set up logic for PASD BAid := id ' save cog# for SBPt stop/restart ' id := dbg.start(31,30,@entry) '<---- Add for PASD Debugger <<=== ''PUB init ' storage := BM1 | $ABCD ' Kuroneko code ' id := cognew(@trigger, @storage) ' Kuroneko code '' id := cognew(@entry,@storage) ' set up logic for PASD '' repeat repeat ' Main Loop ************ deals with signals between Prop#1 and Pod ********* if (c := PropSer.rxcheck) <> -1 ' check for Prop#1 command and data Prop2Prop1 '(Pod i/f via assembly rather than Spin cogs) '************************************************************************************* PRI Prop2Prop1 ' process Prop #2 commands from Prop#1 if (c & $C0) == $C0 ' test if is a valid 'Control Pg 2' command CmdVP := c ' save copy for Viewport use CmdP2 := c ' if so, set variable CmdP2 (asm picks up in 'Cmd') case c $80 : ' used during Init; transfers 'title', Chipver and #cogs PropSer.tx(c) ' echo that command value for Prop#1 'handshake' waitcnt(8000_000 + cnt) ' wait about 100 ms IS THIS TIMING RIGHT (below too) ??? PropSer.str(@title2a) ' send first text 'title' to Prop#1 waitcnt(800_000 + cnt) ' wait about 10 ms ??? PropSer.str(@title2b) ' send 2nd 'title' waitcnt(800_000 + cnt) ' wait about 10 ms ??? PropSer.tx(CHIPVER + $30) ' send ChipVersion waitcnt(800_000 + cnt) ' wait about 10 ms ??? PropSer.tx(id) ' send #cogs used $81 : ' looptest Prop#2 PropSer.tx(c) ' echo command repeat c := PropSer.rxcheck ' check for loop test value while c == -1 PropSer.tx(c) ' return 'loop test value' ' $82 : ' - unused $83 : ' returns Breakpoint address to Prop##1 SBPt := $0001_0000 ' set bit 16 true -- get ready to set Breatpoint value repeat ' c := PropSer.rxcheck while c == -1 SBPt := SBPt | (c << 8) ' store HI byte of BreakPoint register repeat c := PropSer.rxcheck while c == -1 SBPt := SBPt | c ' add LO byte PropSer.tx($83) ' let Prop#1 display BPt bytes held in Prop#2 (comment out to 84) c := (SBPt >> 24) & $FF ' get ms byte, return to Prop#1; now return as 4 bytes PropSer.tx(c) c := (SBPt >> 16) & $FF ' get 2nd ms byte PropSer.tx(c) c := (SBPt >> 8) & $FF ' get 2nd ls byte PropSer.tx(c) c := SBPt & $FF ' get ls byte PropSer.tx(c) $84 : ' returns Pod control bits PropSer.tx(c) c := INA ' get Prop#2 pin states PodCntl := (c >> 24 ) & $7 ' only get lower 3 bits of ms byte PropSer.tx(PodCntl) ' send to Prop#1 ' $85..$8F and $92..$FF codes unused; codes $000 ,, $6F for D/K communications $90 : ' returns $90 code and a count each time D/K RUN pressed PropSer.tx(c) ' echo '90' code PropSer.tx(n) ' send 'count', then increment it n++ $91 : ' unused COGSTOP(BAid) ' stop that cog waitcnt(40_000_000 + cnt) ' wait about 1/2 sec ??? BAid := COGNEW(@BAbusRd,@SBPt) ' sets up Control pg#2 'logic' for CntlP2; CmdP2@PAR '************************ End of Spin code, next Assembly ************************* DAT ORG 0
@ Kuroneko,
I wonder if there is any difference between true input signals and a cog which applies values to your setup's output pins? I'd hope not. These input signals are supplied from TTL logic through 220 Ohm resistors, YES, low to minimize RC rise/fall time degradation and delay.
I tried your code which output values but didn't get matches as I'd hoped. I'm glad you could get the sample code to work. I'm stumped, honestly.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
It looks like SBPt is the value that gets sent to BAcomp, am I correct? What I see, though, is SBPt becoming non-zero ($0001_0000) before its value is fully-formed. As soon as that happens, your breakpoint program will seize upon it and look for that value. In this case, it will be looking for an address of zero, which is not in your stated range of $0004 to $0014.
What you need to do is compute your breakpoint value using a temporary variable, then assign it to SBPt.
-Phil
You are correct about SBPt being sent to BAcomp. That value in PAR gets zeroed IF and after WAITPEQ exits. Do you mean what's in PAR will be reflected back to SBPt? The loop at the top of asm code awaits another user input.
In use there is a keypad which the user keys in the breakpoint value. That gets sent from Prop#1 to Prop#2 to form SBPt.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko