Shop OBEX P1 Docs P2 Docs Learn Events
Attempt at using Vmusic2 as Firmware update — Parallax Forums

Attempt at using Vmusic2 as Firmware update

T ChapT Chap Posts: 4,223
edited 2008-11-27 13:51 in Propeller 1
I incorporated a Vmusic 2 onto a board and the mp3 aspect is working fine. Since there is a USB thumbdrive present at all times, I thought that the drive would serve as a nice method to remotely update the Propeller software. Below is what I wrote to FTDI, and the response is not encouraging, at least from my interpretation.

Is anyone here familiar enough with the Vmusic2 and Vinculum music firmware to know if what I am asking is doable?

Thanks
Question said...
I have produced a prototype using the Vmusic2 schematic, I flashed the Vinculum with the music firmware, everything is working great as far as music commands.

I am looking into a method to allow a user to upgrade my processor software by copying the newest rev off my site, putting it on the usb drive, then on inserting the thumbdrive, the processor gets a command from Vinculum stating a drive is inserted. After that command is received, the processor reads the directory looking for a file named for example FW_1.13, upon finding a file with a number higher than a previously stored firmware revision, the user has an option come up on LCD that states "New firmware found. Do you wish to update your firmware now? Press yes/no. On "yes" the processor copies the file contents to a spare EEPROM, then verifies the transfer, then copies the contents to the main boot EEPROM, which is a simple read/write routine. My question is, does the recent music firmware offer capability to do what I have described?

Response said...
For upgrading your processor firmware you need some kind of bootloader running on your processor. And in fact that bootloader should read the files from thumb drive and carry out the flash operation. Since this transfer and reading is processor specific we cannot implement this in VMUSIC firmware. This is something you have to write on your own.

I already have a bootloader, so I am not sure he is understanding my situation. Any thoughts appreciated. I want to transfer a file or parts of a file to an EEPROM from the usb drive, then reset the Prop.

