Shop OBEX P1 Docs P2 Docs Learn Events
Discussing SD Drivers (depreciated fsrw) - Page 4 — Parallax Forums

Discussing SD Drivers (depreciated fsrw)

1246789

Comments

  • I think running a file should be something as simple as this... Probably need to disable the smartpins first, perhaps validate file too? I think you'd need to stop all other cogs before running this? I'll sit down and work on this more later, my bed is calling.
    con
      _Run_SDfile      = $FC578 
    
    PUB runfile(strPtr) | t, i, z       '' ptr to 8.3 filename
        if (t := strsize(strPtr) ) > 12                 ' bad filename
            return false         
        z:= 0                            
        repeat i from 0 to t                            ' copy string to buffer
            if byte[strPtr][i] <>   "."                 ' no dot
                byte[@fname][z++] := byte[strPtr][i]    ' char to buffer
                if z > 11                               ' ? no dot?
                    return false                        ' bad filename
        byte[@fname][z] := 0                            ' z term
        return DoCommand("c", @fname, 0, 0)
        
    chain_f         '' chain a file - arg1 is ptr to 3long filename
                    mov     ptra,           arg1
                    rdlong  fname[0],       ptra++
                    rdlong  fname[1],       ptra++
                    rdlong  fname[2],       ptra++
                    call    #_Run_SDfile
                    mov     err_out,        ##-99           ' !!no file!!       
                    call    #card_init                          
                    jmp     #end_cmd         
    


    Hopefully @Cluso99 can give sage advice!
  • Hi all,

    haven't been here for a long time. What's the actual status of the propeller II-Chip?

    When can I buy a board with an original original propeller-II-chip
    (not any FPGA-emulation)

    best regards

    Stefan
  • Cluso99Cluso99 Posts: 18,069
    @chezus,
    The ROM listing (only the ES is available) shows a pasm routine that parses the filename. I cannot recall if you can call it.
    To call any of the rom use “CALL #_hubxxxx”
    Note as a default i use $FC000 which overwrites the bootloader which has no further use anyway.

    There is an example of calling the ROM routines in the fourth post of the “P2 JMP/CALL addresses to COG/LUT/HUB...” thread
  • kwinnkwinn Posts: 8,697
    StefanL38 wrote: »
    Hi all,

    haven't been here for a long time. What's the actual status of the propeller II-Chip?

    When can I buy a board with an original original propeller-II-chip
    (not any FPGA-emulation)

    best regards

    Stefan

    Last post I recall was for late August or September. Chips are waiting for packaging.
  • Cluso99Cluso99 Posts: 18,069
    There are about 110-120 boards with the ES chips (engineering sample) rev 1 (aka v31i) fitted. The first few of these boards arrived in our hands just in time for chipmas 2018.

    There were a few bugs Chip wanted to fix, and a few extras too. The first 10 of these chips arrived ~ 1st August 2019. Providing there are no show stoppers, and testing so far has been way beyond expectations, there are some 1500-2500 from the wafers that can be packaged. So its possible for chips and/or boards to be available sometime in September /October.
  • @cluso I Think I found it and it looks callable, although I would need the lmm parameters too I believe. I'm not sure if I would need the LMM additional workareas in cog. I'm about adding all these in and revising my naming again to allow hooking into the rom code easier.
    ''============[ COG VARIABLES - MONITOR]========================================
                    org     $1E0              ' place the variables in cog $1E0-$1EF
    ''-------[ LMM parameters, etc ]------------------------------------------------
    lmm_x           res     1       ' parameter passed to/from LMM routine (typically a value)
    lmm_f           res     1       ' parameter passed to      LMM routine (function options; returns unchanged)
    lmm_p           res     1       ' parameter passed to/from LMM routine (typically a hub/cog ptr/addr)
    lmm_p2          res     1       ' parameter passed to/from LMM routine (typically a 2nd hub/cog address)
    lmm_c           res     1       ' parameter passed to/from LMM routine (typically a count)
    ''-------[ LMM additional workareas ]-------------------------------------------
    lmm_w           res     1       ' workarea (never saved - short term use between calls, except _HubTx)
    lmm_tx          res     1       ' _HubTx
    lmm_hx          res     1       ' _HubHex/_HubString
    lmm_hx2         res     1       ' _HubHex
    lmm_hc          res     1       '   "
    lmm_lx          res     1       ' _HubList
    lmm_lf          res     1       '   "
    lmm_lp          res     1       '   "
    lmm_lp2         res     1       '   "
    lmm_lc          res     1       '   "
    lmm_bufad       res     1       ' _HubRxString
                    fit     $1F0
    ''=======[ ^^^^^ End of COG Variables ^^^^^ ]===================================
    ''===============================================================================================
    
    ''-------[ Parse <filename> ]-------------------------------------------------- <--- parse filename --->
    '' On Entry:
    ''      lmm_x   = -anything-                            ' -anything-
    ''      lmm_c   = -anything-                            ' -anything-
    ''      lmm_p   = 'addr'                                ' 'addr':  ptr to string (hub)
    ''      lmm_w   = -anything-                            '
    '' Call Format:
    ''             CALL     #@_ParseFname                   '                       < call: parse filename >
    '' On Return:
    ''      lmm_x   = 'fname'                               ' 'fname':   4 chars of filename
    ''      lmm_c   = -undefined-                           '
    ''      lmm_p   = 'addr++'                              ' 'addr':
    ''      lmm_w   = _undefined-                           '
    ''--------------------------------------------------------------------------------------------------
    _ParseFname     mov     lmm_c,  #4                      ' 4 chars per call
                    mov     lmm_x,  #0
    .loop           rdbyte  lmm_w,  lmm_p                   ' get a char
                    cmp     lmm_w,  #"."           wz
            if_ne   cmp     lmm_w,  #_CR_          wz
            if_ne   or      lmm_x,  lmm_w                   ' insert char..
            if_e    or      lmm_x,  #" "                    ' .. or space..
                    ror     lmm_x,  #8                      ' .. & rotate byte
            if_ne   add     lmm_p,  #1                      ' PTR++
            if_ne   rdbyte  lmm_w,  lmm_p                   ' get a char
            _RET_   djnz    lmm_c,  #.loop                  ' <4 chars
    


    I'm thinking that there needs to be options to start a ?cog with an image? and load a whole hub image and start that. It looks like you exercise both in different sections of code..

    I'm preparing code to release the pins when release is called. I've also been tying to implement an auto-release / mount function somewhat like @lonesock 's mb_raw driver.

    This is the command loop -
    get_cmd         rdlong  cmd_in,         ptra    wz          '
                    pollct2                         wc      
            if_c    call    #card_rel                           ' timeout and release card after 10s       
            if_z    jmp     #get_cmd                            ' no cmd so handle time                               
                    '' these commands don't need any arguments
                    cmp     cmd_in,         #"z"    wz          
            if_z    jmp    #card_rel                                                                      
                    '' get parameters from spin
                    rdlong  arg1_in,        ++ptra               
                    rdlong  arg2_in,        ++ptra               
                    rdlong  arg3_in,        ++ptra                
                    rdlong  err_out,        ++ptra              ' dummy read to align err pointer
                    '' decode command                           
                    cmp     cmd_in,         #"i"    wz          
            if_z    jmp     #save_pins    
                    '' commands that need active smartpins
                    cmp     cmd_in,         #"m"    wz          
            if_z    call    #c_active                        ' do this since checks for pins active too                       
                    '' commands that need active card                
                    cmp     cmd_in,         #"r"    wz          
            if_z    jmp     #read_a                             
                    cmp     cmd_in,         #"w"    wz          
            if_z    jmp     #write_b   
                    cmp     cmd_in,         #"c"    wz          
            if_z    jmp     #chain_f                           
                    mov     err_out,        #5                  ' err = no command                 '               
                   '' do commands                               
    end_cmd         cmp     sp_active,      #1      wz
            if_z    drvh    pinCS                               ' set cs high
            if_z    call    reset_timer    '' save last command time here?
                    wrlong  err_out,        ptra                                                     
                    mov     cmd_in,         #0                  ' signal done to spin driver                 
                    mov     ptra,           ptr_to_mbox         ' return ptra back to mbox
                    wrlong  cmd_in,         ptr_to_mbox         
                    jmp     #get_cmd                            
    


    Here I'm trying to release the pins, as well as reactivate them again. Not sure about all of this, I'd like to do AS LITTLE as possible to deactivate the smartpin, aka hi-z / smartpin disabled...
    release_pins      '' release sd card pins - should send a bunch of clocks first               
                    flth    pinCS               ' Float CS pin
                    dirl    pinCLK      '' setup Clock pin                 
                    wrpin   #0,     pinCLK              ' set clock mode                
                    dirh    pinCLK                              ' enable clk                     
                    dirl    pinDI       '' setup DI pin                  
                    wrpin   #0,     pinDI               ' set di mode
                    dirh    pinDI                               ' enable smartpin               
                    dirl    pinDO       '' setup DO pin                
                    wrpin   #0,     pinDO               ' set do mode
                    dirh    pinDO                               ' enable pin                                
                    mov     sp_active,      #0
    
    quickset_pins   '' uses old modes and y values?
                    dirl    pinCLK      '' setup Clock pin                 
                    wrpin   sp_ck_mode,     pinCLK              ' set clock mode                
                    dirh    pinCLK                              ' enable clk                     
                    dirl    pinDI       '' setup DI pin                  
                    wrpin   sp_di_mode,     pinDI               ' set di mode
                    dirh    pinDI                               ' enable smartpin               
                    dirl    pinDO       '' setup DO pin                
                    wrpin   sp_di_mode,     pinDO               ' set do mode
                    mov     sp_active,      #1
                    dirh    pinDO                               ' enable pin                                
    
    

    And the various functions I'm trying to add
    c_active     '' check if card is active and activate if not            
                    cmp     sp_active,      #1              wz
        if_nz       call    #quickset_pins   
                    cmp     card_active,    #1              wz
        if_nz       call    #card_init
    c_active_ret    ret
    
    reset_timer     getct   timeout                             ' setup 16s timeout 
                    mov     spare,          delay1s
                    shl     spare,          #4                  ' multiply by 16
                    addct2  timeout,        spare             ' in case card does not respond                     
    reset_timer_ret ret
    
    sp_active   long    0       
    card_active long    0
    



    I'm going to work on this a little more, see where I get. I haven't tested any of this so there might be edge-cases i'm missing. Note, c_active is called at the beginning each high-level command like block_r/block_w. I'm going to try adding the parse filename in and create a couple test files...
  • Cluso99Cluso99 Posts: 18,069
    edited 2019-08-11 21:22
    I published the new ROM code but I cannot recall what thread it was in. It almost completely handles the DO problem - there was one obscure path not plugged although in practice it probably won’t cause any issues. Timing delays were also shortened for error conditions. It’s way better than the first rom.
    I am overseas atm and my computer back home is refusing to let me in remotely which I do from work regularly and visa versa. PeterJ has a copy so perhaps he can post a copy?

    Yes, the parse routine uses the lmm_… cog variables as this code only runs when you’re using the monitor rom which uses serial. The normal SD does not use these 16 cog longs iirc.

    You can plug the SD cog variables with values and call the SD routines. Eg sector address, where to place the sector buffer, where to download the file (address), what address to copy to cog, and where to execute from.

    Or you can just copy the PASM code into your own code. It’s MIT license :smiley:
  • rosco_pcrosco_pc Posts: 464
    edited 2019-08-12 06:25
  • Cluso99Cluso99 Posts: 18,069
    Thanks Rosco. I had forgotten Chip posted the respin ROM code (v32j)
  • I checked my library and I actually have the new rom saved for the future. Extracting the relevant addresses from the rom and modifying the constants files I'm working on won't be too hard. I'm going to create a quick test to make sure I have things working right. I plan on using the low-level drivers with my fsrw test which should be straightforward now that I have all the variables in cog.

    The one thing I really need is a buffered serial port and I think that's the 2nd project I'm going to work on..


    @Cluso99
    I had to go back and check, the respin is 33_01j but I guess I had a later version ROM_Booter_v33j_SD-003n. Glad I caught that before I started pulling addresses into the jump table for the new chip.
  • Cluso99Cluso99 Posts: 18,069
    edited 2019-08-12 08:13
    IIRC Chip uses interrupts for his serial receive in the booter for example code. I think TAQOZ also uses interrupt for serial receive too.

    When i get a chance with the respin chip I’ll workup some simple patches for the ROM.

    I have a whole lot more monitor/debug code that i had to strip out to fit. There were all sorts of things like decimal and binary, and a disassembler but for the original P2 before p2-hot

    BTW there is also an input bytes/hex to cog/lut/hub in the format as output be pnut assembler :)
  • msrobotsmsrobots Posts: 3,709
    edited 2019-08-13 00:08
    cheezus wrote: »
    I checked my library and I actually have the new rom saved for the future. Extracting the relevant addresses from the rom and modifying the constants files I'm working on won't be too hard. I'm going to create a quick test to make sure I have things working right. I plan on using the low-level drivers with my fsrw test which should be straightforward now that I have all the variables in cog.

    The one thing I really need is a buffered serial port and I think that's the 2nd project I'm going to work on..


    @Cluso99
    I had to go back and check, the respin is 33_01j but I guess I had a later version ROM_Booter_v33j_SD-003n. Glad I caught that before I started pulling addresses into the jump table for the new chip.

    Try this, one or two ports, buffer in LUT, self contained in PASM2 with Spin around for FastSpin compabillity

    Mike
  • Been busy at work and getting ready to move so haven't had much of a chance to code but a couple hours here and there.. I've finally had a chance to get Ymodem working on the p2, file TX, RX and a simple speed test. It's not heavily tested but seems to be working okay.. I'm calling this release v1 but it's more like an alpha. I'll update the 1'st post if anyone's interested.

    As a note, I did have a chance to try to test SD support and something isn't right. I'll have to look at this after I move..
  • RaymanRayman Posts: 14,624
    Ymodem… I remember that from a very long time ago...
    Thanks for digging that up. Glad you made it work with P2.
  • Rayman wrote: »
    Ymodem… I remember that from a very long time ago...
    Thanks for digging that up. Glad you made it work with P2.

    I've been using your version of ymodem forever with the P1 and even rewrote it using kye's sd (so a file could be run once copied to SD). I added some extra features such as baud change but removed that while trying to get the basics working again. I did rewrite the Receive from SD significantly to build each packet before sending as well as implemented batch Send to SD. I think with some work this could be used to send files between propellers, but I'll need to think about that some more.

    @Rayman, thanks for such a handy piece of code. It's saved me thousands of card swaps!
  • Cluso99Cluso99 Posts: 18,069
    cheezus wrote: »
    Rayman wrote: »
    Ymodem… I remember that from a very long time ago...
    Thanks for digging that up. Glad you made it work with P2.

    I've been using your version of ymodem forever with the P1 and even rewrote it using kye's sd (so a file could be run once copied to SD). I added some extra features such as baud change but removed that while trying to get the basics working again. I did rewrite the Receive from SD significantly to build each packet before sending as well as implemented batch Send to SD. I think with some work this could be used to send files between propellers, but I'll need to think about that some more.

    @Rayman, thanks for such a handy piece of code. It's saved me thousands of card swaps!

    Way back when I wrote my version of P1 OS I used the PropTool protocol to transfer files to the prop and write out to eeprom. I used Chips' booter as the base.
  • RaymanRayman Posts: 14,624
    I dug up the old "test" program for FSRW on P1 and hacked it for P2 and testing with fsrw from cheezus' last post.
    Seems like it works, except for the pwrite and pread tests. I had to comment those out.
    This is with the serial code that msrobots posted above.

    Not sure yet if speed is good or bad, but at least seems to do something:
    How fast can we write using pputc?
    FSRW pputc 1023 kB in 3519 ms at 290 kB/s
    How fast can we read using pgetc?
    FSRW pgetc 1023 kB in 3519 ms at 290 kB/s
    Repeating all the speed results:
    
    Clock: 200000000 ClusterSize: 0 ClusterCount: 0
    Raw write 896 kB in 3305 ms at 271 kB/s
    Raw read 896 kB in 3221 ms at 278 kB/s
    FSRW pputc 1023 kB in 3519 ms at 290 kB/s
    FSRW pgetc 1023 kB in 3519 ms at 290 kB/s
    All done!
    
  • Glad to see things seem to work. I'll try tracking down what's going on with pwrite and pread tests soon. I've been wanting to get back to coding but between work and moving I've had very little time and even less energy.

    One place things can be optimized is by moving to block reads and writes. I was going to explore this but the next thing I need to get working is running a binary from SD card.

    Interestingly enough the LA caps of ymodem running @460800 baud shows the biggest time waste is spent waiting for the computer to send the next packet after receiving an ack. I keep wondering if I could change serial port settings on the pc to improve this but for now it seems to work.
  • jmgjmg Posts: 15,172
    cheezus wrote: »
    Interestingly enough the LA caps of ymodem running @460800 baud shows the biggest time waste is spent waiting for the computer to send the next packet after receiving an ack. I keep wondering if I could change serial port settings on the pc to improve this but for now it seems to work.
    That's likely an artifact of USB packets. Increasing the baud rate, does not help the FS-USB turnarounds which are usually roughly 1ms.
    With USB, you are better to send larger blocks, and ACK less often, or even use hardware handshake.
    HS-USB can be faster, as the turnaround timing is lower, so if you are stuck with a protocol, and need more throughput, you could consider using a HS-USB bridge.(FT232H, FT2232H, CY7C68013A)
  • msrobotsmsrobots Posts: 3,709
    edited 2019-09-28 20:12
    The main reason why FSRW is faster then Kye's driver is that fast-spi does block reads and writes combined with write behind and read ahead.

    So when writing a sector to SD the spin program tells the COG to fetch the data from HUB, it does so and reports success before the COG even attempts to write the sector.

    Another trick @lonesock used is when reading a sector, after writing it to HUB the COG fetches the next sector, just in case it might be needed next.

    Both of this speeds thigs up.

    Mike
  • jmg wrote: »
    cheezus wrote: »
    Interestingly enough the LA caps of ymodem running @460800 baud shows the biggest time waste is spent waiting for the computer to send the next packet after receiving an ack. I keep wondering if I could change serial port settings on the pc to improve this but for now it seems to work.
    That's likely an artifact of USB packets. Increasing the baud rate, does not help the FS-USB turnarounds which are usually roughly 1ms.
    With USB, you are better to send larger blocks, and ACK less often, or even use hardware handshake.
    HS-USB can be faster, as the turnaround timing is lower, so if you are stuck with a protocol, and need more throughput, you could consider using a HS-USB bridge.(FT232H, FT2232H, CY7C68013A)

    That makes perfect sense and I figured as much. I've read the ymodem spec several times and ymodem-g looks like it could work. It would take a pretty heavy rewrite although it could be a fun project sometime. Ymodem-G does not ack or do a crc so it should be much faster. I'm seeing about 20k/s right now which should be more than sufficient for my needs. Some other protocol would probably be better suited for transferring large files.
  • msrobots wrote: »
    The main reason why FSRW is faster then Kye's driver is that fast-spi does block reads and writes combined with write behind and read ahead.

    So when writing a sector to SD the spin program tells the COG to fetch the data from HUB, it does so and reports success before the COG even attempts to write the sector.

    Another trick @lonesock used is when reading a sector, after writing it to HUB the COG fetches the next sector, just in case it might be needed next.

    Both of this speeds thigs up.

    Mike

    I'm still trying to understand file systems so a lot of fsrw vs kyes is still greek. I'm starting to understand the spi end though and while I've only implemented single block rw, it seems like multiblock should be much faster. From what I understand this is the case that multiblock is designed for. Each packet is 1024k or 2x 512byte blocks. I'm not sure how much this would really improve the overall transfer times. I'll post a LA cap when I get a chance...

    Loading a 800x480x16bpp bmp should really show the difference though...
  • I load a 640x480x8 BMP in 100ms with a multi block read but where are you thinking of loading a larger 16bpp bitmap with only 512k?
  • I load a 640x480x8 BMP in 100ms with a multi block read but where are you thinking of loading a larger 16bpp bitmap with only 512k?

    I'll be loading to the fast SRAM (16b) and then to 7" 16b parallel display. Once I get these verified I'll be pushing that image to the flash chip on my board. Some SRAM functions are tested and I'm working on rewriting the display / ram cog. 100ms sounds promising. I really wish I could get my head around fourth but I can't seem to get past following others examples and slightly modifying. Anything else and I'm just stuck staring at the screen. :lol:
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-09-30 02:49
    cheezus wrote: »
    I load a 640x480x8 BMP in 100ms with a multi block read but where are you thinking of loading a larger 16bpp bitmap with only 512k?

    I'll be loading to the fast SRAM (16b) and then to 7" 16b parallel display. Once I get these verified I'll be pushing that image to the flash chip on my board. Some SRAM functions are tested and I'm working on rewriting the display / ram cog. 100ms sounds promising. I really wish I could get my head around fourth but I can't seem to get past following others examples and slightly modifying. Anything else and I'm just stuck staring at the screen. :lol:

    I can never really learn another language well unless I'm immersed in it and I have to, be that computer or spoken. But while Forth may be very "different", it allows you to interact, and any educator knows that interactive learning is very productive.

    This is an older video and things have improved since then and I can also switch to any video mode dynamically, but gives you a glimpse at what you can do without extra memory.

  • rjo__rjo__ Posts: 2,114
    Cheesus,


    I wanted to thank you for all of your hard work. I am working on a program, which absolutely has to write large data to the SD and after scratching my head and going up blind alleys for the better part of two days, I finally arrived at your version on the preceding page... I can't tell how happy that made me!!!

    Thanks

    Rich
  • rjo__rjo__ Posts: 2,114
    edited 2019-11-20 03:49
    oh... by the way. When running fswr_speed_top, I originally wasn't getting a video signal. I had to change some of the clock parameters to get it to 160MHz in a way that my monitor liked. Also, everything works at 320MHz, but the time to write ended up with a negative value I know the P2 is fast... but faster than light? I had no idea:)

    I am planning to replace the need for a serial library with some in line assembly... to save a cog.

    I'll post it if I ever get it done!

    Thanks again
  • cheezuscheezus Posts: 298
    edited 2019-11-20 17:24
    rjo__ wrote: »
    oh... by the way. When running fswr_speed_top, I originally wasn't getting a video signal. I had to change some of the clock parameters to get it to 160MHz in a way that my monitor liked. Also, everything works at 320MHz, but the time to write ended up with a negative value I know the P2 is fast... but faster than light? I had no idea:)

    I am planning to replace the need for a serial library with some in line assembly... to save a cog.

    I'll post it if I ever get it done!

    Thanks again

    Glad this was able to help you! When I get my P2D2 the first thing I plan on doing is updating to work with revA or revB chips. I've been really busy with work and moving so I haven't had time in the past couple months to do much coding.

    I'm pretty sure the negative return value @320mhz is due to signed vs non-signed numbers. I noticed this as well but didn't have time to track it down for sure (or come up with a solution.)


    *edit
    Cluso has also released a SD driver, although I've not had a chance to test it yet. https://forums.parallax.com/discussion/170543/clusos-sd-card-cog-driver-for-p2#latest
  • RaymanRayman Posts: 14,624
    edited 2020-01-21 19:27
    I think I spotted a bug in "sdspi_asm.spin2"...
    My custom P2 board was not working and couldn't figure out why... It did work with "sdspi_bashed.spin2" though.

    I decided it must be something to do with my pins not being in the same order as the Eval board.
    Went looking for what might be wrong and found and fixed this (smartpin relative offset for negative values):
    PRI getmask(clk, data) : t
        t := clk - data
        if ( || t ) <> t        
          't := ( || t ) + %0100     
          t := ( 4-(|| t) ) + %0100    'RJA
    

    Now, it works. Thanks for this fsrw work.
  • Rayman wrote: »
    I think I spotted a bug in "sdspi_asm.spin2"...
    My custom P2 board was not working and couldn't figure out why... It did work with "sdspi_bashed.spin2" though.

    I decided it must be something to do with my pins not being in the same order as the Eval board.
    Went looking for what might be wrong and found and fixed this (smartpin relative offset for negative values):
    PRI getmask(clk, data) : t
        t := clk - data
        if ( || t ) <> t        
          't := ( || t ) + %0100     
          t := ( 4-(|| t) ) + %0100    'RJA
    

    Now, it works. Thanks for this fsrw work.

    Good eye! I was just looking at that the other night and thought it looked wrong. I'll get that fixed in my library and roll it into the next release. Thanks for the bug report!
Sign In or Register to comment.