Shop OBEX P1 Docs P2 Docs Learn Events
(Help) I can't do anything right with PASM today, even a simple timer loop — Parallax Forums

(Help) I can't do anything right with PASM today, even a simple timer loop

turbosupraturbosupra Posts: 1,088
edited 2012-07-02 20:08 in Propeller 1
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?

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                        

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

  • PerryPerry Posts: 253
    edited 2012-07-02 13:05
    I think you should use "subs" for cases when the "cnt" might over flow.

    Perry
  • Mark_TMark_T Posts: 1,981
    edited 2012-07-02 15:52
    If you're expecting the difference between endTime and startTime to be about 100 cycles, then there's no way you can print the values from spin code as they will be changing under your feet many times (hundreds? thousands?) befween you sampling the values. You either have to stop the cog, use locks, cycle the values into a large enough buffer or some strategy that prevents the hub locations from being overwritten dozens of times while you write to the serial line. 100 cycles = 1.2us, 1 character to the serial port at 115200 baud = 95us
  • turbosupraturbosupra Posts: 1,088
    edited 2012-07-02 16:36
    Ah! icon-lightbulb.gif That would make sense why this exact same code that I'm using in another object to measure loop timing worked!

    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?
                            mov     cntT, cnt
                            add     cntT, tenThousandCycles
                            waitcnt cntT, #0
    

    Mark_T wrote: »
    If you're expecting the difference between endTime and startTime to be about 100 cycles, then there's no way you can print the values from spin code as they will be changing under your feet many times (hundreds? thousands?) befween you sampling the values. You either have to stop the cog, use locks, cycle the values into a large enough buffer or some strategy that prevents the hub locations from being overwritten dozens of times while you write to the serial line. 100 cycles = 1.2us, 1 character to the serial port at 115200 baud = 95us
  • PerryPerry Posts: 253
    edited 2012-07-02 16:53
    I had found the "Clock" code in OBEX http://obex.parallax.com/objects/139/ very useful in explaining this stuf.

    Perry
  • turbosupraturbosupra Posts: 1,088
    edited 2012-07-02 18:47
    I can be pretty dense sometimes, but it appears to me that all of the examples in that object are in spin and the spin stuff I understand. It is the PASM waitcnt I'm struggling with.
  • Vega256Vega256 Posts: 197
    edited 2012-07-02 19:35
    turbosupra wrote: »
    I can be pretty dense sometimes...
    Couldn't be much worse than trying to dev without the serial terminal...
  • pjvpjv Posts: 1,903
    edited 2012-07-02 19:36
    Hi Turbo

    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)
  • turbosupraturbosupra Posts: 1,088
    edited 2012-07-02 19:41
    ROFL!

    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.
    restart
                            mov     startTime, cnt          ' copy cnt to startTime
                            add     alive, #1               ' add "1" to the alive count
                            wrlong  alive, pstPtr13         ' write the alive count to hub ram for the pst
                            wrlong  pinMask, pstPtr1        ' write the pinMask to hub ram for the pst
                            wrlong  pin, pstPtr2            ' write the pin number to hub ram for the pst
    
                                                  
    
    
    
    end
                            
                            mov     cntT, cnt               ' copy read only cnt to temporary variable
                            add     cntT, tix               ' add tix value to temporary cnt variable
                            waitcnt cntT, #0                ' wait until cnt value exceeds temporary variable
                             
                            mov     endTime, cnt            ' copy cnt to endTime
                            wrlong  startTime, pstPtr14     ' write start time to pst
                            wrlong  endTime, pstPtr15       ' write end time to pst
                            sub     endTime, startTime      ' subtract startTime from endTime
                            wrlong  endTime, pstPtr16       ' print difference to hub ram for pst, should be around 100k with current tix value
    
                            
                            jmp     #restart                        
    
    
    
    charAt( 12, 36, " " )  ' ("Pst16:") )
          pst.dec(l_updateTest)'getPst16)
          pst.str(@spaces)
    

    Vega256 wrote: »
    Couldn't be much worse than trying to dev without the serial terminal...
  • turbosupraturbosupra Posts: 1,088
    edited 2012-07-02 19:44
    Hi Peter,

    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.

    pjv wrote: »
    Hi Turbo

    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)
  • Vega256Vega256 Posts: 197
    edited 2012-07-02 19:58
    Have you a copy of the Prop Manual? It's a pretty useful doc; it has all of the ASM opcodes in there, alphabetically listed.

    Attachment not found.
  • photomankcphotomankc Posts: 943
    edited 2012-07-02 20:08
    Just to be contrary.... and because this rarely happens for me.... I just converted my robot's sonar controller scanning code over to launch a seperate cog to monitor and control a PICAXE I2C slave doing the firing and this is the first stress test of my PASM I2C driver for multiple cogs to share the same I2C bus at 400KHz. I nearly fell out of my chair when after making the changes the dang thing took off and just worked! Only tweak needed was to slow down a bit since my sonar code is now running a median filter to suppress the spurious noise readings so it's a little sluggish now with three sensors in the array.

    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.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-07-02 20:08
    Yes I do, I've read it more times then I can count, this was just a particularly bad day I guess.

    @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.
Sign In or Register to comment.