Post Edited (TChapman) : 11/21/2008 10:34:53 PM GMT
«1

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-21 22:42
    The music firmware does not have the capability of doing this automatically. It has some of the pieces. For example, the Vinculum chip will put out a status message when a drive is inserted. The Vinculum chip provides a command to list a directory and it has a command to read a file. It's up to a program in the Propeller to watch for the drive insertion message, to look through a directory listing for a particular file name, to copy the file to a 32K page of EEPROM and verify it.

    The bootloader in the Propeller's ROM only deals with the serial connection to the Propeller Tool on a PC and an EEPROM. FTDI was talking about you needing the equivalent that works with their Vinculum. You'll have to write it or find someone else to write it. It hasn't been done yet.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-21 22:49
    Mike Green said...
    It's up to a program in the Propeller to watch for the drive insertion message, to look through a directory listing for a particular file name, to copy the file to a 32K page of EEPROM and verify it.

    Yes, this is what I am wanting to know if I can do, to read a file, buffer it in ram while it gets written to the temp EEPROM, then re-read the file to verify the transfer, then copy the temp EEPROM parts to the main EEPROM location for read on the next boot. I will dig into the Vinculum and music firmware notes this weekend, but just wanted to not waste time if someone has already been down this road and determined is was not doable. I understand that it would be a major challenge to boot off the usb drive, that is not a consideration.

    Thanks Mike.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-21 23:01
    Table 5.4 and section 5.6.3 in the Vinculum Firmware Manual show the insertion messages. The CD (change directory) and DIR (directory listing) commands would allow you to monitor the contents of a directory to look for a "most recent / new" firmware file name. The OFR (open file for reading) and RDF (read file) command would be used to read the firmware file a block at a time. Since many 64K byte and larger EEPROMs (24LC512 and 24C512) use a 128 byte page size, that's a good size unit to handle since it would require just one EEPROM write cycle to write the whole page.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-21 23:08
    Thanks for the information, I am printing the manual now, but from your notes I think this is very doable.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-21 23:14
    Would the process to get the file to the drive be Compile and Save Binary? Then drop the binary on the drive as is?

    Having never experimented with the binary file, I am assuming it is the carbon copy of what would exist starting at $00 on the boot EEPROM.
  • BradCBradC Posts: 2,601
    edited 2008-11-22 05:33
    Yes it is, but you really want the .eeprom file rather than the .binary.

    With the .eeprom you get what would be in the eactual eeprom after the bootloader has written it there. The binary is just a short version that relies on the propeller bootloader to add some extra guff prior to writing it out.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Pull my finger!
  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-22 05:40
    The main "extra stuff" is enough zeroes to pad out the file to 32K. If you zero the rest of the first 32K of the EEPROM yourself, you can also use the .binary file. The loader that's part of FemtoBasic doesn't care if the rest of the EEPROM is zeroed. It uses the program length stored in the parameter block in the first 16 bytes of the file. The checksum there has to be correct, but only up through the recorded program length. The rest of the EEPROM would normally be zero and wouldn't affect the checksum anyway.
  • BradCBradC Posts: 2,601
    edited 2008-11-22 05:56
    Mike Green said...
    The main "extra stuff" is enough zeroes to pad out the file to 32K. If you zero the rest of the first 32K of the EEPROM yourself, you can also use the .binary file. The loader that's part of FemtoBasic doesn't care if the rest of the EEPROM is zeroed. It uses the program length stored in the parameter block in the first 16 bytes of the file. The checksum there has to be correct, but only up through the recorded program length. The rest of the EEPROM would normally be zero and wouldn't affect the checksum anyway.

    Don't forget the two extra longs ($FFF9FFFF) at the beginning of the stack segment. They are not in the .binary file also and contribute to the checksum.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Pull my finger!
  • T ChapT Chap Posts: 4,223
    edited 2008-11-22 06:02
    OK, great, thanks Brad, working on it now. I can't believe how simple this really is to update from a USB drive. I am setting the steps prior to reading the file:

    1. Check the drive for a file with the beginning section of SWREV(+ word)
    2. Extract the numbers following the prefix as a word
    3. Check the current software rev word that is stored on the spare EEPROM as SWCurrentREV i.e. dec 12
    4. If the number on the drive > SWREVX, display newer SW found, ask if you want to update now
    5. If yes, start the transfer, OFR (open file for reading) then RDF (set read file length at 128) read file into UpdateSWArray[noparse][[/noparse]128]
    6. Write UpdateSWArray to the first page starting at $00, set increment counter for next iteration read and write
    7. Go back and read the next block, read and write until 32k has been read and written.
    8. Read all bytes again, compare against spare EEPROM
    9. If errors, fix the errors or report a problem.
    10. Transfer from Spare EPPROM to boot EPPROM
    11. REBOOT
    12. Hope

    OK, there are some 50 preferences stored on the spare EEPROM starting at $7000, I suppose I need to anticipate the future program length maximum, and assuming $7000 is a safe bet, do not copy from USB past $6FFF. But, when transferring to the boot EEPROM, I will write the whole 32k, the boot will ignore the preferences stored above $7000.

    There is a verify from USB to Spare EEPROM, but no verify from Spare to boot EEPROM. Should I add the extra measure of comparing Spare to boot? OR USB to BOOT prior to REBOOT?

    Post Edited (TChapman) : 11/22/2008 6:09:23 AM GMT
  • T ChapT Chap Posts: 4,223
    edited 2008-11-22 06:05
    BradC said...
    Mike Green said...
    The main "extra stuff" is enough zeroes to pad out the file to 32K. If you zero the rest of the first 32K of the EEPROM yourself, you can also use the .binary file. The loader that's part of FemtoBasic doesn't care if the rest of the EEPROM is zeroed. It uses the program length stored in the parameter block in the first 16 bytes of the file. The checksum there has to be correct, but only up through the recorded program length. The rest of the EEPROM would normally be zero and wouldn't affect the checksum anyway.

    Don't forget the two extra longs ($FFF9FFFF) at the beginning of the stack segment. They are not in the .binary file also and contribute to the checksum.

    Well, seems like extra work to do this, why not just use the .eeprom, and transfer up to $6FFF leaving my prefs in tact? Then I don't have insert the extra longs.

    I just saw your post Mike, thanks for those suggestions too.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-22 07:04
    To make things simpler I will do what FTDI does for firmware updates:

    Download from their site the newest update, rename the file to a fixed name they assign for it, put the file on a thumbdrive, insert the drive and it automatically updates. I see no point to try to determine the revision on the drive by name, if a certain file name is there, update. The user can just as easily overwrite the files or trash them as needed. The revision can live as a variable which can be displayed when needed to get the current revision.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-22 14:42
    BradC,
    Thanks for reminding me about the $FFF9FFF9. The FemtoBasic loader puts these in after reading the program from EEPROM or an SD card file when it's directly loading a program.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-22 20:51
    PUB SWupdateSet
        ser.str(2, string("SCS", CR)) 
        ser.str(2, string("IPH", CR))
        repeat
         ReadSetupKeys   'i2c read buttons
         if setupkeys == yesbut
           ser.str(2, string("OPR update" , CR))    '3E successful command  here
           spk.beep(19, 2500, 200)
           if receiveStr(@MonitorUSBbuffer,3) <> CR
             quit
           if   MonitorUSBbuffer[noparse][[/noparse]0] == $4E   
              gotoxy(0, 0)
              ser.str(3, string("No Drive Present"))
           if   MonitorUSBbuffer[noparse][[/noparse]0] == $43
              gotoxy(0, 0)
              ser.str(3, string("Update Not Found"))    'file not found
           if   MonitorUSBbuffer[noparse][[/noparse]0] == $3E            '3E success here
              gotoxy(0, 0)
              ser.str(3, string("Update Found"))
              repeat while setupkeys == yesbut     'trap the button press until released
                 ReadSetupKeys
              gotoxy(1, 0)
              ser.str(3, string("Continue? Y/N"))
              if setupkeys == yesbut
                'ser.str(2, string("RDF", $80 ,CR))      ' $80 = 128 bytes to read,but any size fails "42= bad command"
                ser.str(2, string("RDF 128",CR))          '"42= bad command"
                'ser.str(2, string("0x0B","0x20", "0x80", "0x0D"))   "42= bad command"
                if receiveStr(@MonitorUSBbuffer,128) <> CR
                 quit
                WritePage(eeprom2, $0000, @MonitorUSBbuffer, 128)
                gotoxy(1,0)
                ser.str(3, string("Write Complete      "))
              if setupkeys == nobut
                gotoxy(0,0)
                cls
                ser.str(3, string("Update Canceled "))
                repeat while setupkeys == nobut     'trap the button until but released
                  ReadSetupKeys
    
    
           gotoxy(1, 14)
           ser.hex(3, MonitorUSBbuffer[noparse][[/noparse]0], 2)    'show response byte 1 for reference
    
    
         if setupkeys == nobut
           gotoxy(0,0)
           ser.str(3, string("Update Canceled"))
           ser.str(2, string("CLF update" , CR))
           if receiveStr(@MonitorUSBbuffer,3) <> CR
             quit
           spk.beep(19, 2500, 200)
    
    
         repeat while (setupkeys == yesbut) or  (setupkeys == nobut)
              ReadSetupKeys
    
         if trap
            repeat while (setupkeys == leftbut) or  (setupkeys == rightbut)
               ReadSetupKeys
         if  (setupkeys == leftbut) or  (setupkeys == rightbut) or (setupkeys == setupbut)
            return stop
         trap~
    




    Some stranger behavior, I get a 3E successful response on OPR file, but I get this response even if I rename the file on the drive, so this can't be right. There should be file not found when I rename it.

    Also, I get a 42 "bad command" response when doing RDF 'size'.

    The drive is working perfectly for all mp3 purposes, so I know there is not a drive problem.

    Any suggestions appreciated.
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2008-11-22 22:11
    Hi, I think the format for RDF should be one of the following

    ser.str(2,·string("RDF ",·0,0,0,$80,CR))

    ser.str(2,·string("RDF ",0,0,0,128,CR))

    the RDF command should be after the file has been opened.

    Jeff T.·····
  • T ChapT Chap Posts: 4,223
    edited 2008-11-23 01:29
    Thanks for the info Jeff, the commands are correct according to the manual. The problem seems to be that the Vinculum likes my mp3 files and I can do an Open For Read on those and get a success response, but the file that I saved from bst called "update" gives file not found response. I think when I get a file n a format it likes things will be ok, but I am not sure what it doesn't like about the file, it is just an .eeprom export from bst, but there is no extension on it.

    I made an eeprom file from the Propeller tool too, as well as a binary from bst, still it gives errors on finding the file, but finds my mp3's ok.

    Post Edited (TChapman) : 11/23/2008 1:53:52 AM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-23 02:24
    There might be an extension after all with BST not showing it. Do a directory listing on the memory stick while it's on the PC and make sure you have Windows configured to show the file extensions.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-23 02:26
    I will check that, but I did do a save as from bst called p.eeprom and then trying to open for read p.eeprom and had no luck, I will see if I cfan find some extensions hiding though.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-23 02:50
    Yes the extensions were part of the problem in a sense, although I did test with p.eeprom, but you can't use extensions with more than 3 characters past the dot. So it is seeing the files now.

    Thanks for the input.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-23 19:24
    From the Vinculum/UMfirmware manual you would think that all is required is to send an Open File For Read command, and upon a success response then send a Read File command containing the size for it to send you. The manual states that it has it's own internal pointer to keep track of where it is, so you don't need to tell it where to start reading unless you want to SEK forward to any location. However, even on a success command on Open and then subsequent Read Size, nothing comes back.

    What have done is set up a statement using full duplex using the basics of the common ReceiveStr, only I pulled out the if statement looking for CR or TAB, just let it count 128 bytes, return "0" when done.

    So the jist of the main code is:
    
    ser.str(2, string($0E, $20, "ppp", $0D)     'send hex OPRs
              'RecieveStr , CR delimited string to get response of 3E, successful previous command
    ser.str(2, string("0x0B","0x20", "0x80", "0x0D"))   'send RDF size, 128 bytes, have also tried 8 byte
    if receiveStr(@MonitorUSBbuffer,128) == 0
                 quit
    
    



    The ReceiveBlock locks up waiting on a response.

    If I change the file name in the code or on the drive, it will respond File Not Found.

    Upon booting and sending the first CR command to check on status, it responds with some initial info, probably disk info, serial, revision etc, but ends up with successful command response, so I let it get past all it's initial boot response first prior to sending the file commands.

    Any suggestions on things to try would be very welcome.
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2008-11-23 19:54
    Hi, in my earlier post the thing I thought of importance was the part of the RDF command that specified the number of bytes to read. I was referencing the VDAP firmware at this link http://www.parallax.com/Portals/0/Downloads/docs/prod/comm/VDAPFirmwareSpec.pdf page 11.

    The command was formatted $0B,$20, byte, byte, byte, byte ,$0D which would be $0B,$20,·0,0,0,$80 ,$0D

    I apologize if I am reading the wrong manual or if you have already discounted this but I have to mention it again because I feel it could be important smile.gif

    regards

    Jeff T.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-23 22:49
    Thanks for the suggestions Jeff. You have a good point, the vdap does show different methods, the Vmusic shows simply "dword" as the parameter, not written as 4 bytes, but the vdap shows 4 separate bytes. I think you are right though, FTDI manuals and schematics are always wrong on some amount of issues.

    After boot, the first command that is sent the Vinculum(doesnt seem to matter what command, CR is fine, it starts sending out its basic info, maybe serial, Firmware etc, then it sends out 3E to say it is ready. Interesting thing is, these first few bytes (maybe 32 -40, I forget) they seem to want to be sent in multiples of 4 bytes, and want to get a CR in return for each 4 bytes before moving to the next set.

    I have made some progress using different methods to send the commands, below is half way working. The way the RDF ( file and specify how much to read) works is, you tell it the command, then state the size to get. If you tell it a size larger than the actual file, it will send the right amount, but it will pad the excess if you said too much. It seems to pad with FE. The problem is, that regardless of what size tell it, it thinks I am sending some massive number, and it sends the entire eeprom file, plus infinity FE's past the file. I tell it to get 8 bytes, it goes past the file into infinity FE, 32, 64, 128, all the same issue.

    So, I set up a loop to display data as fast as possible on LCD, so I can see the correct file wizzing by, there are several obvious clumps of zeros, then the FE's.

    Also, for some reason it is losing the first 12 or 16 bytes somehow when it copies to the spare eeprom, the spare starts several longs late, maybe 16 if I recall.

    The Vinculum is rather picky about how you send it commands, I am in SCS short command and hex mode, but it still doesn't like me sending the file length in hex, no response, but using 0x00 or similar it responds.

    Below is what is semi starting to show progress, although the infinity transmission is the real snag.


    PUB SWupdateSet
        ser.str(2, string($0E, $20, "ppp", $0D))  'send command to  open file for read, gets success
        repeat
         ReadSetupKeys
         gotoxy(0,0)
         ser.str(3, string("Update Software?"))  'lcd
       
         if setupkeys == yesbut
           spk.beep(19, 2500, 200)
           ser.str(3, string("Reading Drive..."))  'lcd
          'not sure if hex is sent msb, or lsb  
           ser.str(2, string($0B, $20,"0x80","0x00", "0x00", "0x00", $0D)) '  '00000080 or 08000000 is same issue
           if ReceiveBlock(@MonitorUSBbuffer,128) == -1
             WritePage(eeprom2, $0000, @MonitorUSBbuffer, 128)  'losing some bytes here
             gotoxy(1,0)
             ser.str(3, string("Write Complete"))
             spk.beep(19, 2500, 200)
             waitcnt(80_000_000 + cnt)
             repeat while setupkeys == yesbut
                ReadSetupKeys
         if setupkeys == nobut
    
           gotoxy(0,0)
           cls
           repeat while setupkeys == nobut
            ser.str(3, string("Update Canceled "))
            ser.str(2, string($0D))
    
            ShowMonitor
    
            ReadSetupKeys
            spk.beep(19, 2500, 50)
    
    
         repeat while (setupkeys == yesbut) or  (setupkeys == nobut)
              ReadSetupKeys
    
         if trap
            repeat while (setupkeys == leftbut) or  (setupkeys == rightbut)
               ReadSetupKeys
         if  (setupkeys == leftbut) or  (setupkeys == rightbut) or (setupkeys == setupbut)
            return stop
         trap~
    
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2008-11-24 00:09
    Hi, I think you are getting on track piece by piece, I believe that 0,0,0,$80 is right , MSB first.

    Not being sure of the Spin functions I'm not 100% on whats going on but it seems like you are enclosing the "bytes to read" in quotation, wouldn't that send a string rather than a number, what I mean is doesn't "0x80" actually transmit the string of hex values 30-78-38-30.

    I might try something like ser.str(2,·string($0B,·$20,$0,$0,$0,$02,·$0D))·just to see if I could read two bytes to begin with or ser.str(2,·string($0B,·$20,0,0,0,2,·$0D))·, I might even try the same program code in ASCII mode ("IPA").

    Jeff T.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-24 00:35
    Unsoundcode said...

    I might try something like ser.str(2, string($0B, $20,$0,$0,$0,$02, $0D)) just to see if I could read two bytes to begin with or ser.str(2, string($0B, $20,0,0,0,2, $0D)) , I might even try the same program code in ASCII mode ("IPA").

    Yes the device will respond to ascii, hex, etc. What you just wrote was what I have tried a lot: ser.str(2, string($0B, $20,$0,$0,$0,$02, $0D)) but the Vinculum just sits and does nothing. It only starts responding (wrongly) with what I have posted. I have tried all ascii in IPA as well, seems to make no difference, there is something still not quite right.

    I will write FTDI, they are usually good about getting back in a day or so.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-24 08:00
    After switching to IPA (ascii) mode, I finally started getting something close to right, I am losing bytes between the command to read the drive and the spin loop to get the response, so I need to set up an cog that is waiting to catch the response prior to sending the commands, but getting closer.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-26 02:40
    Update.

    You can't send hex data to the Vinculum using ser.str, you must use ser.tx to send hex values.

    Here is what works:

    [noparse][[/noparse]code]

    'seek to where you want to start reading
    ser.str(2, "SEK"))
    ser.tx(2, $20))

    'word value of where to start reading in the file that is already open
    ser.tx(2, $00))
    ser.tx(2, $00))
    ser.tx(2, $00))
    ser.tx(2, $00))
    ser.tx(2, $0D)) 'CR



    'RDF "size" read the file, specify the amount you want to read.
    ser.str(2, "RDF"))
    ser.tx(2, $20))

    'word value of amount of data you want to read at one time:
    ser.tx(2, $00))
    ser.tx(2, $00))
    ser.tx(2, $00))
    ser.tx(2, $80)) 'read 128 bytes
    ser.tx(2, $0D)) 'CR
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2008-11-26 06:04
    Great to hear the update I was curious as to your progress, it must be very satisfying.

    Jeff T.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-26 06:35
    Thanks Jeff, yes I had it working with IPA, but ascii mode is more awkward with a processor, I am glad to have solved the mystery, lesson learned. Whats good is that when you have these issues, you learn about 20 times more about the issue than you would if there were no problems, in this case I now know the Vinculum manuals inside out, not by choice though.

    I am actually surprised we don't see a lot more of Vinculum posts. The ability to read and write USB drives with this kind of simplicity is amazing.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-27 04:16
    Hey Guys

    I just read the USB drive containing the .eeprom file into the eeprom2(24cl256) starting at $00 up to $6FFF (At $7000 I am storing preferences). I then copied 64 bytes at a time from eeprom 2 to eeprom 1 starting at $00 up to $6FFF. There is a method to scroll through the lcd and get a visual of the bytes on each eeprom, they appear identical except after $7000. On the .eeprom file, there is nothing up that high except at $7F18 FF FF F9 FF FF F9 FF, which is present on the boot drive as I did not erase that high.

    Scanning and looking from $0 to $6FFF looks identical, but the Prop will not boot from it. Any suggestions on what may be missing?
  • BradCBradC Posts: 2,601
    edited 2008-11-27 04:29
    I just looked at the boot code and it does not do a checksum when loading from eeprom, so provided the bytes are the same (it _does_ check for a valid PBASE=0x10) then it should boot and run. There must be something obviously wrong. It's a very simple boot routine.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cardinal Fang! Fetch the comfy chair.
  • T ChapT Chap Posts: 4,223
    edited 2008-11-27 04:31
    Ok, I will write a routine to compare byte by byte for the entire file tp to $7000 and see if there is a flaw. Thanks
Sign In or Register to comment.