SD Drivers for REVa - FSRW (working) and physical SPI

cheezuscheezus Posts: 234
edited 2019-08-07 - 17:10:36 in Propeller 2
Sd Drivers for P2 REVa

Because most of my projects with the P1 made extensive use of SD cards, I found myself needing a good SD driver. I'm in the process of building several drivers and this thread is to document the progress, as well as hold the releases for now. I will keep this first post updated with the current Release Candidate, as well as current release notes.

FSRW RC3

Based on FSRW2.x for p1. sdspi_asm is default and is starting to take shape. sdspi_sp_inline uses the same methods to read/write to pins but doesn't start it's own cog and instead uses inline assembly to handle smartpins. sdspi_bashed uses bit-bashing to control pins and is only included for cases where data/clock pins aren't within smartpin reach.

There's much on the TODO list, including releasing pins (release does nothing right now) as well as much needed documentation. Since I'm not a "professional" developer, I could use a lot of help and really appreciate suggestions and even complaints. Hopefully others will find this work helpful and useful!


I though I saw someone working on and possibly having a working FSRW for the P2. Any help would be great!

I've been working on porting FSRW2.6 to the Propeller 2 under fastspin and I'm finally getting somewhere. I have inline ASM working up to 320MHZ on a couple cards, although I need to thoroughly test things still. It's SLOWWWWW but seems to be working with SD as well as SDHC. Removing SD support would speed things up but the goal is "most compatible." Tested with FAT32, FAT16, FAT12 not supported but wouldn't be too hard to add.

I'm going be working on a cogdriver for this next as I think that's the next big speed bump at this point. Please test, break, comment, complain. I promise I won't stay emo for long :D

«134

