Shop OBEX P1 Docs P2 Docs Learn Events
I'm ashamed to ask - pointer dereferening question — Parallax Forums

I'm ashamed to ask - pointer dereferening question

agsags Posts: 386
edited 2011-08-06 22:20 in Propeller 1
This is embarrasing. I think in terms of C/C++, and I have already RTFM many times. I can't figure out why I'm unable to start with a SPIN local variable containing a hub RAM address and increment the value of the register pointed to by that address. I just want to march a single bit from LSB to MSB. Here's what I started out with:
PUB Test(cmdAddr, mSecInterval) | clockTics
  clockTics := 80000 * mSecInterval
  long[cmdAddr] := $00000001  'works
  repeat
    waitcnt(clockTics + cnt)
    if (long[cmdAddr] == $80000000)
      long[cmdAddr] := $00000001
    else
      long[cmdAddr]<<=1  ' does not work
      'also tried (and failed):
      'long[cmdAddr] := ((long[cmdAddr])<<1)

and here's how I surrendered after 30 minutes of trying unsuccessfully to make it work:
PUB Test(cmdAddr, mSecInterval) | clockTics, cmdVal
  clockTics := 80000 * mSecInterval        '80MHz clock
  cmdVal := $00010000
  repeat
    long[cmdAddrr] := cmdVal
    if (cmdVal == $80000000)
      cmdVal := $00010000
    else
      cmdVal <<= 1
    waitcnt(clockTics + cnt)

What am I missing? The long[registerContainingAnAddress] and variable.short syntax is not natural for me, but I do think I understand it? I parenthesized until I was exhausted, wondering if it was an issue with operator precedence. No luck.

Thanks for any help.

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2011-08-06 19:05
    No issues here. How are you calling Test()? Note that the function contains an endless loop and will never return.
    VAR
      long  stack[32]
      
    PUB main | local
    
      cognew(rotate(@local, 100), @stack{0})
      
      dira[16..23]~~
      repeat
        outa[16..23] := >| local    ' display top bit location +1
        
    PUB rotate(cmdAddr, mSecInterval) | clockTics
      clockTics := 80000 * mSecInterval
      long[cmdAddr] := $00000001  'works
    
      repeat
        waitcnt(clockTics + cnt)
        long[cmdAddr] <-= 1         ' rol #1
    
    DAT
    
    I also just dropped your first solution into my example and there is no issue with it. ... and there is no stupid question :)
  • agsags Posts: 386
    edited 2011-08-06 19:15
    More code:
    VAR
      long g_stack[32]
      long g_globalVal
     
    PUB main
     
      cognew(@Test(@g_globalVar,250),@stack)
      '...other stuff
     
    PUB Test(cmdAddr, mSecInterval) | clockTics
      clockTics := 80000 * mSecInterval
      long[cmdAddr] := $00000001 'works
      repeat
        waitcnt(clockTics + cnt)
        if (long[cmdAddr] == $80000000)
          long[cmdAddr] := $00000001
        else
          long[cmdAddr]<<=1 ' does not work
    
  • kuronekokuroneko Posts: 3,623
    edited 2011-08-06 19:18
    Could we have something which compiles? Test isn't a valid function name, cognew(@Test()) looks suspicious ... there must be a simple test case.

    How do you validate that assigning $00000001 works but shifting doesn't?
  • pgbpsupgbpsu Posts: 460
    edited 2011-08-06 19:18
    ags-

    I believe you're call should be:
    cognew(Test(@g_globalVar,250),@stack)
    
    NOT
    cognew(@Test(@g_globalVar,250),@stack)
    

    Does that make any difference?
  • agsags Posts: 386
    edited 2011-08-06 19:37
    Sorry, I was trying to simplify. Here's the actual code (cut from code that compiled and is running):
    VAR
     
      long  g_serialDriverTest
      long  g_testStack[128]
     
    PUB main
     
      '...stuff
      cognew(Test16Bits(@g_serialDriverTest,10),@g_testStack) 'this works
      cognew(Test16Bits_2(@g_serialDriverTest,10),@g_testStack) 'this doesn't work       
      '...more stuff
     
    PUB Test16Bits(cmdStartPtr, mSecInterval) | clockTics, cmdVal
     
      clockTics := 80000 * mSecInterval
      cmdVal := $00010000
      repeat
        long[cmdStartPtr] := cmdVal
        if (cmdVal == $80000000)
          cmdVal := $00010000
        else
          cmdVal <<= 1
        waitcnt(clockTics + cnt)
     
    PUB Test16Bits_2(cmdStartPtr, mSecInterval) | clockTics
     
      clockTics := 80000 * mSecInterval
      long[cmdStartPtr] := $00010000
      repeat
        waitcnt(clockTics + cnt)
        if (long[cmdStartPtr] == $80000000)
          long[cmdStartPtr] := $00010000
        else
          long[cmdStartPtr] <<= 1
    

    This is just a test harness for the PASM code I wrote to drive a shift register. That code runs in another cog, and watches for a value in the hub RAM address (passed in to cognew(..) for the PASM code) and then sends it out to the shift register. I breadboarded a simple circuit (with the shift registers) that drives LEDs. With Test16Bits() the LEDs chase as expected; with Test16Bits_2() the first LED lights and then that's all.

    Ironically, the PASM code (the goal of this phase of the project, which the Test*() code is merely to test) was correct the first time; however, I spent an hour trying to figure out what was wrong, only to realize it was my test bench...

    Thanks for any thoughts on this. (I suppose there might be something else going on in the PASM code (or elsewhere), but it does work as expected with the Test16Bits() test driver.
  • agsags Posts: 386
    edited 2011-08-06 22:05
    I'm still stumped by this. I've tried adding the "cmdVal" local to Test16Bits_2, and swapping position (order) in memory, in case it's a stack corruption problem. Still no luck; Test16Bits(...) works as expected, Test16Bits_2(...) doesn't.
  • agsags Posts: 386
    edited 2011-08-06 22:17
    Moron Alert!

    What I didn't post was my PASM code in a different cog. It just loops, waiting to see a non-zero value in the memory location that is written by the test harness (Test16Bit(...)). When it sees any non-zero value, it copies it to cog RAM, clears the hub RAM location, processes that value and then loops looking for the next non-zero value.

    Of course, with Test16Bit(...), after each waitcnt period, a new non-zero value is written to that hub RAM location, and all works as planned. With Test16Bit_2(...), the first value is written ($00010000), it is seen by the PASM code in the other cog, copied, and then processed. The next waitcnt time, the main (SPIN) cog does what I told it to do: read the hub RAM location, shift left one bit, and write it back out. The only problem is, it was cleared by the PASM cog so shifting all zeros left one bit doesn't do much.

    Good Grief! More coffee, less stupid. My sincere apologies to those that wasted pesonal cycles helping to diagnose. If it's worth anything, the confirmation that the SPIN code I wrote and posted worked for others did help me eventully focus my attention to the right place.
  • kuronekokuroneko Posts: 3,623
    edited 2011-08-06 22:20
    I suspected as much (PASM clearing the location) but couldn't really believe it :) Anyway, glad you got it sorted!
Sign In or Register to comment.