Shop OBEX P1 Docs P2 Docs Learn Events
Need some help with Jon Macs SD card program update method — Parallax Forums

Need some help with Jon Macs SD card program update method

Don MDon M Posts: 1,652
edited 2014-04-29 17:24 in Propeller 1
I am trying to use Jon Mac's code (which I think is pretty neat btw)-
PUB checkupdate | check, fsize, addr

'' Checks for mounted SD card and presence of "update.pgm"
'' -- if "update.pgm" is on SD card the contents are loaded into the EEPROM
''    and the Propeller is rebooted

  check := \sd.mount(0)
  if (check == 0)
    term.str(string("1. SD card mounted.", 13))
    check := sd.popen(@NewFirmware, "r")                        ' look for update
    if (check == 0)
      term.str(string("2. Found update UPDATE.PGM.", 13))
      fsize := sd.get_filesize                                  
      if (fsize == 32768)                                       ' check 32K (ee image)
        term.str(string("   -- size is correct", 13))
        term.str(string("3. Updating EEPROM...", 13))
        BlinkLed(1, 0, RDR_ERR) 
        addr~ 
        repeat constant(32768 / PG_SIZE)                        ' loop through pages
          sd.pread(@buf, PG_SIZE)                               ' read one
'          check := i2c.putpagex($A0, addr, PG_SIZE, @buf)       ' write it  WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit
          check := i2c.WritePage(i2c#BOOTPIN, EE_DEVICE_ADDR, addr, @buf, PG_SIZE)       ' write it  WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit    
          if (check == i2c#NAK)                                 ' if problem
            term.str(string("   -- EE write error", 13))
            quit                                                ' abort
          addr += PG_SIZE                                       ' else next page
        term.str(string(13, "   -- update complete", 13))
        BlinkLed(5, 0, RDR_ERR) 
        pause(2_000)
        sd.popen(@NewFirmware, "d")                             ' delete update file
        sd.pclose
        reboot                                                  ' restart device
      else
        term.str(string("   -- bad file size; update aborted", 13))
    else
      term.str(string("   -- no update file; update aborted", 13))
  else
    term.str(string("No SD card; update aborted.", 13))   
      
  sd.pclose


I have Version 1 of my code running in the Prop which includes the above method. I have made quite a few changes to my code so now I have Version 2.

Here's what is happening:

1. I use F11 to load Version 1 into Prop. Works fine. Looks for the update.pgm file to see if present. Reports card mounted but file not present. All is good. Program runs.

2. For testing I use F8 and then "Save EEPROM file" and save Version 1 to a file on the SD card named update.pgm. I insert the SD card into the Prop board and restart. Program mounts SD card and finds the update.pgm file, copies data to EEPROM, restarts and Version 1 still runs as expected, reported as SD mounted but no file present (it erases the file after loading eeprom) so continues on ok.

3. Ok now on to trying an actual update. With Version 1 still running ok on the Prop I use F8 and the procedure mentioned above to load the EEPROM image of Version 2 named update.pgm onto the SD card. Insert the SD card into the Prop board and restart. Boots up as normal using Version 1, mounts SD card and finds file named update.pgm. It proceeds to copy data to eeprom and when finished it restarts. Prop is bricked and does not start up.

4. So next I load Version 2 onto the Prop using F11 and it comes up working with Version 2 as expected, checks SD card for update file (none found), etc and runs ok. Again using the F8 "Save EEPROM file" I save Version 2 as update.pgm to the SD card. I insert the card into Prop board and restart. It goes through the steps of mounting card, finds file, copies data to eeprom and restarts. Comes up working fine as Version 2.

I don't understand why it doesn't update Version 1 to Version 2 and run. Any ideas? Sorry I can't post all the code as it is part of a large project I can't reveal. I can tell you that the Main object is exactly the same on Version 1 and Version 2. The first thing it does is start FDS serial, pause and send the message to PST of "Booting..." It does not even do that after trying to update with SD card from Version 1 to Version 2.

As I said earlier there are additional objects, some code and variables added in Version 2 that are not in Version 1 but the start up and message are exactly the same in Version 1 and Version 2.

Comments

  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-04-29 13:02
    My name is not Jonny -- it's Jon. And my last name is McPhalen, not Mac. Says so right on my driver's license, my SAG card, and my signature line. Please, for the love of God, STOP CALLING ME BY MY AVATAR when I make my actual name known.

    That code is a little dated, but I have deployed it in a couple products and NEVER had a problem with it.

    Since you can't reveal your double-super-extra TOP SECRET project, I suggest you write an test app that fails in the same what that we can see where you're going wrong. Paraphrasing Tom Cruise in Jerry Maguire, help the forums membership help you.
  • Don MDon M Posts: 1,652
    edited 2014-04-29 16:07
    Ok so I pared things down a bit.

    Here's Version 1:
    CON
    
      _clkmode        = xtal1 + pll8x                       ' Feedback and PLL multiplier
      _xinfreq        = 10_000_000                          ' External oscillator = 10 MHz
    
      MS_001   = 80_000_000 / 1_000
    
      RDR_ERR  = 4                                          ' Red LED on P4.
    
      EE_DEVICE_ADDR = $A0                                  ' EEPROM assigments                       
    
      SD_DO  = 0                                            ' SD card pins
      SD_CLK = 1
      SD_DI  = 2
      SD_CS  = 3
    
      PG_SIZE  = 64
    
    obj
    
      term     : "FullDuplexSerial"                         ' for terminal output
      i2c      : "Basic_I2C_Driver_1"                       ' EEPROM driver
      aes      : "AES"                                      ' AES encryption engine
      sd[ 2 ]  : "fsrw2_6B"                                 ' SD card driver 
        
    var                                                     
    
      byte buf[PG_SIZE] 
        
    pub main | b, c, temp, wdcnt, wd, i, r, tmp, bytesread, value, place, x 
    
      term.start(31, 30, %0000, 115_200)                    ' start terminal using PST
      i2c.initialize(28)                                    ' initialize I2C object
    
      pause(750)                                            ' pause for PST
    
      term.str(string("Boot... ", 13)) 
    
      term.str(@model)                                      ' display device name on reset  
      term.str(@version)                                    ' display version number on reset
    
      checkupdate
    
    PUB checkupdate | check, fsize, addr
    
    '' Checks for mounted SD card and presence of "update.pgm"
    '' -- if "update.pgm" is on SD card the contents are loaded into the EEPROM
    ''    and the Propeller is rebooted
    
      check := \sd.mount(0)
      if (check == 0)
        term.str(string("1. SD card mounted.", 13))
        check := sd.popen(@NewFirmware, "r")                        ' look for update
        if (check == 0)
          term.str(string("2. Found update UPDATE.PGM.", 13))
          fsize := sd.get_filesize                                  
          if (fsize == 32768)                                       ' check 32K (ee image)
            term.str(string("   -- size is correct", 13))
            term.str(string("3. Updating EEPROM...", 13))
            BlinkLed(1, 0, RDR_ERR) 
            addr~ 
            repeat constant(32768 / PG_SIZE)                        ' loop through pages
              sd.pread(@buf, PG_SIZE)                               ' read one
    '          check := i2c.putpagex($A0, addr, PG_SIZE, @buf)       ' write it  WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit
              check := i2c.WritePage(i2c#BOOTPIN, EE_DEVICE_ADDR, addr, @buf, PG_SIZE)       ' write it  WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit    
              if (check == i2c#NAK)                                 ' if problem
                term.str(string("   -- EE write error", 13))
                quit                                                ' abort
              addr += PG_SIZE                                       ' else next page
            term.str(string(13, "   -- update complete", 13))
            BlinkLed(5, 0, RDR_ERR) 
            pause(2_000)
            sd.popen(@NewFirmware, "d")                             ' delete update file
            sd.pclose
            reboot                                                  ' restart device
          else
            term.str(string("   -- bad file size; update aborted", 13))
        else
          term.str(string("   -- no update file; update aborted", 13))
      else
        term.str(string("No SD card; update aborted.", 13))   
          
      sd.pclose
        
    PUB BlinkLed(blink_rate, mode, pin)
    
      outa[pin] := mode       ' 1: solid, 0: flashing (depending on frqa)
      dira[pin] := 1
      ctra := constant(%0_00100_000 << 23) | pin
      case blink_rate
        1:   
          frqa := 100
        2:   
          frqa := 150
        3:   
          frqa := 200
        4:   
          frqa := 250
        5:   
          frqa := 350
        6:   
          frqa := 500
                                                                                                                    
    pub pause(ms) | t
    
      t := cnt
      repeat ms
        waitcnt(t += MS_001)
    
    DAT
    
    NewFirmware  byte "update.pgm", 0
    
    model        byte "Rev1Test", 13, 0
    version      byte "FW: Main V2.1", 13, 0    
    
    


    And here's Version 2:
    CON
    
      _clkmode        = xtal1 + pll8x                       ' Feedback and PLL multiplier
      _xinfreq        = 10_000_000                          ' External oscillator = 10 MHz
    
      MS_001   = 80_000_000 / 1_000                             
    
      RDR_ERR  = 4                                          ' Red LED on P4. 
    
      EE_DEVICE_ADDR = $A0                                  ' EEPROM assigments
    
      SD_DO  = 0                                            ' SD card pins
      SD_CLK = 1
      SD_DI  = 2
      SD_CS  = 3
    
      PG_SIZE  = 64
    
    obj
    
      term     : "FullDuplexSerial"                         ' for terminal output
      i2c      : "Basic_I2C_Driver_1"                       ' EEPROM driver
      aes      : "AES"                                      ' AES encryption engine
      sd[ 2 ]  : "fsrw2_6B"                                 ' SD card driver
      hash     : "SHA-256" 
      num      : "Numbers"
    
    var                                                     
    
      byte buf[PG_SIZE]
      
    pub main | b, c, temp, wdcnt, wd, i, r, tmp, bytesread, value, place, x 
    
      term.start(31, 30, %0000, 115_200)                    ' start terminal using PST
      i2c.initialize(28)                                    ' initialize I2C object
    
      pause(750)                                            ' pause for PST
    
      term.str(string("Boot... ", 13)) 
    
      term.str(@model)                                      ' display device name on reset  
      term.str(@version)                                    ' display version number on reset
    
      checkupdate
    
    PUB checkupdate | check, fsize, addr
    
    '' Checks for mounted SD card and presence of "update.pgm"
    '' -- if "update.pgm" is on SD card the contents are loaded into the EEPROM
    ''    and the Propeller is rebooted
    
      check := \sd.mount(0)
      if (check == 0)
        term.str(string("1. SD card mounted.", 13))
        check := sd.popen(@NewFirmware, "r")                        ' look for update
        if (check == 0)
          term.str(string("2. Found update UPDATE.PGM.", 13))
          fsize := sd.get_filesize                                  
          if (fsize == 32768)                                       ' check 32K (ee image)
            term.str(string("   -- size is correct", 13))
            term.str(string("3. Updating EEPROM...", 13))
            BlinkLed(1, 0, RDR_ERR) 
            addr~ 
            repeat constant(32768 / PG_SIZE)                        ' loop through pages
              sd.pread(@buf, PG_SIZE)                               ' read one
    '          check := i2c.putpagex($A0, addr, PG_SIZE, @buf)       ' write it  WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit
              check := i2c.WritePage(i2c#BOOTPIN, EE_DEVICE_ADDR, addr, @buf, PG_SIZE)       ' write it  WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit    
              if (check == i2c#NAK)                                 ' if problem
                term.str(string("   -- EE write error", 13))
                quit                                                ' abort
              addr += PG_SIZE                                       ' else next page
            term.str(string(13, "   -- update complete", 13))
            BlinkLed(5, 0, RDR_ERR) 
            pause(2_000)
            sd.popen(@NewFirmware, "d")                             ' delete update file
            sd.pclose
            reboot                                                  ' restart device
          else
            term.str(string("   -- bad file size; update aborted", 13))
        else
          term.str(string("   -- no update file; update aborted", 13))
      else
        term.str(string("No SD card; update aborted.", 13))   
          
      sd.pclose
        
    PUB BlinkLed(blink_rate, mode, pin)
    
      outa[pin] := mode       ' 1: solid, 0: flashing (depending on frqa)
      dira[pin] := 1
      ctra := constant(%0_00100_000 << 23) | pin
      case blink_rate
        1:   
          frqa := 100
        2:   
          frqa := 150
        3:   
          frqa := 200
        4:   
          frqa := 250
        5:   
          frqa := 350
        6:   
          frqa := 500
                                                                                                                    
    pub pause(ms) | t
    
      t := cnt
      repeat ms
        waitcnt(t += MS_001)
    
    DAT
    
    NewFirmware byte "update.pgm", 0    
    
    model       byte "Rev2Test", 13, 0
    version     byte "FW: Main V2.3", 13, 0
    
    

    Please note that I use a 10Mhz crystal so you'll need to change that to whatever you use. Both pieces of code are exactly the same with these exceptions- Version 2 has 2 more objects and there is a couple variances in verbiage in the DAT section otherwise strings are same size.

    Since playing with this some more I noticed if I comment out the 2 additional objects in Version 2 that are not present in Version 1 then the Prop will boot up again after I update via SD card but the code did not get updated. Still shows Version 1 after PST indicates that the process is done. So I think the main problem is the EEPROM is not getting updated for some reason.

    My board uses a Microchip 25LC512-E/ST EEPROM.

    Any help with this greatly appreciated.

    Thanks.
    Don
  • Don MDon M Posts: 1,652
    edited 2014-04-29 16:34
    I think I found the problem... stay tuned.
  • Don MDon M Posts: 1,652
    edited 2014-04-29 16:44
    Ok the problem appears to be self inflicted. Somewhere I got a copy of the method checkupdate that was modified to work with the generic i2c driver. I changed it to Jon's jm_i2c_driven driver and that fixed it.

    This line was the problem:
       check := i2c.WritePage(i2c#BOOTPIN, EE_DEVICE_ADDR, addr, @buf, PG_SIZE)       ' write it  WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit 
    
    

    I replaced it with this line from his demo program:
       check := i2c.putpagex($A0, addr, PG_SIZE, @buf)       ' write it  WritePage(SCL, devSel, addrReg, dataPtr, count) : ackbit
    
    

    Seems to be working now but will do further testing.

    Jon- you mentioned that this was some outdated code. Any updates or enhancements?

    Thanks. Marking solved for now.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-04-29 17:02
    Ok the problem appears to be self inflicted.

    Excuse me while I put on my shocked face....

    And I said the code was a little dated, not outdated. It works.
  • Don MDon M Posts: 1,652
    edited 2014-04-29 17:24
    This must be attack Don week in the forum.

    I apologize to everyone that I'm not as sharp a programmer as many here but some things aren't apparent to me at first. I'm sure it appears as though I'm just asking for someone to write code. If you only knew how much I go through and write myself before asking for help. This has been a continual learning experience for me the last number of years as I'm sure it will always continue to be.

    For the most part the forum has always felt like a welcome environment but lately there seems to be an angry undertone to some replies. It's like walking on egg shells to make sure you don't ask the "wrong question" or try to phrase the question in the wrong manner.
Sign In or Register to comment.