Comments

  • I did the SD Boot code and the Monitor/Debugger for the P2 ROM.

    I have a P1 OS that uses Kye's SD code as a base and I will be converting/rewriting for a P2 OS soon.

    Peter has also done SD routines for P2 in TAQOZ.

    What do you need help with?
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • I'm trying to wrap my head around porting Ymodem to the P2 and FAT drivers have always been a "black box" for me. I'm looking for an object to replace FSRW to start that build around. I just need something basic and i'm really hoping for something with the same interface:
    'Very slightly modified by RJA to retrieve filesize when doing a DIR
    PUB  stop
    PUB  fsize : size
    PUB  mount(basepin)
    PUB  pflush
    PUB  pclose
    PUB  popen(s, mode)
    PUB  pread(ubuf, count)
    PUB  pgetc
    PUB  pwrite(ubuf, count)
    PUB  pputc(c)
    PUB  opendir 
    PUB  nextfile(fbuf)
    

    This is the current version's interface, modified 1.5fsrw for P1. This isn't something I'm able to develop right now, I was going to focus on implementing a serial driver to start. I was just hoping someone had something working or was working on something already.

    The Touch.spin OS is largely built on your OS (I'm pretty sure) and Kye's SD would be amazing to have for the P2. The RAM and Touchscreen PASM cog is a modified version of your triblade RAM driver. Some beautiful code there..

    I plan on porting the touch os to P2 but I've got quite a few things I need to do first. Getting the new PCB to work is step 1, but it's made me realize some of the tools I need to develop to make my life easier first. I just finished some work on Ymodem and wanted to start the P2 branch while things are fresh in my mind.

    I thought I saw one of the C guru's working on a pure spin FSRW but I can't find the right thread. Thanks in advance!
  • I use the C version of FSRW for the p2gcc SD driver. However, you're probably looking for the Spin version. It shouldn't be too hard to get the Spin version running on the P2. The tricky part would be to get the SPI driver working. You could start with the SPI driver from FSRW 1.6. It is written in Spin.
  • I would like to, but the best way would be to get @lonesock to write a new block driver in PASM2. :smile:

    I am still working on serial, but as @Cluso99 said in the source of the boot rom is the basics already there, pin config, init, SPI block access, even basic FAT32. That is what I would and will start with as soon as I finished my serial buffered in COG driver.

    Because there is some common stuff with buffering and HUB transfers.

    There are two reasons why @lonesock's code shines.

    The first one is read ahead and write behind using a sector buffer in the COG. This does speed up block transfers quite nice.
    The second one is that insane HUB/COG transfer @kuroneko helped to put in there.

    I studied that source for hours, it is just beautiful.

    So to get FSRW running one basic just need a PASM block driver for the SD, I think the whole init part is done in spin.

    The Spin part should work with fastspin on P2 and another block driver.

    But first I need to finalize my serial driver.

    Enjoy!

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • Pleased you found my code helpful. Take alook at the P2 ROM code. The routines are there to follow the FAT32 and DIR to locate a file, find its size, and read/load it. I dont have a write sector, but of course read sector is there. In fact you can call it from your code. My code runs in hubexec from the ROM and just uses variables in cog $1C0-$1DF for SD and $1E0-$1EF for serial. So you can also call the serial routines such as char, string, hex, read char and read string.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • I tried getting this working before and I'm not sure what's going on tbh. I'll need to dig a little deeper to understand I guess. I just tried all the "modes" for fsrw and the only one that seems to work right is spiqasm, fasm and asm fail on running the directory listing although that could be the mod RJA mentioned. The interesting thing is the pure spin spi driver fails to mount the card. Like I said, I still need to dig deeper.
  • Cluso99 wrote: »
    Pleased you found my code helpful. Take alook at the P2 ROM code. The routines are there to follow the FAT32 and DIR to locate a file, find its size, and read/load it. I dont have a write sector, but of course read sector is there. In fact you can call it from your code. My code runs in hubexec from the ROM and just uses variables in cog $1C0-$1DF for SD and $1E0-$1EF for serial. So you can also call the serial routines such as char, string, hex, read char and read string.


    I'll have to investigate the ROM code. I was hoping for a "drop in" replacement but I know it's still very early in the development lifetime and there's not a lot of existing code. Sector read and write are the functions used, not sure if char is ever used. It sounds like this might be a better starting point, although it's becoming obvious it's going to be a while before I have anything working.

    Thanks again guys, at least I have some direction to go now.
  • yeah I think building a block driver using the rom routines in HubExec that FSRW can use is maybe the fastest way to get somewhere.

    Once working one can replace it thru some more extended thing like buffer in COG and read ahead write behind

    That should be easy. Watch me. Famous words. No first the serial driver/

    Enjoy!

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • Yeah, famous last words indeed! I often get the feeling of a money banging on a typewriter... Now just 9,999 more of me will produce the entire works of Shakespeare. In 10,000 years that is...
  • click the link in my signature about Code Monkeys...
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • I have never actually heard that full song, just the portion they play for the intro of "Code Monkeys" tv show. Good times. I just liken it to the Russian space program. Build something and then see which way it blows up. Not very elegant but with enough determination almost anything is possible.
  • That older version of FSRW with the SPI driver written in Spin is probably worth a look-see. On P2, Spin2 runs a good fraction as fast as PASM did on P1 so some of the PASM calisthenics we took for granted aren't really necessary any more.
  • cheezuscheezus Posts: 234
    edited 2019-02-15 - 04:07:53
    I tried FSRW 1.6 and I'm stuck trying to get the pure spin SPI driver working. All the other versions mount the card just fine. The spin driver never mounts, although I really need to go though some actual debugging. I did try changing the mount delay from 1/2 second to 2 seconds. Maybe that's not enough though. I tried with fastspin but maybe that has something to do with it.
    PUB Mount |key
    
      'Try to mount SD card
    
      Mounted:=sdfat.mount(SD_Basepin)
      case Mounted
        -20: ' not a fat16 volume
          ser.str(string("Error:  Not a FAT16 volume.",10,13))
        -21: ' bad bytes per sector
          ser.str(string("Error:  Bad bytes per sector.",10,13))
        -22: ' bad sectors per cluster  
          ser.str(string("Error:  Bad sectors per cluster.",10,13))
        -23: ' bad bytes per sector
          ser.str(string("Error:  Missing second FAT.",10,13))
        -24: ' bad FAT signature
          ser.str(string("Error:  Bad FAT signature.",10,13))
        -25: ' bad FAT signature
          ser.str(string("Error:  Too many clusters.",10,13))
        0:  'OK
          ser.str(string("SD card mounted successfully.",10,13))
    

    *edit - Getting somewhere, if I compile with propeller tool the SD card mounts but when compiling with fastspin it never does.

    * aedit - It looks like something's still not working right with the pure spin code. I'm going to keep digging to see what I can find.
  • Dave HeinDave Hein Posts: 5,933
    edited 2019-02-15 - 04:10:45
    In the C version I had to add some delay after toggling the clock in the read function. It looks like this:
    int readb(void)
    {
        int i, r;
    
        r = 0;
        for (i = 0; i < 8; i++)
        {
            OUTB &= ~clk_mask;
            OUTB |= clk_mask;
            sdspi_delay(2);
            r <<= 1;
            if (INB & do_mask)
                r |= 1;
        }
        return r;
    }
    
    Maybe you can try adding a waitx instruction after the clock goes high. Start with something like "waitx #10", and if that works you can reduce the delay to some smaller amount. BTW, I have recently replaced this routine with an assembly one that I copied for taqoz. The assembly version runs about 4 or 5 times faster than the C code.
  • cheezus wrote: »
    I tried FSRW 1.6 and I'm stuck trying to get the pure spin SPI driver working. All the other versions mount the card just fine. The spin driver never mounts, although I really need to go though some actual debugging. I did try changing the mount delay from 1/2 second to 2 seconds. Maybe that's not enough though. I tried with fastspin but maybe that has something to do with it.
    I'm assuming you are testing this on P1 before trying on P2, correct (i.e. you said you are compiling with propeller tool)? One thing to note is the pin order will be different than what sdspi.spin expects, for P2 on the P2ES.

    For P1 sdspi.spin, expects:
    if basepin is 0:
    '   p0 <--> do
    '   p1 <--> clk
    '   p2 <--> di
    '   p3 <--> cs
    
    P2ES SD:
    '  p58 <--> do
    '  p59 <--> di
    '  p60 <--> cs
    '  p61 <--> clk
    
    Unless you are setting up your own MOD'ed SD plugin...

    dgately
    Livermore, CA (50 miles SE of San Francisco)
  • cheezuscheezus Posts: 234
    edited 2019-02-15 - 05:27:40
    I'm making a little bit of progress. I've been trying to diagnose my P1 code and it seems the copy of SDSPI included with fsrw1.6 and friends doesn't like my sd cards. Have a feeling I'll be pulling out the LA shortly.

    @dgately , yes I'm testing on the P1 before I even plug the P2 in. This is in attempt to create a codebase that works for P1 and P2. I'll keep in mind the pin numbering issue. I've already been trying to figure out what to do about sd testing. I'm really not happy with the way pins are shared with sd and flash. I'm also aware there's some issues with added capacitance on some of the pins to resolve boot issues.

    @Dave Hein
    This seems like a good place to start investigating for the P1. My last test suggests a timing issue since the regular spin code seems to function but the fastspin does not and returns a -41 read timeout. I thought the pure spin was hanging but maybe its just way slower than I'm willing to wait out.
    		QASM 
    	Spin - 
    Mounting.
    Mounted.
    Dir:
    CPLD_PIN.PNG
    VIEWPORT.EXE
    ABLETON.EXE
    SPEED.TXT
    That's the dir
    
    Writing 2M took 927839056
    Reading 2M took 437979600
    Returned from start 3
    0
    
    	FastSpin-
    Mounting.
    Mounted.
    Dir:
    CPLD_PIN.PNG
    VIEWPORT.EXE
    ABLETON.EXE
    SPEED.TXT
    That's the dir
    
    Writing 2M took 842526368
    Reading 2M took 407214544
    Returned from start 3
    0
    
    
    	SPIN SPI
    SPIN- 
    Mounting.
    Mounted.
    Dir:
    CPLD_PIN.PNG
    VIEWPORT.EXE
    ABLETON.EXE
    SPEED.TXT
    That's the dir
    
    Writing 2M took 742130336
    Reading 2M took -612901184
    Returned from start 3
    0
    
    
    
    
    FastSpin-
    Mounting.
    Returned from start
    -41 read timeout
    
  • @chezus,
    I may be able to post P2 SD PASM code that will help as soon as I get the ROM changes done for the respin. Will just need to add back the write sector routine and you will have read/write sector, search DIR for a file, and read the files start sector and size, and load/run if you wish. You will need the extra functions to operate on the FAT32 though.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • cheezuscheezus Posts: 234
    edited 2019-02-15 - 06:40:40
    Cluso99 wrote: »
    @chezus,
    I may be able to post P2 SD PASM code that will help as soon as I get the ROM changes done for the respin. Will just need to add back the write sector routine and you will have read/write sector, search DIR for a file, and read the files start sector and size, and load/run if you wish. You will need the extra functions to operate on the FAT32 though.

    That might be enough to get me working. I'm still trying some basic diagnostics on SDSPI. I hope I just caught something in the read function. I'm thinking this should be a shift and or?

    pri read | r
    '
    '   Read eight bits from the card.
    '
       r := 0
       repeat 8
          outa[clk] := 0
          outa[clk] := 1
          r += r + ina[do]  '' ?should be r := (r << 1) | ina[do] ''?
       return r
       
    

    The spin test code finally finished. I'm not sure what these numbers mean but i'm guessing clock cycles?

    I've tried both versions of the read code and both seem to work in spin? FastSpin gives -20 not fat16 volume.

    Either version of the read code works, I should quit being lazy and hook up my logic analyzer. I tried adding in delays in the usual places, ie clock edges. I was hoping to get lucky on this one, guess not.
  • If @Dave Hein has a working C version of FSRW can we just try to use that in fastspin?

    One of the best parts of fast spin is that one can include objects written in different languages, so why not FSRW in C?

    Enjoy!

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • I have the spin only version of FSRW here...
    I tried a while ago to make it work under FastSpin and it didn't...
    Think I'll try again...
    Prop Info and Apps: http://www.rayslogic.com/
  • cheezus wrote: »
    I
    @Dave Hein
    This seems like a good place to start investigating for the P1. My last test suggests a timing issue since the regular spin code seems to function but the fastspin does not and returns a -41 read timeout. I thought the pure spin was hanging but maybe its just way slower than I'm willing to wait out.
    If the "regular" spin code (compiled with openspin or bstc) works, but when compiled with fastspin it doesn't, then it probably is a timing issue. Regular spin bytecode is slow enough that people often leave off delays that really should be in there. When compiled with fastspin the code speeds up so that the missing delays cause problems. Dave's suggestion of inserting short pauses after pin manipulation is a good one.

  • My suggestion for adding delay was for the P2. I don't think the P1 needs the extra delay.
  • It is quite possibly the actual spi routine. Remember the P2 has a 3 clock delay before the level appears at the pin, and when reading you are seeing the pin as it was 2+2 clocks before the input instruction completes.
    This means you have to really understand the timing or you will get errors and nothing will work.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • When converting spin to the P2, don't forget that you must use INB and OUTB instead of INA and OUTA for pins beyond 32, which is where the SD card is on the ES.
  • To be clear, I was trying to use the Spin-Only version of FSRW on a P2...

    It works with Prop Tool on P1 and I'm pretty sure it'd work with FastSpin on a P1 too, but haven't tried that...
    Prop Info and Apps: http://www.rayslogic.com/
  • Dave Hein wrote: »
    My suggestion for adding delay was for the P2. I don't think the P1 needs the extra delay.

    Well, it might -- as I mentioned I've seen some programs that when moved from PropTool/bstc/openspin to fastspin (on P1) need delays added, because the operations are happening so much faster in PASM than in bytecode. I don't know if that's the case here, but it's something to watch for. Of course P2 with its higher clock and faster instructions is even more sensitive to this kind of thing.
  • I think the main issue with the P2 is the pipeline delay on the inputs and outputs. When an external device is clocked, such as an SD card, it takes a few cycles before the results are clocked into the INA/INB registers. There is also propagation delay caused by the logic gates. When clocking at 320 MHz the cycle period is only 3.125 nano-seconds. SD cards might have a problem with a pulse width of 6.25 nsecs, but it should work fine at 80 MHz, where the pulse width would be 25 nsecs.

    The P1 has minimal pipeline delay.
  • Short pulses like that face the problem of stray capacitances and inductances limiting the slew-rate - the off-chip
    world is very different from the CMOS core, where capacitances are measured in fF (femto farads) - such slewing
    also causes propagation delays, which are in time units, not clock cycles, so get worse at higher clock frequencies.
  • cheezuscheezus Posts: 234
    edited 2019-02-15 - 21:49:30
    I started with adding in pauses after each pin manipulation but without actually SEEING what's going on it would be a lazy guess. I'll quit being lazy and actually hoo
    Rayman wrote: »
    To be clear, I was trying to use the Spin-Only version of FSRW on a P2...

    It works with Prop Tool on P1 and I'm pretty sure it'd work with FastSpin on a P1 too, but haven't tried that...

    I've got the spin only FSRW working on the P1 using the regular compilers. But when I use fastspin to try to produce a P1 binary, there's an issue. I'll grab some LA caps today to try and figure things out better. I'm almost 100% sure it's just a timing issue but without seeing what the timing is now vs what it's supposed to be..

    I want to get this working on the P1 so I have some "known good" condition to debug against. I'm expecting the P2's in/out delays to give me some grief. I hope I'm wrong.
  • Here's a simple FSRW demo that works on my P1 (an activity board) when compiled with fastspin. You may need to adjust the pins of course to get it to work.
Sign In or Register to comment.