(Help) I can't do anything right with PASM today, even a simple timer loop
turbosupra
Posts: 1,088
I feel like I'm in the twilight zone ...
I know the second code block is long (it is there in case someone wanted to compile the whole thing), but it is a PASM template I use and the important part of the code I have put in the first code block, as well as its output to the PST in the quotation. I tried to do a simple timer to check an issue with another code block and I can't even get the timer to work. Does everyone have these days or is it just me?
startTime (1834539093) - endTime (1834707489) is not 2 as Pst16 indicates, it's actually 168396 which I don't think it correct either as it shouldn't be that high, it should be around 100 cycles.
The entire code for compilation, is below
I know the second code block is long (it is there in case someone wanted to compile the whole thing), but it is a PASM template I use and the important part of the code I have put in the first code block, as well as its output to the PST in the quotation. I tried to do a simple timer to check an issue with another code block and I can't even get the timer to work. Does everyone have these days or is it just me?
restart mov startTime, cnt add alive, #1 wrlong alive, pstPtr13 wrlong pinMask, pstPtr1 wrlong pin, pstPtr2 end mov endTime, cnt wrlong startTime, pstPtr14 wrlong endTime, pstPtr15 sub endTime, startTime wrlong endTime, pstPtr16 jmp #restart
From the PST wrote:Pst1: 00000000000000000000000000010000
Pst2: 4
Pst3: 16
Pst4: 0
Pst5: 0
Pst6: 0
Pst7: 0
Pst8: 0
Pst9: 0
Pst10: 0
Pst11: 0
Pst12: 0
Pst13: 261657325
Pst14: 1834539093
Pst15: 1834707489
Pst16: 2
startTime (1834539093) - endTime (1834707489) is not 2 as Pst16 indicates, it's actually 168396 which I don't think it correct either as it shouldn't be that high, it should be around 100 cycles.
The entire code for compilation, is below
{ WHAT OBJECT SHOULD DO GOES HERE } CON _CLKMODE = XTAL1 + PLL16X _CLKFREQ = 80_000_000 ' current code only allows from 1Hz upwards MIN_FREQUENCY = 1 ' dunno which upper limit can be achieved by the SPIN-code MAX_FREQUENCY = 9200 BAUDRATE = 115_200 _byteLimit = 100 OBJ pst : "Parallax Serial Terminal" n : "Numbers" VAR byte b_delimiter, b_prefix[_byteLimit], b_suffix[_byteLimit] byte b_waitingToBeParsed[_byteLimit] byte b_byteMoveIndex byte b_RxString[_byteLimit] ' Shared cog/hub variables and addresses long l_cog long l_pst1 long l_pst2 long l_pst3 long l_pst4 long l_pst5 long l_pst6 long l_pst7 long l_pst8 long l_pst9 long l_pst10 long l_pst11 long l_pst12 long l_pst13 long l_pst14 long l_pst15 long l_pst16 long l_pin ' Non pst shared ' Non shared long l_tmp long l_updateRateDenominator, l_sendAllValuesOnce, l_sendAllValues, l_myReceivedByte ' Test variables here long l_updateTest long l_cntTest long l_prefix long l_suffix pub main b_delimiter := "=" l_updateTest := 2 pst.Start( BAUDRATE ) l_tmp:=-1 repeat while l_tmp==-1 pst.str( string( " ",$0d,"== please press key to start ==",$0d ) ) l_tmp:=pst.rxcheck if l_tmp==-1 waitcnt( clkfreq+cnt ) pst.Clear pst.str( string( "Starting COG!",$0d ) ) pstInitScreen l_pin := 4 init(0) {pst.str(string("updateTest value: ")) pst.dec(l_updateTest) pst.char(13)} repeat pstCom {l_cntTest += 1 waitcnt((clkfreq/10)+ cnt) pst.dec(l_updateTest) pst.char(13)} pub init(tmp) waitcnt((clkfreq*1) + cnt) ' let screen initialize return l_cog := cognew(@pasmstart, @l_cog) + 1 PUB pstCom | lpcnt1,lpcnt2, timeStamp lpcnt1:=0 lpcnt2:=0 timeStamp := cnt 'repeat charAt( 12,2 , proc[ lpcnt1 ] ) lpcnt1 := (lpcnt1+1) & 3 charAt( 28,2 , proc[ lpcnt2 ] ) lpcnt2 := (lpcnt2+1) & 3 charAt( 12, 4, " " ) ' ("object1 cog:") ) pst.Dec(l_cog) pst.str(@spaces) charAt( 43, 4, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 72, 4, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 102, 4, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 12, 5, " " ) ' (":") ) pst.Dec(-7) pst.str(@spaces) charAt( 43, 5, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 72, 5, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 102, 5, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 12, 6, " " ) ' (":") ) pst.dec(-7) pst.str(@spaces) charAt( 43, 6, " " ) ' ( ":" ) ) pst.dec(-7) pst.str(@spaces) charAt( 72, 6, " " ) ' ( ) ) pst.dec(-7) pst.str(@spaces) charAt( 102, 6, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 12, 7, " " ) ' (":" ) ) pst.dec(-7) pst.str(@spaces) charAt( 43, 7, " " ) ' (":") ) pst.dec(-7) pst.str(@spaces) charAt( 72, 7, " " ) ' (":") ) pst.dec(-7) pst.str(@spaces) charAt( 102, 7, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 12, 8, " " ) ' (":" ) ) pst.dec(-7) pst.str(@spaces) charAt( 43, 8, " " ) ' (":") ) pst.dec(-7) pst.str(@spaces) charAt( 72, 8, " " ) ' (":") ) pst.dec(-7) pst.str(@spaces) charAt( 102, 8, " " ) ' ( ":" ) ) pst.Dec(-7) pst.str(@spaces) charAt( 12, 9, " " ) ' (":" ) ) pst.dec(-7) pst.str(@spaces) charAt( 12, 21, " " ) ' ("Pst1:") ) pst.bin(getPst1, 32) pst.str(@spaces) charAt( 12, 22, " " ) ' ("Pst2:") ) pst.dec(getPst2) pst.str(@spaces) charAt( 12, 23, " " ) ' ("Pst3:") ) pst.dec(getPst3) pst.str(@spaces) charAt( 12, 24, " " ) ' ("Pst4:") ) pst.dec(getPst4) pst.str(@spaces) charAt( 12, 25, " " ) ' ("Pst5:") ) pst.dec(getPst5) pst.str(@spaces) charAt( 12, 26, " " ) ' ("Pst6:") ) pst.dec(getPst6) pst.str(@spaces) charAt( 12, 27, " " ) ' ("Pst7:") ) pst.dec(getPst7) pst.str(@spaces) charAt( 12, 28, " " ) ' ("Pst8:") ) pst.dec(getPst8) pst.str(@spaces) charAt( 12, 29, " " ) ' ("Pst9:") ) pst.dec(getPst9) pst.str(@spaces) charAt( 12, 30, " " ) ' ("Pst10:") ) pst.dec(getPst10) pst.str(@spaces) charAt( 12, 31, " " ) ' ("Pst11:") ) pst.dec(getPst11) pst.str(@spaces) charAt( 12, 32, " " ) ' ("Pst12:") ) pst.dec(getPst12) pst.str(@spaces) charAt( 12, 33, " " ) ' ("Pst13:") ) pst.dec(getPst13) pst.str(@spaces) charAt( 12, 34, " " ) ' ("Pst14:") ) pst.dec(getPst14) pst.str(@spaces) charAt( 12, 35, " " ) ' ("Pst15:") ) pst.dec(getPst15) pst.str(@spaces) charAt( 12, 36, " " ) ' ("Pst16:") ) pst.dec(l_updateTest)'getPst16) pst.str(@spaces) if (l_sendAllValuesOnce == 1) if(cnt > (timeStamp + (clkfreq/l_updateRateDenominator))) sendValues l_sendAllValuesOnce := 0 if (l_sendAllValues == 1) sendValues l_myReceivedByte := pst.RxCheck if l_myReceivedByte <> -1 b_waitingToBeParsed[b_byteMoveIndex++] := l_myReceivedByte 'pst.str(@b_waitingToBeParsed) 'pst.str(string(pst#NL)) if l_myReceivedByte == 13 DelimiterFinder(@b_waitingToBeParsed) ByteFill(@b_waitingToBeParsed, 0, strsize(@b_waitingToBeParsed)) b_byteMoveIndex := 0 'printAt(12, 41, " ") 'pst.str(b_prefix) 'printAt(12, 42, " ") 'pst.str(b_suffix) PUB sendValues | localIndex, pstSendAllValues ' Initialize variables here localIndex := 0 pstSendAllValues := 0 printAt(1,40, String("sendAllValues()")) PUB pstInitScreen printAt( 1,2, string("Main loop [ ]") ) printAt( 20,2, string("Update [ ]") ) printAt( 3,4, string("cog:") ) printAt( 33, 4, string( "cog:" ) ) printAt( 63,4, string("cog:") ) printAt( 93,4, string("cog:") ) printAt( 3,5, string("crGap RPM:") ) printAt( 33, 5, string( "caGap RPM:" ) ) printAt( 63,5, string("+Degrees:") ) printAt( 93,5, string("Targ Ang:") ) printAt( 3,6, string("crTth RPM:") ) printAt( 33, 6, string( "caTth RPM:" ) ) printAt( 63, 6, string( ":" ) ) printAt( 93, 6, string( "angDiff:" ) ) printAt( 3,7, string("crGapTime:" ) ) printAt( 33,7, string("caGapTime:") ) printAt( 63,7, string("cr-CaTime:") ) printAt( 93,7, string("hz:") ) printAt( 3,8, string("crAvgCyc:") ) printAt( 33,8, string("caAvgCyc:") ) printAt( 63,8, string("Cycl/Deg:") ) printAt( 93,8, string("hzCycles:") ) printAt( 3,9, string("toothNum:") ) {printAt( 33,8, string("T Cnt Max") ) printAt( 3,9, string("Min") ) printAt( 33,9, string("Max") ) printAt( 3,10, string("Gap Cnt") ) printAt( 33,10, string("Gap Cnt/Sec") ) printAt( 33,11, string("Gap Rpm:") ) } printAt( 3,21, string("Pst1:") ) printAt( 3,22, string("Pst2:") ) printAt( 3,23, string("Pst3:") ) printAt( 3,24, string("Pst4:") ) printAt( 3,25, string("Pst5:") ) printAt( 3,26, string("Pst6:") ) printAt( 3,27, string("Pst7:") ) printAt( 3,28, string("Pst8:") ) printAt( 3,29, string("Pst9:") ) printAt( 3,30, string("Pst10:") ) printAt( 3,31, string("Pst11:") ) printAt( 3,32, string("Pst12:") ) printAt( 3,33, string("Pst13:") ) printAt( 3,34, string("Pst14:") ) printAt( 3,35, string("Pst15:") ) printAt( 3,36, string("Pst16:") ) DAT org 0 pasmstart add cogPtr, par add pstPtr1, par add pstPtr2, par add pstPtr3, par add pstPtr4, par add pstPtr5, par add pstPtr6, par add pstPtr7, par add pstPtr8, par add pstPtr9, par add pstPtr10, par add pstPtr11, par add pstPtr12, par add pstPtr13, par add pstPtr14, par add pstPtr15, par add pstPtr16, par add pin, par initialize rdlong pin, pin mov ctra, POS_DETECT ' ctra measures high phase add ctra, pin mov frqa, #1 mov ctrb, NEG_DETECT ' ctrb measures low phase add ctrb, pin mov frqb, #1 mov pinMask, #1 ' create pin mask shl pinMask, pin mov ina, pinMask mov inb, pinMask mov loopCnt, cnt restart mov startTime, cnt add alive, #1 wrlong alive, pstPtr13 wrlong pinMask, pstPtr1 wrlong pin, pstPtr2 end mov endTime, cnt wrlong startTime, pstPtr14 wrlong endTime, pstPtr15 sub endTime, startTime wrlong endTime, pstPtr16 jmp #restart ' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ' Unsigned Divide ' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// LNDivide mov LNDivideQuotient, #0 ' Setup to divide. mov LNDivideBuffer, #0 ' mov LNDivideCounter, #32 ' cmp LNDivideDivsor, #0 wz ' Clear if dividing by zero. if_z mov LNDivideDividend, #0 ' if_z jmp #LNDivide_ret ' LNDivideLoopPre shr LNDivideDivsor, #1 wc, wz ' Align divisor MSB and count size. rcr LNDivideBuffer, #1 ' if_nz djnz LNDivideCounter, #LNDivideLoopPre ' LNDivideLoopPost cmpsub LNDivideDividend, LNDivideBuffer wc ' Preform division. rcl LNDivideQuotient, #1 ' shr LNDivideBuffer, #1 ' djnz LNDivideCounter, #LNDivideLoopPost ' 'wrlong LNDivideQuotient, pstptr7 'wrlong LNDivideDividend, pstptr8 mov divisionResult, LNDivideQuotient LNDivide_ret ret ' Return. Remainder in dividend on exit. ' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ' Unsigned Multiply ' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// LNMultiply mov LNMultiplyProduct, #0 ' Clear product. LNMultiplyLoop shr LNMultiplyMultiplicand, #1 wc ' Preform multiplication. if_c add LNMultiplyProduct, LNMultiplyMultiplier ' shl LNMultiplyMultiplier, #1 ' tjnz LNMultiplyMultiplicand, #LNMultiplyLoop ' mov multiplicationResult, LNMultiplyProduct LNMultiply_ret ret ' Return. ' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ' Data ' ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ' -------------------------------------------------------------------------------------------------- cogPtr long 0 pstPtr1 long 4 pstPtr2 long 8 pstPtr3 long 12 pstPtr4 long 16 pstPtr5 long 20 pstPtr6 long 24 pstPtr7 long 28 pstPtr8 long 32 pstPtr9 long 36 pstPtr10 long 40 pstPtr11 long 44 pstPtr12 long 48 pstPtr13 long 52 pstPtr14 long 56 pstPtr15 long 60 pstPtr16 long 64 pin long 68 ' Standard variables here divisionResult long 0 multiplicationResult long 0 startTime long 0 startTimeT long 0 prevStartTime long 0 endTime long 0 alive long 0 prevLoopCnt long 0 loopCnt long 0 loopCntT long 0 timer long 0 ' Variables with non 0 values here clk long 80000000 phaseOne long 1 phaseTwo long 2 phaseThree long 3 phaseFour long 4 phaseFive long 5 phaseSix long 6 phaseSeven long 7 POS_DETECT long %01000 << 26 NEG_DETECT long %01100 << 26 tix long 100000 ' Temporary variables here loopCountTemp long 0 ' Reserved variables here tmp1 res 1 tmp2 res 1 pinMask res 1 ' mask for frequency input pin ' //////////////////////Math Run Time Variables///////////////////////////////////////////////////////////////////////////////////// LNDivideBuffer res 1 LNDivideCounter res 1 LNDivideDividend res 1 LNDivideDivsor res 1 LNDivideQuotient res 1 LNMultiplyMultiplicand res 1 LNMultiplyMultiplier res 1 LNMultiplyProduct res 1 fit 492 PUB DelimiterFinder(RxStringAddr) : idx | localCount, localIndex, pstDelimiterFinder ' Initialize variables here localIndex := 0 pstDelimiterFinder := 0 printAt(1,40, string(" ")) repeat ifnot localCount := byte[RxStringAddr][idx++] ' ifnot c, itterate to the next byte in byte[RxStringAddr] ? printAt( 1,40, String("No delimiter, aborted")) return -1 charAt(1+idx,39,localCount) ' pst.dec(localCount) ' pst.str(string(pst#NL)) until localCount == b_delimiter'localCount == "=" bytemove(@b_prefix, RxStringAddr, --idx) ' idx points to the character after the delimiter, copy prefix b_prefix[idx] := 0 ' add terminator RxStringAddr += idx + 1 ' advance pointer, skip delimiter (+1) bytemove(@b_suffix, RxStringAddr, strsize(RxStringAddr) +1) ' copy tail including the existing terminator (+1) 'pst.str(b_prefix) 'pst.char(13) 'pst.hex(b_suffix,1) 'pst.char(13) variableUpdator(@b_prefix, @b_suffix) PUB variableUpdator(preAddr, sufAddr) | localIndex, pstVariableUpdator, updateValue ' variableUpdator(@prefix, @suffix) ' Initialize variables here localIndex := 0 'pst.str(long[preAddr]) 'pst.char(13) 'pst.str(sufAddr) 'pst.char(13) 'charAt(1,40, " ") 'printAt(1,40, string(" ")) if strcomp(preAddr, string("updateRateDenominator")) 'strcomp(@prefix, var1) l_updateRateDenominator := n.FromStr(sufAddr, %000_000_000_0_0_000000_01010) ' n.FromStr(@suffix, %000_000_000_0_0_000000_01010) ' converts from a string to a dec pst.str(l_updateRateDenominator) 'pst.str(string(pst#NL)) if strcomp(preAddr, string("sendAllValuesOnce")) 'strcomp(@prefix, var1) l_sendAllValuesOnce := n.FromStr(sufAddr, %000_000_000_0_0_000000_01010) ' n.FromStr(@suffix, %000_000_000_0_0_000000_01010) ' converts from a string to a dec 'pst.str(l_sendAllValuesOnce) 'pst.str(string(pst#NL)) if strcomp(preAddr, string("sendAllValues")) 'strcomp(@prefix, var1) l_sendAllValues := n.FromStr(sufAddr, %000_000_000_0_0_000000_01010) ' n.FromStr(@suffix, %000_000_000_0_0_000000_01010) ' converts from a string to a dec 'pst.str(l_sendAllValues) 'pst.str(string(pst#NL)) if strcomp(preAddr, string("update")) 'strcomp(@prefix, var1) l_updateTest := n.FromStr(sufAddr, %000_000_000_0_0_000000_01010) ' n.FromStr(@suffix, %000_000_000_0_0_000000_01010) ' converts from a string to a dec 'genCa.setVariableDegreeDelay(updateValue) 'charAt( 12, 40, " " ) 'pst.str(string("update was updated")) 'pst.char(13) {if strcomp(preAddr, l_i1Name) 'strcomp(@prefix, var1) l_i1value := n.FromStr(sufAddr, %000_000_000_0_0_000000_01010) ' n.FromStr(@suffix, %000_000_000_0_0_000000_01010) ' converts from a string to a dec long sendAllValuesOnce long sendAllValues } pstInitScreen dat spaces byte " ",0 proc byte "-/|\" pub charAt( x,y,c ) ' output a character if it's in screen-range and if it's a printable character if x>0 and x<109 and y>0 and y<75 and c>31 and c<128 posbuf[1]:=x posbuf[2]:=y posbuf[3]:=c pst.str(@posbuf) pub printAt( x, y, text) ' set cursor position and print string posbuf[1]:=x posbuf[2]:=y posbuf[3]:=0 pst.str(@posbuf) pst.str( text ) dat ' a buffer to assemble the bytestream for positioning posbuf byte 2, 0, 0, 0, 0 pub getCog result := l_cog pub getPst1 result := l_pst1 pub getPst2 result := l_pst2 pub getPst3 result := l_pst3 pub getPst4 result := l_pst4 pub getPst5 result := l_pst5 pub getPst6 result := l_pst6 pub getPst7 result := l_pst7 pub getPst8 result := l_pst8 pub getPst9 result := l_pst9 pub getPst10 result := l_pst10 pub getPst11 result := l_pst11 pub getPst12 result := l_pst12 pub getPst13 result := l_pst13 pub getPst14 result := l_pst14 pub getPst15 result := l_pst15 pub getPst16 result := l_pst16
Comments
Perry
So I tried waitcnt with PASM for the first time and apparently it does not function like the spin waitcnt. It seems like it should be a relatively simple command but like the thread title says, nothing was going right today.
If I waitcnt for 10000 cycles, should that be sufficient? Can I just do the following?
Perry
In assembly, WAITCNT xx,yy works like this:
On encountering the WAITCNT instruction, the cog suspends execution until the 32 bit sytem counter value located in CNT reaches the 32 bit value held in cog location xx.
On reaching that value, (which could take up to 53 or so seconds at 80 MHz) the 32 bit value held in cog location yy is instantly added to the value at location xx, prepping the counter for another wait to THAT count if you should desire. To effect that, you would presumably do some code, and loop back to the previous WAITCNT. Every time that WAITCNT is encountered, the cog will wait until the system counter reaches the appropriate value.... and that is the current value in xx, which is then incremented by the value in yy.
Do note, that the value in yy could be zero, and also that in using the # literal designator, yy could be an immediate value. from 0 through 511.
Hope that helps.
Cheers,
Peter (pjv)
Actually it was. In the interest of humbling myself I had a mistake in my template that I had not realized. In the code below, it should have been printing the value returned when I called getPst16, which you can see is commented out. Instead it was printing a hardcoded variable all of the time, so I've been chasing my tail for about 3 hours now. Talk about humble pie!
Once that was straightened out, it printed the values I expected and magically my PASM waitcnt started working (as it was actually working all along). As I said, I learn everything the hard way, which is not to my liking. Working code block is below.
Thank you kindly for your reply. This is a good explanation which helps me wrap my head around this a little better. My mistake turned out to be more due to not taking a break and over looking something obvious, then my understanding of the PASM wait cnt, although I now understand it even better with your explanation. Thank you for that.
Attachment not found.
I was expecting days of frustration and was not convinced that the I2C code would not stop on itself in some random and inobservable way but it worked! :P
To answer your question.... yes I have those days, more often than not. I'm just thankful when there are coding errors and not smoke-inducing hardware errors.
@photomankc, it's nice to hear it isn't only me ... maybe one day this month I'll be blessed with a day like you describe.