Shop OBEX P1 Docs P2 Docs Learn Events
SD2.0 Full FAT32/16 File Sytem Driver - You there! Yes you, viewing this forum. - Page 4 — Parallax Forums

SD2.0 Full FAT32/16 File Sytem Driver - You there! Yes you, viewing this forum.

1246710

Comments

  • Bill HenningBill Henning Posts: 6,445
    edited 2010-06-12 18:10
    Hi Kye,

    I tried to make a quick and dirty port to PropCade of the lonesock version you posted on this page.

    Unfortunately it is not mounting my test uSD card, a 32MB SanDisk formatted for FAT16.

    fsrw26 speed test works on it fine.

    As long as I don't run VMCOG at the same time, the changes to your code are minimal - I just added two lines to shell to select the uSD, and changed the necessary pin definitions.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.mikronauts.com E-mail: mikronauts _at_ gmail _dot_ com
    My products: Morpheus / Mem+ / PropCade / FlexMem / VMCOG / Propteus / Proteus / SerPlug
    and 6.250MHz Crystals to run Propellers at 100MHz & 5.0" OEM TFT VGA LCD modules
    Las - Large model assembler Largos - upcoming nano operating system
  • KyeKye Posts: 2,200
    edited 2010-06-12 20:00
    Yeah, the lonesock port failed to mount alot for me also... I probably don't know how to use it properly as it has "issues" with mounting...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Bill HenningBill Henning Posts: 6,445
    edited 2010-06-12 20:06
    Thanks, I will try your non-lonesock version [noparse]:)[/noparse]
    Kye said...
    Yeah, the lonesock port failed to mount alot for me also... I probably don't know how to use it properly as it has "issues" with mounting...
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.mikronauts.com E-mail: mikronauts _at_ gmail _dot_ com
    My products: Morpheus / Mem+ / PropCade / FlexMem / VMCOG / Propteus / Proteus / SerPlug
    and 6.250MHz Crystals to run Propellers at 100MHz & 5.0" OEM TFT VGA LCD modules
    Las - Large model assembler Largos - upcoming nano operating system
  • KyeKye Posts: 2,200
    edited 2010-06-13 04:00
    Oh, how did you want me to mod it so that it will support tristating?

    My driver supports polling of the SD card regularly however, so that feature won't be active if you tristate the lines.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Bill HenningBill Henning Posts: 6,445
    edited 2010-06-13 12:17
    I have to think a bit about how to share the SPI bus on PropCade. Probably I will have to use LOCKSET/LOCKCLEAR in VMCOG and the low level SD driver.

    The way PropCade multiplexes SPI is:

    3 bit SPI device address on P9/P10/P11 (LSB on P9, MSB on P11)

    0-5 are SPI DIP/SOIC8 ram/flash devices
    6 is the I/O expander
    7 is the uSD socket

    The reason I did it this way is that the four pin group from P0-P3 appears like a regular SPI group - /CS,CLK,MOSI,MISO

    So I do need the SD card to totally release the SPI bus after a transaction, and as soon as I figure out the locking scheme, I need it to stuff 7 into P9-P11 after getting the lock, before asserting /CS.

    I will probably use LOCK 1 for SPI multiplexing (I use LOCK 0 on Morpheus for memory contention control, and the new Morpheus+ also multiplexes one SPI channel)

    Basically, on PropCade, I need to share the SPI bus between VMCOG, SD, and the I/O expander used for joysticks.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.mikronauts.com E-mail: mikronauts _at_ gmail _dot_ com
    My products: Morpheus / Mem+ / PropCade / FlexMem / VMCOG / Propteus / Proteus / SerPlug
    and 6.250MHz Crystals to run Propellers at 100MHz & 5.0" OEM TFT VGA LCD modules
    Las - Large model assembler Largos - upcoming nano operating system
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-06-13 14:44
    Hi Kye,

    With a DOS it gets a bit tedious removing the sd card all the time, so I've been experimenting with xmodem. I started at 110 baud with lots of delays, then 1200 and have now pushed it up to 38k.

    I have yet to add saving the file, but it worked as a seperate program so I think it should work (you can see the commented out test lines). There will be some debugging and I need to add timeouts, but this does download a 100k file with no problems.

    In the code below, where I write out the bytes to the fat file I'm using this:
                  repeat i from 3 to 130
    '               fat.writebyte(XmodemIn[noparse][[/noparse] i ])                 ' save the 128 bytes
    
    



    Is there a more elegant way, eg telling the fat driver I want to save 128 bytes with the pointer @xmodemin array, but start at address 3?


    VAR
       byte XModemIn[noparse][[/noparse]132]
       byte validpacket
       word PacketNumber
       byte ErrorCounter
       word i
       byte OnesComplement
       word Checksum
    PRI programXmodem(stringPointer) 
    
      ifnot(str.stringCompareCI(string("xmodem"), stringPointer))
        PrintString(string("creating file xmtest.txt"))
    '    fat.deleteEntry(string("xmtest.txt")) ' delete any files with this name
     '   fat.openFile(fat.newFile(string("xmtest.txt")), "W") 'create a new file
         sio.rxflush(0) ' start with clear receive buffer
         errorcounter:=0 ' reset error counter
         sio.tx(0,21) ' send a NAK to start things off
         packetnumber:=1            ' packet number 1
         repeat
            validpacket :=255 ' equals true
            XModemIn[noparse][[/noparse]0]:=sio.rx(0) ' read in one byte
            'vt100.hex(xmodemin[noparse][[/noparse]0],2)
            'vt100.str(string(" "))
            if XmodemIn[noparse][[/noparse]0] == 4                               ' finish byte
              errorcounter:=255                             ' signifies finish with no errors
              vt100.str(string("finish byte 4"))
            else  
              if XmodemIn[noparse][[/noparse]0] <> 1                             ' not 1
                validpacket:=0                             ' invalid packet
                errorcounter++                              ' add one to error counter
                vt100.str(string("err1"))
              else                                          ' 1= a valid start byte for a packet
                repeat i from 1 to 131
                  XmodemIn[noparse][[/noparse] i ]:=sio.rx(0)             ' read in rest of packet
                  'vt100.hex(xmodemin[noparse][[/noparse] i ],2)
                  'vt100.str(string(" "))
                repeat while packetnumber > 255              ' calculate the packet number always <256
                    packetnumber:=packetnumber-256
                onescomplement:=255-packetnumber            ' calculate the ones complement
                if packetnumber <> XmodemIn
                  validpacket:=0
                  errorcounter++
                  vt100.str(string("err2"))
                  
                if XmodemIn <> onescomplement              ' ones complement not correct
                 validpacket:=0
                 errorcounter++
                 vt100.str(string("err3"))
                 
                checksum:=0                                  ' calculate the checksum
                repeat i from 3 to 130
                checksum:=checksum+XmodemIn[noparse][[/noparse] i ]
                repeat while checksum>255                   ' round to under 256
                    checksum:=checksum-256
                  
               if checksum <> XmodemIn[noparse][[/noparse]131]                   ' checksum not valid
                 validpacket:=0
                 errorcounter++
                 vt100.str(string("err4"))
                               
               if validpacket == 255                         ' packet is valid so save it
                  repeat i from 3 to 130
    '               fat.writebyte(XmodemIn[noparse][[/noparse] i ])                 ' save the 128 bytes
                 packetnumber++                             ' increment packet number
                 sio.tx(0,6)                        ' send a ACK and wait for the next packet
                 vt100.str(string("ACK"))
                 'vt100.dec(packetnumber)
                 vt100.out(13)
                 vt100.out(10)
               else
                 sio.tx(0,21)                       ' send a NAK as the packet was corrupted
                 vt100.str(string("NAK"))
         until errorcounter>10
         ' need to add the final bytes to finish up and close file
         ' looking at xmodem.asm I think it is supposed to send an ACK here, not a NAK, the text is wrong
         sio.tx(0,6)
    
         vt100.str(string("finished"))
    '    fat.CloseFile
        
        abort 0
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller

    Post Edited (Dr_Acula) : 6/13/2010 2:50:12 PM GMT
  • KyeKye Posts: 2,200
    edited 2010-06-13 14:53
    fat.writeData(address, count) ....

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • jazzedjazzed Posts: 11,803
    edited 2010-06-13 15:17
    Dr_Acula said...

    With a DOS it gets a bit tedious removing the sd card all the time, so I've been experimenting with xmodem.
    @DR_A: Quick question. Sorry if it's too OT.

    I did this xmodem thing too, but now I'm running Vista (involuntarily) and there is no hyperterm.
    Can you recommend a link to a good xyzmodem client application download?

    Thanks,
    --Steve

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Pages: Propeller JVM
  • StefanL38StefanL38 Posts: 2,292
    edited 2010-06-13 17:31
    hi jazzed,

    how about br@y's terminal ?

    has even macros and a scripting language to interact with the other side conditionally

    best regards

    Stefan
  • DDSDDS Posts: 16
    edited 2010-06-13 20:08
    This is possibly in the wrong thread but...

    I am new to the SD driver so excuse my ignorance...

    I am using the FSRW 2.6 driver and it is working but I have to constantly remove the SD card and put it into a PC & read it there to get it to work again with the propeller. Is this what some refer to it getting "stuck"?
    Is there a work-around? I have tried unmounting/remounting but it doesn't help.

    I am using the "mb_rawb_spi" driver
    Thanks in advance.

    Don
  • KyeKye Posts: 2,200
    edited 2010-06-13 20:21
    Mmm, I just know mine does not have that problem. I've had a similar issue when using the FSRW block driver sometimes. I think it has to do with multiblock mode.

    I don't know a work arround. PM lonesock.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • jazzedjazzed Posts: 11,803
    edited 2010-06-13 20:32
    StefanL38 said...
    hi jazzed,
    how about br@y's terminal ?
    I don't think that supports xmodem for binary transfers. I already have code for xmodem.
    It is a good protocol like y/z modem, kermit etc... for transfer to SD (barring IP or USB support).

    Hopefully @DR_A will have a good xyz modem PC application download link.

    Again, sorry if this is too OT.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Pages: Propeller JVM
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-06-14 00:47
    Thanks kye, I figured it would be something simple.

    I'm using a different serial driver as something is going wrong with the fat32 serial driver with a 132 byte packet, somewhere between bytes 15 and 31 it merges two bytes into one. Happens at all baud rates, even down to 110 baud. Just finding this took a serial sniffer program and printing every byte in hex on the vga screen and I'm still not sure why this happens as the buffer for both serial drivers is 256 bytes. Maybe it isn't between 15 and 31 - maybe the other bytes that go through at startup puts it there and that is where it cycles from 255 to 0. I figured I would get xmodem working first and go back to that.

    Once I get it working with Rx, I'll do the Tx half. Then two propeller boards running KyeDOS can send files to each other. (just use a 3 wire null modem cable with wires 2 and 3 crossed over).

    I also need to push the baud rate up to 115k.

    As for downloading froma PC, I've been using Teraterm. But I am at work so I can't post the code, and I can't download the code to the work computer to see which version is the correct one. The newer versions cost money and don't work so well with xmodem. I *think* this is the correct version - about 2002 vintage, runs on xp (and so hopefully vista) and has xmodem www.tucows.com/preview/195282 But if not, when I get home I'll post the code. I have some other terminal programs too, but the one I don't use much is hyperterminal. I've also got my own code in vb.net. Ultimately, if this works, maybe BST could include xmodem, but that is a long way down the track.

    @DDS - I've not used fsrw much, but no problems like that with Kye's driver code. That is why I'm hooked!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller

    Post Edited (Dr_Acula) : 6/14/2010 12:54:26 AM GMT
  • KyeKye Posts: 2,200
    edited 2010-06-14 01:15
    I should write a continuity tester program for my serial port driver... Mmm, I'm gonna do that tonight.

    You keep finding errors in it Dr_Acula =).·Thanks however.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • jazzedjazzed Posts: 11,803
    edited 2010-06-14 01:52
    Dr_Acula said...
    I *think* this is the correct version - about 2002 vintage, runs on xp (and so hopefully vista) and has xmodem www.tucows.com/preview/195282
    Looks like that one does not recognize the USB ports for me on Vista.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Pages: Propeller JVM
  • KyeKye Posts: 2,200
    edited 2010-06-14 02:31
    @Dr_Acula - Okay, I just wrote up a tester program and I had no problems at any baudrates. I'm not sure what's happening with you.

    The program is atteched. It does a loop back test to make sure the data is being sent okay and stresses my driver as much as possible by transmiting 255 bytes back and forth in full duplex mode.

    I think it is a pretty good test of functionality. It works fine in my hardware. Please test it on yours.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-06-14 09:42
    Hi jazzed,

    I'm home now and able to check the download on that program. It works ok on XP. See attached.

    On my PC COM1 and COM2 are real physical serial ports. COM3 and COM4 are cheapie ebay $2 USB to D9 serial adaptors. So the list is 4 ports. That all works ok.

    Can you describe the problem a bit more? If Teraterm (or other terminal programs) are not finding the serial ports, that might suggest more a Windows problem. What is Control Panel/System/Hardware/Device Manager/Ports reporting? for example I get USB-SERIAL CH340 (COM3) when I plug in the USB to serial adaptor. Unplug it and it automatically updates the new configuration. Does Vista work the same?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller

    Post Edited (Dr_Acula) : 6/14/2010 9:48:32 AM GMT
    1008 x 670 - 126K
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-06-14 10:19
    Hi Kye,

    Transferred the first .BIN file via xmodem (I'm testing with FEMTOBASIC which is renamed FBAS1.BIN)

    Two minor errors:

    1) If the file already exists, I would like to erase it. At the moment I am manually deleting it each time and using this code with the delete routine commented out.
        'fat.deleteEntry(string("FBAS1.BIN")) ' delete any files with this name
        fat.openFile(fat.newFile(string("FBAS1.BIN")), "W") 'create a new file
    
    



    is there a way to see if a file exists, and only delete it if it is found?

    2) XMODEM pads out the last packet with ascii hex 1A. See attached for a comparison of the original file and the downloaded file. This is upsetting your checksum routine in the SD2.0_FATEngine and it is aborting with the checksum error at the bottom of this piece of code. Is there a way around this?
    PUB bootPartition(fileName) | bootSectors[noparse][[/noparse]64] '' 101 Stack Longs
    
    '' &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    '' &#9474; Reboots the propeller chip to run the selected valid spin BIN or EEPROM file.                                            &#9474;
    '' &#9474;                                                                                                                          &#9474;
    '' &#9474; If an error occurs this function will abort and return a pointer to a string describing that error.                      &#9474;
    '' &#9474;                                                                                                                          &#9474;
    '' &#9474; FileName - The name of the file to reboot from in the current directory.                                                 &#9474;
    '' &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
       
      longfill(@bootSectors, 0, 64)
      openFile(fileName~, "R")
                
      repeat (listSize <# 32768)
        result += readByte
    
        ifnot($1FF & fileName++)
          bootSectors[noparse][[/noparse]fileName >> 9] := (partitionStart + FATFirstSectorInCluster(currentCluster) + FATWorkingSectorInCluster)  
    
      result &= $FF
      changeFilePosition(6)
      fileName := readShort
      closeFile
      
      if((result and (result <> $14)) or (fileName <> $10))
        errorNumberFlag := Checksum_Error  
        abort string("Checksum Error")
    
    



    addit = this is a real kludge but I commented out these lines
    '  if((result and (result <> $14)) or (fileName <> $10))
    '    errorNumberFlag := Checksum_Error  
    '    abort string("Checksum Error")
    
    



    and it now does boot the .BIN file correctly. So - with this temporary fix, it is now possible to download and run new binary images without removing the sd card.

    Ok - next job - get the 'SEND' half of xmodem working.

    I've got a bit stuck reading the file size
    VAR
       long BinaryFileLength
        
    PRI programXmodemSend(stringPointer) 
      ifnot(str.stringCompareCI(string("xms"), stringPointer))
        PrintStringCR(string("sending file FBAS1.BIN"))
        sio.rxflush(0) ' start with clear receive buffer
        fat.openFile(string("FBAS1.BIN"), "R") 'open the file for reading
        BinaryFileLength:=fat.ListSize
    
    



    maybe the syntax isn't right but this always returns zero. Pub listsize says
    '' │ If a file is currently open this function will retrieve that files information.

    Help there would be most appreciated!

    BTW, this sd card driver is a treasure trove of information. I need to know a file size. There is a routine for that. There is a routine for everything.

    See pictures - KyeDOS is now working on a 20x4 LCD display, as well as VGA and via the serial port. Input from keyboard or serial port. Output to serial port, VGA and LCD.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller

    Post Edited (Dr_Acula) : 6/14/2010 12:07:08 PM GMT
    1020 x 704 - 201K
    876 x 586 - 71K
    640 x 480 - 67K
  • KyeKye Posts: 2,200
    edited 2010-06-14 15:33
    Mmm, as for packet padding, I would suggest removing the padding when xmodem is sending you the data. You know the file length right? So just zero out anything above that file length so that the padding is all zeros. Then the checksum rountine won't have a problem.

    ...

    The list size rountine returns the file's size always. However, you may have not written out the size. You have to close the file after you finish writing it for the size to be written out.

    Check what LS returns for the file size. That's what the file size will be when the file is opened.

    ...

    And finally, for checking if a file exist. I used to have code that did that. And then I deleted it because it is worthless. Use the "checkErrorNumber"" function and abort traps to catch the error and then look to see if the file was not found. Otherwise continue passing the abort upwards.

    So...

    temp := \fat.openFile(string(name.bin"))
    err := fat.checkErrorNumber

    if(err <> fat#FILE_NOT_FOUND)
    abort temp
    elseif(err == fat#FILE_NOT_FOUND))
    fat.newFile(...)
    elseif(err == 0)
    'Continue without error.

    ' Do stuff

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • heaterheater Posts: 3,370
    edited 2010-06-14 17:01
    Problem is in the CP/M world one does not know the file length. Files are always a multiple of the sector/cluster size of the CP/M operating system.
    Text files has an EOF somewhere in there but that can't be used for binary files.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • lonesocklonesock Posts: 917
    edited 2010-06-14 17:17
    DDS said...
    This is possibly in the wrong thread but...

    I am new to the SD driver so excuse my ignorance...

    I am using the FSRW 2.6 driver and it is working but I have to constantly remove the SD card and put it into a PC & read it there to get it to work again with the propeller. Is this what some refer to it getting "stuck"?
    Is there a work-around? I have tried unmounting/remounting but it doesn't help.

    I am using the "mb_rawb_spi" driver
    Thanks in advance.

    Don
    Hi, Don.

    The recommended block driver is "safe_spi.spin", and is set up as the default block driver in the latest FSRW 2.6 distribution. Definitely start with that. Once that one is working, _then_ you can try using the faster read version (the "mb_rawb_spi.spin"). The faster read version is sensitive to tiny timing discrepancies, which can be caused by anything from hardware layout to cog-to-pin interaction timing.

    Kye, same thing, please distribute the safe version...please please pretty please! [noparse][[/noparse]8^)

    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • KyeKye Posts: 2,200
    edited 2010-06-15 01:30
    SafeSPI... Ah, okay. I will look at that code more closely.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • RaymanRayman Posts: 14,879
    edited 2010-06-15 01:32
    jazzed said...

    I did this xmodem thing too, but now I'm running Vista (involuntarily) and there is no hyperterm.
    Can you recommend a link to a good xyzmodem client application download?

    Thanks,
    --Steve
    jazzed:· If you still have a machine running XP, you can just copy over the hyperterminal program and run it under Vista.
    There is one trick to it because one of the dll files is·in the·windows folder.
    But, there's plenty of help out there on how to do it...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Prop Apps:· http://www.rayslogic.com/propeller/Programming/Programming.htm

    My Prop Info: ·http://www.rayslogic.com/propeller/propeller.htm
    My Prop Products:· http://www.rayslogic.com/Propeller/Products/Products.htm
  • jazzedjazzed Posts: 11,803
    edited 2010-06-15 02:28
    You're right Rayman [noparse]:)[/noparse] Thanks!

    This page even has a zip package:
    blog.taragana.com/index.php/archive/how-to-install-windows-xp-hyperterminal-client-on-windows-7-or-vista-for-free/
    Rayman said...
    [noparse][[/noparse]If you still have a machine running XP, you can just copy over the hyperterminal program and run it under Vista.
    There is one trick to it because one of the dll files is in the windows folder.

    But, there's plenty of help out there on how to do it...
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Pages: Propeller JVM
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-06-15 02:54
    Hi Kye,

    I've made a lot more progress. xmodem is fairly easy to get working, but need to test lots of scenarios - eg unplugging a cable half way through - does it time out or hang?

    1) File size is now reporting correctly. Yes, it hadn't written it out.
    2) Packet padding - this is difficult as it is the sending program that does the padding and that might be hyperterminal or teraterm. So even if you write your own custom program with '0' padding, it still needs to be compatible with other download methods. I've left out your checksum and that does work. How is the checksum calculated for spin binary files?
    3) I got the 'check for file' working. See code below.
    4) I'm not sure about the best syntax for xmodem. CP/M used
    XMODEM R MYFILE.TXT or
    XMODEM S MYFILE.TXT

    But I'm wondering about
    XMR MYFILE.TXT
    XMS MYFILE.TXT

    I'm going to trap the file name in the xmr and xms pubs
    (tested with vt100.str(str.tokenizeString(0)) which passes through a name)

    And then I think I should be able to change the name of the file.


    Code as it is up to now:

    VAR
       byte XmodemBuffer[noparse][[/noparse]132]
       byte validpacket
       word PacketNumber
       byte ErrorCounter
       word i
       byte OnesComplement
       word Checksum
       byte Timeout
    PRI programXmodemReceive(stringPointer) 
    
      ifnot(str.stringCompareCI(string("xmr"), stringPointer))
        vt100.str(string("Send NAK and waiting for reply")) ' only print on local display, not to serial port
        i:=0                                                ' set counter to 0
        sio.rxflush(0)                                      ' clear the receive buffer
         repeat while (i < 10 and sio.rxavail(0)==0)        ' send 10 NAKs don't make the delay too short
           vt100.out(".")                                   ' print a . on vga display
           sio.tx(0,21)                                     ' send a NAK to start things off
           delay.pause1ms(1500)                             ' wait 1.5 seconds 
           i++                                              ' add 1 to i
        if sio.rxavail(0)                                   ' if any reply then do the file transfer
           i:=\fat.openfile(string("FBAS1.BIN"),"R")         ' does this file already exist?
           i:=fat.checkerrornumber                          ' 0 if it does exist
           if i==0                                          ' yes it does exist so delete it
             fat.closefile                                  ' close this file
             fat.deleteEntry(string("FBAS1.BIN"))           ' delete any files with this name
           vt100.str(string(13,10,"Creating file FBAS1.BIN",13,10))     ' print creating new file message
           fat.openFile(fat.newFile(string("FBAS1.BIN")), "W") 'create a new file
           vt100.str(string("Starting file transfer",13,10))
           errorcounter:=0                                  ' reset error counter
           packetnumber:=1                                   ' packet number 1
          repeat
             validpacket :=255                              ' equals true, set to 0 if any errors further down
             timeout:=0
             repeat while timeout <100                      ' timeout if no byte arrives
               if sio.rxavail(0)                              ' is there a byte?
                 XmodemBuffer[noparse][[/noparse]0]:=sio.rx(0)                         ' read in one byte
                 timeout:=255                               ' finish the timeout
               else
                 delay.pause1ms(1)                          ' wait 1 ms
                 timeout++                                   ' add 1 to timeout
            if XmodemBuffer[noparse][[/noparse]0] == 4                             ' finish byte
              errorcounter:=255                             ' signifies finish with no errors
            else  
              if XmodemBuffer[noparse][[/noparse]0] <> 1                           ' not 1
                validpacket:=0                              ' invalid packet
                errorcounter++                              ' add one to error counter
              else                                          ' 1= a valid start byte for a packet
                i:=1
                timeout:=0                                  ' if times out then packet will be corrupt
                repeat while i<132                         ' includes a timeout if half packet missing
                  if sio.rxavail(0)                         ' if a byte is available
                    XmodemBuffer[noparse][[/noparse] i ] :=sio.rx(0)                    ' read it in
                    i++                                       ' and increment
                  else
                    delay.pause1ms(10)                        ' otherwise, pause a little
                    timeout++                                 ' and keep track of the pauses
                    if timeout>100                            ' and give up after 1 second total
                      i:=133                                 ' force end if there is a timeout
                      errorcounter++                        ' and add one to error counter 
                repeat while packetnumber > 255             ' calculate the packet number always <256
                    packetnumber:=packetnumber-256
                onescomplement:=255-packetnumber            ' calculate the ones complement
                if packetnumber <> XmodemBuffer
                  validpacket:=0                            ' not a valid packet
                  errorcounter++
                if XmodemBuffer <> onescomplement            ' ones complement not correct
                  validpacket:=0
                  errorcounter++                             
                checksum:=0                                 ' calculate the checksum
                repeat i from 3 to 130
                checksum:=checksum+XmodemBuffer[noparse][[/noparse] i ]
                repeat while checksum>255                   ' round to under 256
                    checksum:=checksum-256
                if checksum <> XmodemBuffer[noparse][[/noparse]131]                   ' checksum not valid
                  validpacket:=0
                  errorcounter++
                if validpacket == 255                         ' packet is valid so save it
                  fat.writeData(@XmodemBuffer+3,128)
                  packetnumber++                             ' increment packet number
                  sio.tx(0,6)                                ' send a ACK and wait for the next packet
                  vt100.out(".")                             ' print a . on the screen for each packet
                else
                  sio.tx(0,21)                               ' send a NAK as the packet was corrupted
                  vt100.str(string("NAK"))
                  errorcounter++                             ' increment the error counter
          until errorcounter>10
           sio.tx(0,6)
          fat.CloseFile
       abort 0
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller

    Post Edited (Dr_Acula) : 6/15/2010 3:03:34 AM GMT
  • heaterheater Posts: 3,370
    edited 2010-06-15 04:41
    Dr_A: Gosh XMODEM is getting long...

    Suggest using:
            packetnumber &= 255
    
    


    instead pf:
           repeat while packetnumber > 255             ' calculate the packet number always <256
                    packetnumber:=packetnumber-256
    
    



    Same for checksum.

    I have to try this out.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-06-15 08:30
    Thanks heater, that works and saves some memory.

    Tested with some big files , hundreds of kilobytes so the counter cycles many times. All working fine.

    Yes, xmodem is long. I'm copying this from working vb.net code, which was in turn copied from Z80 .asm code. There are all sorts of tricks, for instance if you start up KyeDOS and then send a file from a terminal program, and serial buffer is not cleared, and the file happens to be a binary file, and the KyeDOS operating system is echoing back characters, and the file happens to be a binary file, and by chance, at least one byte of the first 132 byte packet happens to be a hex 21, then the KyeDOS will echo back that character in amongst all the other characters, and the sending program will interpret that as a NAK and will send the packet over and over. So you have to clear the buffer on bootup (and I clear it when the xmodem command is run as well, just to be sure).

    The only way to find these things is exhaustive testing transferring files over and over. But in the process, I'm giving Kye's SD code a real workout and I haven't managed to break it.

    And I have transferred many files to the sd card and haven't had to remove the card all day. This really is a time saver. It is so nifty to send a file like FemtoBasic and run it from the KyeDOS operating system.

    Hey, and how cool is this for Kye's code.

    Say you forget to insert the sd card, or you accidentally knock it out. I boot up with this
      VT100.clearscreen                                     ' clear the screen
      vt100.str(string("Testing for SD card",13,10))        ' helpful message if card is out, better than just a blank screen 
    
    



    If there is no card, it leaves that message on the screen as a reminder, then hangs.

    If there is a card, the next step is
      fat.mountPartition(0,0)     ' mount the sd card    
      VT100.clearscreen                                     ' if the sd card is not inserted, will leave the message on the screen as a reminder. If it is inserted, start with a blank screen
      PrintStringCR(string("****   SD card operating system by Kwabena W. Agyeman   ****"))
      PrintString(string("Type Help for command listing"))
      crlf
    
    


    etc

    But here is something really nifty. If it is hanging at the "Testing for SD card" message, you can then insert the card and after a delay of a few seconds, it will keep going. Kye's code obviously keeps checking and rechecking for a card.

    Warts and all, attached is a snapshot of the code. Works on dracblade boards. Other boards; - change pins and comment out the LCD driver code. Does NOT need external memory, so if you can attach an sd card to the demo board and change the pin settings this will work on any board with sd card attached.

    This code is such fun to use!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller

    Post Edited (Dr_Acula) : 6/15/2010 8:44:44 AM GMT
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-06-15 13:49
    Xmodem now working both send and receive. See attached. Type Help for the syntax. Now KyeDOS can talk to a PC and also exchange files between two propeller boards.

    The tx code ended up a bit neater than the rx code - less delays and timeouts.

    A few minor bugs to work out - sometimes when I boot up KyeDOS and type a command it says "Command not found". Type it a second time and it works. Happens with all commands. I'm thinking a buffer somewhere isn't being cleared.

    Another minor bug is that the CAT (TYPE to us CP/M people) is sending only carriage returns to the vt100 terminal, and it needs to send CRLF. At the moment it prints all the lines on top of each other. That might be a hangover from the propeller terminal that I think interprets CR as CRLF.

    There was just one instance when I downloaded a file and the OS told me the file did not exist when I tried to send it back again. But it refreshed when I rebooted.

    I guess YMODEM is next. It gets a little tedious typing the filename at both ends, and YMODEM is almost the same as xmodem except that it sends the filename in the first packet, so you only have to type it once.

    I've certainly given Kye's code a good workout here!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller
  • KyeKye Posts: 2,200
    edited 2010-06-15 14:47
    Thank you Dr_Acula!!! (Yes my file system driver actually retries up to 8 times to mount the SD card and for each of those eight tries it will attemp the first init command 128 times. So, if my driver cannot mount the card it is 100% incompatible. I also retry reading and writing up to 2 times if they fail to make sure the file system has the least amount of disk I/O errors as possible.)

    Okay, so... its been about a two weeks. Has anyone found any outstanding problems that need to be fixed before releaseing to the obex?

    Thanks,

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • jazzedjazzed Posts: 11,803
    edited 2010-06-15 16:35
    @DR_A,

    The problem appears to be that teraterm sees COM1-4 which I have, but does not see COM8 where my Propeller is attached.

    Hypertrm finds COM8 and COM21. It seems to work ok, so I'll stick with that for file transfers.

    Thanks,
    --Steve
    Dr_Acula said...
    Hi jazzed,

    I'm home now and able to check the download on that program. It works ok on XP. See attached.

    On my PC COM1 and COM2 are real physical serial ports. COM3 and COM4 are cheapie ebay $2 USB to D9 serial adaptors. So the list is 4 ports. That all works ok.

    Can you describe the problem a bit more? If Teraterm (or other terminal programs) are not finding the serial ports, that might suggest more a Windows problem. What is Control Panel/System/Hardware/Device Manager/Ports reporting? for example I get USB-SERIAL CH340 (COM3) when I plug in the USB to serial adaptor. Unplug it and it automatically updates the new configuration. Does Vista work the same?
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Pages: Propeller JVM
Sign In or Register to comment.