CLKFREQ mysteriously jumps from 80mhz to 824,195,128

R PankauR Pankau Posts: 127
edited March 2012 in Propeller 1 Vote Up0Vote Down
I could not figure out what was going on with my interrupts, all of a sudden the interrupts were taking roughly 10x longer between executions.
this is my clock setup
_clkmode = XTAL1 + PLL16x
_xinfreq = 5_000_000

at boot up CLKFREQ returns 80,000,000 as expected, then after writing to the SD card once it returns 824,195,128 instead. (using fsrw.spin) then it appears to stay put. essentially making all of the waitcnt instructions take a little over 10 times longer.

I've had other strange things with this board as well, for instance if I use SD-MMC_FATEngine instead, then the SD driver will not operate if GPS_IO_mini.spin is used in the same project. I suspect that some resource is being shared not so well but I cannot figure out which one.
Tagged:

Comments

  • 24 Comments sorted by Date Added Votes
  • MagIO2MagIO2 Posts: 2,181
    edited March 2012 Vote Up0Vote Down
    I bet there is a bug in your code. FSRW is very well testes like all objects in the object exchange.

    By the way ... what do you mean with interrupts? There is no such concept for propellers.

    Waitcnt needing longer than expected you have when you just missed the cnt!

    You should post your code!
  • Mark_TMark_T Posts: 1,479
    edited March 2012 Vote Up0Vote Down
    Suspiciously 824195128 is $31203838, valid ASCII, which is the string fragment "88 1" - so a memory overwrite is most likely.
  • Dave HeinDave Hein Posts: 4,532
    edited March 2012 Vote Up0Vote Down
    The CLKFREQ value is located at location 0. It appears that you are writing to location 0. You may be using a NULL pointer somewhere. This kind of error could happen if you did something like BYTEMOVE(buffer, string("88 1"), 4) instead of BYTEMOVE(@buffer, string("88 1"), 4), and buffer is an uninitialized VAR variable that would contain a zero.
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    Very insightful, I think the offending piece of code lies in this that I used from OBEX
    PUB readNEMA
      Null[0] := 0
      repeat
       longfill(gps_buff,20,0)
       repeat while Rx <>= "$"      ' wait for the $ to insure we are starting with
         Rx := uart.rx              '   a complete NMEA sentence 
       cptr := 0
    
       repeat while Rx <>= CR       '  continue to collect data until the end of the NMEA sentence 
         Rx := uart.rx              '  get character from Rx Buffer
         if Rx == ","
           gps_buff[cptr++] := 0    '  If "," replace the character with 0
         else
           gps_buff[cptr++] := Rx   '  else save the character   
       
       if gps_buff[2] == "G"             
         if gps_buff[3] == "G"            
           if gps_buff[4] == "A"            
               copy_buffer(@GPGGAb, @GPGGAa)
    
       if gps_buff[2] == "R"             
         if gps_buff[3] == "M"            
           if gps_buff[4] == "C"           
               copy_buffer(@GPRMCb, @GPRMCa)
                       
       if gps_buff[0] == "P"
        if gps_buff[1] == "G"  
         if gps_buff[2] == "R"
          if gps_buff[3] == "M"  
           if gps_buff[4] == "Z"
               copy_buffer(@PGRMZb, @PGRMZa)
    
    
       if gps_buff[0] == "G"
        if gps_buff[1] == "P"
         if gps_buff[2] == "G"
          if gps_buff[3] == "S"
           if gps_buff[4] == "A"
               copy_buffer(@GPGSAb, @GPGSAa)
    
    The ascii 88 1 is the first four chars of Longitude.
    the "Null[0] right off the bat has me thinking that it's writing to location zero.

    the "interrupt" I refer to is just this, running it a separate cog.
    PUB interrupt
    repeat
      waitcnt(80_000_000 + cnt)
      cntr++
    
    and I use cntr a global var to trigger subs then clear cntr,then wait again. I had CLKFREQ in the waitcnt instruction at first then switched it to 80Mhz and noticed that things began working better.

    I also use byte addressing in this, which is where all the writing to the sd card happens. but I believe it should never affect location zero....requires a closer look though.

    pub write_sd(landmark)  |address, i
    
      ret_val := \sd.popen(string("Log01.txt"),"a")
          if landmark == 2
              \sd.SDstr(gps.GPSaltitude)
              \sd.SDstr(string(", "))
    
              'bytefill(@lat_and_long,0,15)  'Clear Buffer
              address := gps.latitude   'Get address of latitude
              byte[lat_and_long][0] := byte[address][0]
              byte[lat_and_long][1] := byte[address][1]
              byte[lat_and_long][2] := " "
              i := 3
              repeat 7
                byte[lat_and_long][i] := byte[address][i-1]
                i++
              byte[lat_and_long][i] := 0  
              \sd.SDstr(lat_and_long)
              \sd.SDstr(string("N, "))
              
              'bytefill(@lat_and_long,0,15)  'Clear Buffer
              address := gps.longitude   'Get address of longitude
              byte[lat_and_long][0] := byte[address][1]
              byte[lat_and_long][1] := byte[address][2]
              byte[lat_and_long][2] := " "
              i := 3
              repeat 7
                byte[lat_and_long][i] := byte[address][i]
                i++
              byte[lat_and_long][i] := 0   
              \sd.SDstr(lat_and_long)
    
              \sd.SDstr(string("W, ")) 
              \sd.SDstr(gps.satellites)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.valid)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.time)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.heading)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.speed)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.date)
              \sd.SDstr(string(" ",13,10))
              'debug.str(string("test"))
              'debug.dec(ret_val)
              'debug.tx(13) 
              \sd.pflush
              \sd.pclose
              'debug.str(string("after file close",13,10))
             
    
          if landmark == 1
              \sd.SDstr(gps.GPSaltitude)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.latitude)
              \sd.SDstr(string(", -"))
              \sd.SDstr(gps.longitude)
    
              
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.satellites)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.valid)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.time)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.heading)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.speed)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.date)
              \sd.SDstr(string(", Landmark"))
              \sd.SDstr(string(" ",13,10))
              'debug.str(string("test"))
              'debug.dec(ret_val)
              'debug.tx(13) 
              \sd.pflush
              \sd.pclose
    
          if ret_val == 0
            outa[Green_LED] := 1              'Blink LED for success.  
            waitcnt(clkfreq/100 + cnt)
            outa[Green_LED] := 0
    
          if ret_val <> 0  
            outa[Blue_LED] := 1              'Blink LED for NOT success.  
            waitcnt(clkfreq/2 + cnt)
            outa[Blue_LED] := 0
    

    maybe I should have used byte[@lat_and_long][0], I assumed that referencing a var array would return the address of the first byte, but.... now I see that by clearing the array to zero, or if it starts out that way, the byte[effectively zero][0] then writes to location zero.
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    This should work a little better
    Now if I could find the switch to turn off "unsolved" on the forum heading.
    pub write_sd(landmark)  |address, i
    
      ret_val := \sd.popen(string("Log01.txt"),"a")
          if landmark == 2
              \sd.SDstr(gps.GPSaltitude)
              \sd.SDstr(string(", "))
    
              'bytefill(@lat_and_long,0,15)  'Clear Buffer
              address := gps.latitude   'Get address of latitude
              byte[@lat_and_long][0] := byte[address][0]
              byte[@lat_and_long][1] := byte[address][1]
              byte[@lat_and_long][2] := " "
              i := 3
              repeat 7
                byte[@lat_and_long][i] := byte[address][i-1]
                i++
              byte[@lat_and_long][i] := 0  
              \sd.SDstr(lat_and_long)
              \sd.SDstr(string("N, "))
              
              'bytefill(@lat_and_long,0,15)  'Clear Buffer
              address := gps.longitude   'Get address of longitude
              byte[@lat_and_long][0] := byte[address][1]
              byte[@lat_and_long][1] := byte[address][2]
              byte[@lat_and_long][2] := " "
              i := 3
              repeat 7
                byte[@lat_and_long][i] := byte[address][i]
                i++
              byte[@lat_and_long][i] := 0   
              \sd.SDstr(lat_and_long)
    
              \sd.SDstr(string("W, ")) 
              \sd.SDstr(gps.satellites)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.valid)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.time)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.heading)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.speed)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.date)
              \sd.SDstr(string(" ",13,10))
              'debug.str(string("test"))
              'debug.dec(ret_val)
              'debug.tx(13) 
              \sd.pflush
              \sd.pclose
              'debug.str(string("after file close",13,10))
             
    
          if landmark == 1
              \sd.SDstr(gps.GPSaltitude)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.latitude)
              \sd.SDstr(string(", -"))
              \sd.SDstr(gps.longitude)
    
              
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.satellites)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.valid)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.time)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.heading)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.speed)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.date)
              \sd.SDstr(string(", Landmark"))
              \sd.SDstr(string(" ",13,10))
              'debug.str(string("test"))
              'debug.dec(ret_val)
              'debug.tx(13) 
              \sd.pflush
              \sd.pclose
    
          if ret_val == 0
            outa[Green_LED] := 1              'Blink LED for success.  
            waitcnt(clkfreq/100 + cnt)
            outa[Green_LED] := 0
    
          if ret_val <> 0  
            outa[Blue_LED] := 1              'Blink LED for NOT success.  
            waitcnt(clkfreq/2 + cnt)
            outa[Blue_LED] := 0
    
  • SapiehaSapieha Posts: 2,964
    edited March 2012 Vote Up0Vote Down
    To that You need reedit first post of thread in advanced mode

    R Pankau wrote: »
    This should work a little better
    Now if I could find the switch to turn off "unsolved" on the forum heading.
    pub write_sd(landmark)  |address, i
    
      ret_val := \sd.popen(string("Log01.txt"),"a")
          if landmark == 2
              \sd.SDstr(gps.GPSaltitude)
              \sd.SDstr(string(", "))
    
              'bytefill(@lat_and_long,0,15)  'Clear Buffer
              address := gps.latitude   'Get address of latitude
              byte[@lat_and_long][0] := byte[address][0]
              byte[@lat_and_long][1] := byte[address][1]
              byte[@lat_and_long][2] := " "
              i := 3
              repeat 7
                byte[@lat_and_long][i] := byte[address][i-1]
                i++
              byte[@lat_and_long][i] := 0  
              \sd.SDstr(lat_and_long)
              \sd.SDstr(string("N, "))
              
              'bytefill(@lat_and_long,0,15)  'Clear Buffer
              address := gps.longitude   'Get address of longitude
              byte[@lat_and_long][0] := byte[address][1]
              byte[@lat_and_long][1] := byte[address][2]
              byte[@lat_and_long][2] := " "
              i := 3
              repeat 7
                byte[@lat_and_long][i] := byte[address][i]
                i++
              byte[@lat_and_long][i] := 0   
              \sd.SDstr(lat_and_long)
    
              \sd.SDstr(string("W, ")) 
              \sd.SDstr(gps.satellites)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.valid)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.time)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.heading)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.speed)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.date)
              \sd.SDstr(string(" ",13,10))
              'debug.str(string("test"))
              'debug.dec(ret_val)
              'debug.tx(13) 
              \sd.pflush
              \sd.pclose
              'debug.str(string("after file close",13,10))
             
    
          if landmark == 1
              \sd.SDstr(gps.GPSaltitude)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.latitude)
              \sd.SDstr(string(", -"))
              \sd.SDstr(gps.longitude)
    
              
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.satellites)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.valid)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.time)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.heading)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.speed)
              \sd.SDstr(string(", "))
              \sd.SDstr(gps.date)
              \sd.SDstr(string(", Landmark"))
              \sd.SDstr(string(" ",13,10))
              'debug.str(string("test"))
              'debug.dec(ret_val)
              'debug.tx(13) 
              \sd.pflush
              \sd.pclose
    
          if ret_val == 0
            outa[Green_LED] := 1              'Blink LED for success.  
            waitcnt(clkfreq/100 + cnt)
            outa[Green_LED] := 0
    
          if ret_val <> 0  
            outa[Blue_LED] := 1              'Blink LED for NOT success.  
            waitcnt(clkfreq/2 + cnt)
            outa[Blue_LED] := 0
    
    Regards
    Sapieha
    _____________________________________________________
    Nothing is impossible, there are only different degrees of difficulty.
    For every stupid question there is at least one intelligent answer.
    Don't guess - ask instead.
    If you don't ask you won't know.
    If your gonna construct something, make it as simple as possible yet as versatile/usable as possible.
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    Thanks for the help.
  • MagIO2MagIO2 Posts: 2,181
    edited March 2012 Vote Up0Vote Down
    You should go back to waitcnt( CLKFREQ+cnt ) as it usually works correctly. It does not work in your case because CLKFREQ is actually a value stored somewhere in the first 16 bytes of HUB-RAM. If your code somehow overwrites it, you get trouble in code that uses CLKFREQ.

    So, if you still have the problem after changing back you did not fix the original bug yet and this means it can also overwrite other parts which cause more harm!

    It's better to post the whole truth, because the bug might be at a place you'd never expect it to be! The propeller tool has a niche archive function which zips all needed files from actual file point of view. So, select your top-file and do an archive and post it here.
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    Here's the entire thing. pretty messy.
  • MagIO2MagIO2 Posts: 2,181
    edited March 2012 Vote Up0Vote Down
    You should only use COGINIT for a very good reason - but there is only a limited number of those, so you should rather use COGNEW.

    I think your code is fine, but the GPS code seems to be buggy, starting wit this:
    byte gps_buff[80],Rx',cksum
    ....
    longfill(gps_buff,20,0)

    This overwrites the whole begin of HUB-RAM propably destroying something in your code which makes it write to wrong memory locations as well.
  • kuronekokuroneko Posts: 3,623
    edited March 2012 Vote Up0Vote Down
    MagIO2 wrote: »
    longfill(gps_buff,20,0)

    This overwrites the whole begin of HUB-RAM propably destroying something in your code which makes it write to wrong memory locations as well.
    FWIW, it doesn't.
  • MagIO2MagIO2 Posts: 2,181
    edited March 2012 Vote Up0Vote Down
    Maybe I'm wrong?!
    My expectation was that longfill works the same way as bytemove, which needs a pointer to the memory. If my expectation is wrong I'd say that SPIN has an inconsistency in the syntax.
    If my expectation is correct, gps_buff is an array to store the incoming string. Using it without @ means that
    gps_buff[0] is read and used as address which is 0.
  • kuronekokuroneko Posts: 3,623
    edited March 2012 Vote Up0Vote Down
    MagIO2 wrote: »
    Maybe I'm wrong?!
    My expectation was that longfill works the same way as bytemove, which needs a pointer to the memory ...
    Relax, look at the parameters. Requirements are longfill(ptr, value, count), so with count being 0 it's not doing anything useful. That said, the object is a can of worms. Given its functionality it's easier to rewrite this bit.

    @R Pankau: would it be possible to get a data dump of the stuff coming from the GPS unit for one of the failure cases? I don't have any GPS h/w so that would kind of help figuring out where it goes wrong.
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    are you just looking for the string that comes from the gps unit in its raw form?
    the incompatibility that I spoke of in my first post I believe is happening before any reading of gps data takes place.
    for instance the SD_MMC fat engine has written for it a SD card profiler demo program, if I run that demo everything is great, if I load the gps object in the same project even without calling it the demo crashes with no apparent cause, nothing is written to the sd card, i believe usually the error string is written to the card if it was successfully mounted with a file open.

    I used coginit once as a troubleshooting method, thinking I had a faulty cog possibly, also rearranged the order of starting the objects. it just needs to be switched back to cognew.
  • kuronekokuroneko Posts: 3,623
    edited March 2012 Vote Up0Vote Down
    R Pankau wrote: »
    are you just looking for the string that comes from the gps unit in its raw form?
    Exactly. I just need something to replay and feed the GPS object with.
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    just grabbed this...now you know the location of my living room.

    $GPRMC,032531,A,3016.3376,N,08811.8669,W,000.0,000.0,250312,,,A*61

    $GPGGA,032532,3016.3377,N,08811.8667,W,1,03,02.4,00237.5,M,-033.9,M,,*7A

    $GPGSA,A,2,08,11,19,,,,,,,,,,02.6,02.4,01.0*00

    $GPGSV,3,1,11,01,28,140,26,03,13,050,00,06,02,047,00,07,76,142,33*73

    $GPGSV,3,2,11,08,62,317,34,11,46,124,41,13,18,192,26,17,13,220,00*77

    $GPGSV,3,3,11,19,48,051,41,26,19,315,30,28,34,283,00,,,,*40

    $GPRMC,032532,A,3016.3377,N,08811.8667,W,000.0,000.0,250312,,,A*6D

    $GPGGA,032533,3016.3376,N,08811.8669,W,1,03,02.4,00237.5,M,-033.9,M,,*74

    $GPGSA,A,2,08,11,19,,,,,,,,,,02.6,02.4,00.9*08

    $GPGSV,3,1,11,01,28,140,00,03,13,050,27,06,02,047,00,07,76,142,33*72

    $GPGSV,3,2,11,08,62,317,34,11,46,124,41,13,18,192,00,17,13,220,26*77

    $GPGSV,3,3,11,19,48,051,41,26,19,315,29,28,34,283,00,,,,*48

    $GPRMC,032533,A,3016.3376,N,08811.8669,W,000.0,000.0,250312,,,A*63

    $GPGGA,032534,3016.3375,N,08811.8671,W,1,03,02.4,00237.5,M,-033.9,M,,*79

    $GPGSA,A,2,08,11,19,,,,,,,,,,02.6,02.4,00.9*08

    $GPGSV,3,1,11,01,28,140,00,03,13,050,00,06,02,047,00,07,76,142,34*70

    $GPGSV,3,2,11,08,62,317,33,11,46,124,41,13,18,192,00,17,13,2
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    out of sheer laziness I used a prebuilt gps parser. this would not be rocket science to get what I need from this. maybe I should just roll my own.
  • kuronekokuroneko Posts: 3,623
    edited March 2012 Vote Up0Vote Down
    Thanks.
    ... if I load the gps object in the same project even without calling it the demo crashes with no apparent cause ...
    I assume you at least started it?
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    correct, started, not called.
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    One thing I have not done is see how big the buffer in my gps object gets.
  • kuronekokuroneko Posts: 3,623
    edited March 2012 Vote Up0Vote Down
    R Pankau wrote: »
    here is the sd card test. it fails with either gps parser.
    That's serious! Can you try the attached parser object? All it does is place the incoming string in a buffer without actually parsing it. I also adjusted its stack (was too short).

    Also, the object uses a cut down version of FDS but sets the transmit pin to 0 which I believe is used by the SD card interface. So if you could move that out of the way and see if it resolves the issue (serXmit). That said, the other parser object (Lite) doesn't have the pin conflict so something else is going on here.

    Note that the attached object also uses 0 for tx. Just set it to something unused.

    Edit: Just in case, there should be a buffer length check (while Rx <> CR and cptr < 80).
  • R PankauR Pankau Posts: 127
    edited March 2012 Vote Up0Vote Down
    I think you are on to something here. I forced the xmit pin to 16 for the gps module, and the sd profiler works then.
    The SD-MMC_FATEngine.spin object is a pretty nice SD object, so I may try to redo this now that it works.
Sign In or Register to comment.