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

Discussing SD Drivers (depreciated fsrw)

2456789

Comments

  • cheezus, did you try adding delay where I suggested? I think that's the only place where it was required. The timing for p2gcc should be similar to compiled Spin using fastspin.

    Another possibility is that FSRW 1.6 may not be able to handle SDHC cards. I think I had to make some changes to get SDHC cards to work. Do you have any older SD cards that you an try? I'll see if I can figure out what I had to change to get SDHC to work.
  • ersmith wrote: »
    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.

    Thanks @ersmith , I'll check that out in a little bit.

    I finally got a couple good captures of the wire. Spent a bunch of time trying to figure out why I'm only getting 8msps, pretty sure I used to run @16 but that was on my desktop. This one's fighting me!
  • @"Dave Hein"

    Sorry I missed your comment, didn't see the 2nd page. I did try adding the delay where suggested but it didn't seem to help. I need to start with a fresh copy of SDSPI and try again though because it seems that I broke something last night and now the regular spin version isn't working either.

    To be sure I'm following along, you started with the pure spin (no pasm block driver) SDSPI. Add delay after toggling clock, before reading data. You also use the "shift-or" sampling.

    The interesting thing I did notice is SDSPI has no "STOP" method so I added it back in.

    I'm sure this is something simple at this point. I've been using an old 2G - FAT16 card for testing. It's known working with FSRW if I use the asm block driver. The pure spin is being more difficult.

    Once I get the basic pure spin version working on the p1, I'll move on to the P2. Having a common "pure spin" driver is important at this point, especially considering the respin coming up. Once the P2 compiled version is working I'd really like to look at using ROM functions.
  • Dave HeinDave Hein Posts: 6,347
    edited 2019-02-16 01:07
    I looked at sdspi.spin, and it clearly does not support SDHC cards. I had to make a few changes to get it to work. The cmd routine shifts the parm up by 9 bits as it sends it to the SD card. By doing this it converts the sector address to a byte address, which is what an SD card expects. SDHC cards expect sector addresses.

    I modified the cmd routine to send all 32 bits of the parm without shifting it. In the start routine I detect whether the card is SD or SDHC by sending cmd 58, and looking at bit 6 of the first byte read back. I set an sdhc flag, and use it in the readblock and writeblock routines to shift the address up by 9 bits if it's not an SDHC card.

    I've attached my C version of sdspi.spin for you to look at. Look at the cmd routine, and also look where I used the sdhc flag.
    c
    c
    8K
  • cheezus, you did say that you got it working on the P1 using the Prop Tool. So this implies that the card you tested with was not an SDHC card, but only and SD card. Therefore, you should be able to get this to work on the P2 with the same card by just adding the delay that I suggested. Of course you will also need to implement the start_explicit routine since the pins are not sequential. In the P2 I call mount_explicit with the following parms:
    mount_explicit(58, 61, 59, 60)
    
  • I finally found the issue with compiling for P1. It seems there's a bug in the fastspin compiler, I'm not sure it's listed.
    '' doesn't set clock to output
       outa[clk] := outa[di] := outa[cs] := 1
       dira[clk] := dira[di] := dira[cs] := 1
    
    ' doesn't set di output
       outa[clk] := outa[di] := 1
       outa[cs] := dira[clk] := 1
       dira[di] := dira[cs] := 1
    
    '' but this works
       outa[clk] := 1
       outa[di] :=  1
       outa[cs] :=  1
       dira[clk] := 1
       dira[di] := 1
       dira[cs] := 1
    
    

    Once I started looking at the LA caps it became obvious that the clock was not toggling. Fastspin now mounts the card just fine.
  • I started making some serious progress once I hooked up my LA, duh. I've just about finished making all the changes @"Dave Hein" noted above. I did have some issues with a couple of things in the mount. I'm not sure about the "extra" 2 commands, they both cause my sd card to hang. I'll see what happens with some different cards now that things are firming up. Now all I need to do is add in the code to handle portb on the p2... Some conditional compilation statements to easily switch for P1/P2...

    I'm being lazy and still haven't looked at the actual spec, maybe someone can comment on what these commands are and why they might cause my card to hang. I'm sure it's something simple..
    pub start_explicit(_do, _clk, _di, _cs)  
    
       do := _do
       clk := _clk 
       di := _di
       cs := _cs
       sdhc := false
       outa[clk] := 1
       outa[di]  := 1
       outa[cs]  := 1
       dira[clk] := 1
       dira[di]  := 1
       dira[cs]  := 1
       
       starttime := cnt
       repeat 600
          read
       cmd(0, 0)
       endcmd
    {
       cmd(8, $1aa)                 ' card never mounts  
       endcmd
    }
       repeat
          cmd(55, 0)
          result := cmd(41, $4000_0000)
          endcmd
          if result <> 1
             quit
             
       if result
          abort -40 
    
       result := 0
    {   
       cmd(58, 0)                   ' card never mounts
       sdhc := (read >> 6) & 1
       endcmd
    }
       
       
    
  • Cluso99Cluso99 Posts: 18,066
    I posted a few hours ago a new soft-loaded version of the next ROM SD Booter. It is in PASM and runs in hubexec with some variables in cog $1C0-$1EF.
    It has some debug info so you can see where it gets to if it fails.
  • cheezus, are you sending a CRC7 of $87 for CMD8? In the cmd routine I added some code to send $95 for CMD0 and $87 for all other commands. CMD0 and CMD8 are the only ones that require a valid CRC7, so you must send $87 with CMD8.

    Here's the snippet of code from the cmd routine.
        if (op == 0)
            send(0x95);
        else
            send(0x87);
    
  • I started to think about it and I need to do some more testing to confirm but the two offending commands seem to only apply to SDHC cards. I've been testing with FAT16 formatted SD cards (I have 3 SD and a bunch of SDHC). I'll do some tests to verify this later. If this is indeed the issue, I need to figure out how to handle it properly. I'd like to be able to support SD cards but maybe it would be best to throw an error?

    Thanks again for helping me get things working on the P1, I just need to pin down a couple issues like handing SD/SDHC. I'll post here after I get things working on the P2.
  • Cluso99Cluso99 Posts: 18,066
    Here is a P1 thread that has P1 PASM and tests the cards.

    BTW you should be supporting FAT32 not FAT16.

    Here is a flow chart of the SD commands that I did some time ago for the P2 SD ROM (there is 4 sheets, not 3)
  • I think cmd $58 is to detect if sd or sdhc, but heck it's 5 years ago ilooked at it

    Mike
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2019-02-17 02:54
    I know I know I'm busy on finishing TAQOZ for the ROM but you can easily check anything to do with the SD right down at the SPI level using TAQOZ.
    If I want to send a CMD0 (which has data=0) and read the response I type 0 0 CMD . where the first 0 is the data, the second the command, and dot to print the result.
    TAQOZ# 0 0 CMD . --- 1 ok
    
    The --- is inserted when we hit enter so that it is easier to see the output vs the input.
    The crc is automatically set to $95 for a CMD0 but otherwise it is $87 since it only matters for CMD8

    So to send $1AA with a CMD8 it is the same <data> <command> CMD format.
    TAQOZ# $1AA 8 CMD . --- 1 ok
    
    But now with a result of 1 we need to read a long of data from the device so we use the primitive function SPIRL (SPI Read Long) and supply it with a dummy value then print the result as a hex long.
    TAQOZ# 0 SPIRL .L --- $0000_01AA ok
    
    Perfect! That is the response we are looking for.

    But we can try and MOUNT it as FAT32 and .DISK display internal card and FAT32 information easily: (now back to finishing off this ROM....)
    TAQOZ# MOUNT --- CARD: SANDISK   SD SU32G REV$80 #744079391 DATE:2013/4 ok
    TAQOZ# .DISK --- CARD: SANDISK   SD SU32G REV$80 #744079391 DATE:2013/4
    
                       *** OCR *** 
        VALUE........................... $C0FF_8000
        RANGE........................... 2.7V to 3.6V
    
                       *** CSD *** 
        CARD TYPE....................... SDHC
        LATENCY......................... 1ms+1400 clocks 
        SPEED........................... 50Mbps 
        CLASSES......................... 010110110101
        BLKLEN.......................... 512
        SIZE............................ 31,166MB
    
                     *** SPEEDS *** 
        SECTOR.......................... 639us,1031us,780us,783us,782us,813us,783us,787us,
        BLOCKS.......................... 1,258kB/s @120MHz
    
                       *** MBR *** 
        PARTITION....................... 0 00 INACTIVE
        FILE SYSTEM..................... FAT32 LBA
        CHS START....................... 1023,254,63
        CHS END......................... 0,0,0
        FIRST SECTOR.................... $0000_2000
        TOTAL SECTORS................... 62,325,760 = 31,910MB
    
    00170: 0000_0000 0000_0001 0001_0000 506F_7250     '............ProP'
    
                      *** FAT32 *** 
        OEM............................. TAQOZ P2
        Byte/Sect....................... 512
        Sect/Clust...................... 64 = 32kB
        FATs............................ 2
        Media........................... F8
        Sect/Track...................... $003F
        Heads........................... $00FF
        Hidden Sectors.................. 8,192 = 4MB
        Sect/Part....................... 62,325,760 = 31,910MB
        Sect/FAT........................ 7,640 = 3MB
        Flags........................... 0
        Ver............................. 00 00 
        ROOT Cluster.................... $0000_0002 SECTOR: $0000_5BD0
        INFO Sector..................... $0001 = $0000_2001
        Backup Sector................... $0006 = $0000_2006
        res............................. 00 00 00 00 00 00 00 00 00 00 00 00 
        Drive#.......................... 128
        Ext sig......................... $29 OK!
        Part Serial#.................... $A3D9_B89A #2748954778
        Volume Name..................... P2 CARD    FAT32    ok
    TAQOZ#
    
  • cheezuscheezus Posts: 295
    edited 2019-02-17 10:29
    I'm pretty sure I got my frankendriver working on P1. The old driver only worked on SD-FAT16. I would like to try to include support these cards too but I need to test things to see what works and what doesn't. Right now my "test card" is a 4gb sandisk uSDHC-4. Everything seems to be working with FSRW26, although I got some torture testing to do.

    The next thing to do is to change the way the pins are handled and start littering it with conditional compiles :smile:

    It's pretty slow, the basic mount write/readback test takes forever but at least I understand the wire-level better. I'm not finishing up the logic cap on the "pure spin" but reading the directory takes 1/2 a second. PQASM is .. The 2M write/readback test (compiled using fastspin) takes 77seconds vs 15seconds for the QASM. QASM-"pure" is about 19seconds. These are just some baseline numbers to be used for direct comparison.
    con
       sectorsize = 512
       sectorshift = 9
    var
       long di, do, clk, cs, starttime, sdhc
    
    pub start_explicit(_do, _clk, _di, _cs)  
    '
    '   Initialize the card!  Send a whole bunch of
    '   clocks (in case the previous program crashed
    '   in the middle of a read command or something),
    '   then a reset command, and then wait until the
    '   card goes idle.
    
       sdhc := false   
       do := _do
       clk := _clk 
       di := _di
       cs := _cs
    
       outa[clk] := outa[di]  := outa[cs]  := 1 ' fixed in fastspin .20
       dira[clk] := dira[di]  := dira[cs]  := 1
       
       starttime := cnt
       repeat 600
          read
    
       cmd(0, 0)    '' Software reset.
       endcmd
      
       cmd(8, $1aa) '' For only SDC V2. Check voltage range. 
       result := ((read<<24)+(read<<16)+(read<<8)+(read))
       endcmd  
    
       repeat
          cmd(55, 0)
          result := cmd(41, $4000_0000)
          endcmd
          if result <> 1
             quit
      
       if result
          abort -40 ' could not initialize card
           
       cmd(58, 0)                   ' card never mounts
       sdhc := (read >> 6) & 1
       read         ''  finish 32 bit read
       read
       read
       endcmd        
       result := 0
       
    pub start(basepin)
      start_explicit(basepin, basepin+1, basepin+2, basepin+3)
      
    pub stop
     release
     
    pub release
       dira[clk] := 0
       dira[di]  := 0
       dira[cs]  := 0
         
    pub readblock(n, b)
    '
    '   Read a single block.  The "n" passed in is the
    '   block number (blocks are 512 bytes); the b passed
    '   in is the address of 512 blocks to fill with the
    '   data.
    
       if (!sdhc)
         n <<= 9
    
       starttime := cnt
       cmd(17, n)
       readresp
       repeat sectorsize
          byte[b++] := read
       read
       read
       return endcmd
    {
    pub getCSD(b)
    '
    '   Read the CSD register.  Passed in is a 16-byte
    '   buffer.
    '
       starttime := cnt
       cmd(9, 0)
       readresp
       repeat 16
          byte[b++] := read
       read
       read
       return endcmd
    }
    pub writeblock(n, b)
    '
    '   Write a single block.  Mirrors the read above.
    
       if (!sdhc)
         n <<= 9
         
       starttime := cnt
       cmd(24, n)
       send($fe)
       repeat sectorsize
          send(byte[b++])
       read
       read
       if ((readresp & $1f) <> 5)
          abort -42
       busy
       return endcmd
    
    pri send(outv)
    '
    '   Send eight bits, then raise di.
    '
       repeat 8
          outa[clk] := 0
          if outv & $80
            outa[di] := 1
          else
            outa[di] := 0   
          outv <<= 1
          outa[clk] := 1
       outa[di] := 1
          
    pri read | r
    '
    '   Read eight bits from the card.
    '
       r := 0
       repeat 8
          outa[clk] := 0            
          outa[clk] := 1
          'waitcnt(cnt+timeout)        ' at least 10
          r := ( r << 1) | ina[do]
       return r  
        
    pri cmd(op, parm)
    '
    '   Send a full command sequence, and get and
    '   return the response.  We make sure cs is low,
    '   send the required eight clocks, then the
    '   command and parameter, and then the CRC for
    '   the only command that needs one (the first one).
    '   Finally we spin until we get a result.
    '
       outa[cs]~
       
       read
       send($40+op)
       send(parm >> 24)
       send(parm >> 16)
       send(parm >> 8)
       send(parm << 0)
       if (op == 0)
         send($95)
       else
         send($87)   
    
       return readresp
    
    pri checktime
    '
    '   Did we go over our time limit yet?
    '
       if cnt - starttime > clkfreq
          abort -41 ' Timeout during read
             
    pri endcmd
    '
    '   Deselect the card to terminate a command.
    '
       outa[cs] := 1
       return 0
       
    pri readresp | r
    '
    '   Read eight bits, and loop until we
    '   get something other than $ff.
    '
       repeat
          if (r := read) <> $ff
             return r
          checktime
    pri busy | r
    '
    '   Wait until card stops returning busy
    '
       repeat
          if (r := read)
             return r
          checktime  
       
    

    *edit- seems this only works with one card. Back to the drawing board...
  • RaymanRayman Posts: 13,767
    edited 2019-02-17 22:17
    Ok, I just got FSRW 2.6 working with FastSpin on P2 using the Spin version of SDSPI.
    Didn't have to change anything actually...
    (Or, maybe I did and forgot...)

    It mounts and list directory content.
    Appears to test write OK. Haven't tried actually using it for something yet...
  • RaymanRayman Posts: 13,767
    Got the original speed test ("test.spin2") mostly working.
    Fails at the very end when trying to copy from one file to another.
    Seems that having two instances of fsrw at the same time isn't working right...
    But, that isn't so important usually.

    Don't understand the results as it looks like speed goes down slightly as clock speed goes up...
  • I'm pretty confident I have my P1 version working properly now. I'm working on changing the handling of pins for the P2 and will post more once I have some results.

    I'll see if I can figure out why 2 instances of FSRW isn't working and I'll also see if I can figure out what's going on with the clock. I have some ideas RE more than once instance but will know more soon.

    The one thing I'm still trying to figure out is the "proper" way to release a SD card. Being able to "share" the SPI bus pins is going to be important. I need to do some more reading but it seems everything else works.

    PUB release   
    '' CHZ -  if we release pins, card hangs?
    {
    #ifdef __port_b__
        outb[clk] := outb[di] := outb[cs] := 1
        dirb[clk] := dirb[di] := dirb[cs] := 0
    #else   
        outa[clk] := outa[di] := outa[cs] := 1
        dira[clk] := dira[di] := dira[cs] := 0
    #endif 
    }
    
    


    PortB is controlled by this switch here:
    
    #ifdef __P2__
    def __port_b__
    #endif 
    
    

    This seems to work for P1 although it would probably be a good idea to rewrite to allow the P2 to use portA.

    I'm pretty sure I figured out why I was having such a problem... seems I had multiple instances of the same file open and it wasn't being saved properly somewhere along the way. Don't you love chasing bugs that don't exist? :smile:
  • There are a bunch of threads about tri-stating the SD card pins.

    The 'common solution' was to toggle clk about 20 times after unmounting to let the state machine of the SD card finishing what it needs to do.

    I think there is code in the latest FSRW doing that, as of a request from @Cluso99 if I remember correct.

    Enjoy!

    Mike
  • I've finally got something that seems to work on both the p1 and p2. It still needs a lot of work but it's a start. I'm attaching it here in case I break something later. This can be improved significantly, I've hard-coded SD cards to portB for now but I'll need to deal with it better in the future.

    Some early results-
    FSRW - writes 2M / Reads 2M
    P1 - SPIN - 67 seconds @80 mhz
    P2 - SPIN - 26 seconds @160 mhz
    P1 - MB_rawb - 2.6 seconds @80 mhz

    These are completely unoptimized and I'm trying to keep both spin versions as close as possible.

    I made some minor changes to FSRW so it handles errors returned from the spi driver start. FSRW1.6 used aborts but 2.6 used negative returns but didn't check the spi driver. I also added in ifdef controls for the SDSPI so use PASM P1 driver for release.
    
    obj
    #ifdef __P2__
        sdspi: "sdspi_def.spin2"   '' cheeze's frankendriver
    #else
        sdspi: "mb_rawb_spi"     
    '    sdspi: "sdspi_def.spin2"   '' cheeze's frankendriver  
    #endif
    
       if (result := sdspi.start_explicit(DO, CLK, DI, CS)) < 0
         return
       'sdspi.start_explicit(DO, CLK, DI, CS)
    

    The SDSPI is pretty straightforward.
    pri send(outv)
    '
    '   Send eight bits, then raise di.
    '
       outv ><= 8
    #ifdef __P2__
        repeat 8
            outb[clk] := 0
            outb[di] := outv
            outv >>= 1
            outb[clk] := 1
        outb[di] := 1
    
    #else   
        repeat 8
            outa[clk] := 0
            outa[di] := outv
            outv >>= 1
            outa[clk] := 1
        outa[di] := 1
    #endif   
    pri read | r
    '
    '   Read eight bits from the card.
    '
    #ifdef __P2__
        repeat 8
        r := 0
        repeat 8
            outb[clk] := 0
            outb[clk] := 1
    '        waitcnt(cnt+wait_time)     '' c code needs wait here
            r += r + inb[do]
    #else   
        r := 0
        repeat 8
            outa[clk] := 0
            outa[clk] := 1
            r += r + ina[do]
    #endif 
       return r
    
    #ifdef __P2__
        outb[cs] := 0
    #else   
        outa[cs] := 0
    #endif       
    
        read
        send($40+op)
        send(parm >> 24)
        send(parm >> 16)
        send(parm >> 8)
        send(parm << 0)
        if (op == 0)
            send($95)
        else
            send($87)   
        return readresp
       
    pri endcmd
    '
    '   Deselect the card to terminate a command.
    '
    #ifdef __P2__
        outb[cs] := 1
    #else   
        outa[cs] := 1
    #endif       
    
    PUB release   
    '' CHZ -  if we release pins, card hangs?
    {
    #ifdef __port_b__
        outb[clk] := outb[di] := outb[cs] := 1
        dirb[clk] := dirb[di] := dirb[cs] := 0
    #else   
        outa[clk] := outa[di] := outa[cs] := 1
        dira[clk] := dira[di] := dira[cs] := 0
    #endif 
    }
    
    pub start_explicit(iDO, iCLK, iDI, iCS)|basepin 'RJA adding in some things to make work
       do := iDO
       clk := iCLK
       di := iDI
       cs := iCS
    
    #ifdef __P2__
        do  -= 32
        clk -= 32
        di  -= 32
        cs  -= 32
    
        outb[clk] := outb[di] := outb[cs] := 1
        dirb[clk] := dirb[di] := dirb[cs] := 1
    #else   
        outa[clk] := outa[di] := outa[cs] := 1
        dira[clk] := dira[di] := dira[cs] := 1
    #endif 
    
       starttime := cnt
       repeat 600
          read
    
       cmd(0, 0)
       endcmd
    
       cmd(8, $1aa)
       read
       read
       read
       read
       endcmd   
    
       repeat
          cmd(55, 0)
          basepin := cmd(41, $4000_0000)
          endcmd
          if basepin <> 1
             quit
    
       if basepin
          return -40'abort -40 ' could not initialize card
    
      cmd(58, 0)
      sdhc := (read >> 6) & 1
      read
      read
      read
      endcmd
    
       return sdhc +1 ' card type?
    
           
    pub start(basepin)
    
      result := start_explicit(basepin, basepin+1, basepin+2, basepin+3)
      
    PUB doSDHC(n)
        if sdhc == 0   ' STANDARD WORKS ==0
            return n  <<= 9
        else 
            return n
           
    pub readblock(n, b)
    '
    '   Read a single block.  The "n" passed in is the
    '   block number (blocks are 512 bytes); the b passed
    '   in is the address of 512 blocks to fill with the
    '   data.
    '
       starttime := cnt
       cmd(17, doSDHC(n))
       readresp
       repeat sectorsize
          byte[b++] := read
       read
       read
       return endcmd
    {
    pub getCSD(b)
    '
    '   Read the CSD register.  Passed in is a 16-byte
    '   buffer.
    '
       starttime := cnt
       cmd(9, 0)
       readresp
       repeat 16
          byte[b++] := read
       read
       read
       return endcmd
    }
    pub writeblock(n, b)
    '
    '   Write a single block.  Mirrors the read above.
    '
       starttime := cnt
       cmd(24, doSDHC(n))
       send($fe)
       repeat sectorsize
          send(byte[b++])
       read
       read
       if ((readresp & $1f) <> 5)
          return -42'abort -42
       busy
       return endcmd
    
    

    I'm still testing this, there's lots of places that can be improved. I'm thinking about trying inline ASM now that I'm starting to understand conditional compiles. I still have some questions but I'll get to those in the right thread :smiley:
  • cheezuscheezus Posts: 295
    edited 2019-02-21 00:34
    I've hit what seems to be a brick wall in my testing (and further development) and I'm looking for ideas... Up to this point I've been relying on the logic analyzer to sort out what's going on. Seems the P2's just too fast and can toggle faster than 24msps can catch. Not a surprise there :smile:But while playing around with timings I'm pretty sure I'm activating the flash chip and it's interfering.. I THINK.

    I'm very tempted to grab the rework station and pop the flash chip off but I'm reluctant for several reasons. I've also considered hooking up a secondary SD card.. Part of my intention with this driver is to support the native sd socket on the P2-ES since I'm going to be using this board for quite some time.

    I can't really think of a use case where I'd NEED the flash chip and SD wouldn't suffice but idk. I've been trying to figure this one out all day.

    Any thoughts would be greatly appreciated!

    *edit-
    After studying the schematic again, I realized there's no way the flash chip could be interfering since I have the FLASH dip switch off, disconnecting the FLASH chip select. DUHHH
  • Post your code before you pop out the flash chip. Maybe we can see where the problem is.
  • I'd have to try to recreate the bug again but I'm basically trying to convert sections of the SDSPI SPIN file into PASM2. What I have right now is working but, I keep needing to power cycle the P2 when I do break the code. I'm working through remote desktop and the P2 is in a different room so it seriously slows progress. If I can break it again, and it stays broken through a power cycle I'll post the code.
  • Well now I'm really confused. When I compile the code posted above it seems to compile correctly with No Optimization or Default. When I try Full optimization it seems to hang after the "Mounting" message but but before starting the SD init. I don't see any pin activity as it just hangs. I'll probably end up comparing between the output files.
  • @"Dave Hein" & @Rayman ,
    Are you using the SD card slot on the P2-ES or one connected to different pins?
  • I used the SD card slot that's solder on the P2-ES.
  • RaymanRayman Posts: 13,767
    Using different one on custom board..
  • First post updated with most current release candidate. Please test if you can, it should be compatible with pretty much any and every combo of sd/sdhc/fat16/32/p1/p2.

    Thanks for everyone's help along the way. I'd have never even tried to make this work without knowing there's such a great community out there!
  • Bumping this thread because I'm getting ready to start working on this again and could use some help. I'm trying to understand the new way to start a cog and pass a parameter list. Will not been able to test anything until I get the new power supply from Parallax tomorrow. Once I have enough juice I should be able to resume testing.

    I could really use some help testing the current RC posted in the first post of this thread. fsrw_speed is the full test but I don't have it reporting times correctly yet. I tried a few things but couldn't figure out how to pass a current cnt. That's another one I don't quite understand. It should mount a card, list the root directory and write then read a 2m file.

    I should note I haven't tested with the latest release of fastspin so it will be interesting to see if O2 optimizations work now.

    Thanks in advice!
    Chz
  • There's not much different about starting a COG in P2 versus P1; the only difference on the COG PASM side is that the parameter arrives in "ptra" instead of "par". On the starting side there's a slight difference in setting up the coginit instruction, but the Spin library handles that for you transparently (if you're starting from Spin).
  • I'm hoping I understand some of the changes. I THINK something like this should work, I just haven't tested it yet. I'm getting stuck on LOC and addressing, not imperative that I understand to get stuff working but I'd feel better if I could google fu the LOC and addressing threads.


    I'm working on a "template" cog engine, mostly for my own understanding. What I have so far is this :
    
    PUB HOOK
    start_explicit( 3, 2, 1, 0 )
    
    PUB Stop
        if cog
            cogstop(cog-1)
        cog := 0
        
    PUB GetCog
        return cog
        
    PUB start_explicit( DO, CLK, DI, CS ) : card_type
    
      stop
      long[@cmd] := "i"                         'set flag to know if the started cog has read its parameters
      long[@cmd][1] := @DO
      long[@cmd][2] := clkfreq
      cog := cognew(@_asm_start,@cmd) + 1
      if cog
        repeat until long[@cmd] <> "i"  ' wait until cog is done reading parameter
       card_type := long[@cmd][1]       ' arg1 returns card type or aborts with ptr to error from low level driver
      else                                  ' we don't have a cog?  
        return @nocogmsg                    ' probably not a problem so waste of bytes
    
    PUB DoCommand(_cmd, _arg1, _arg2, _arg3)
        if cmd <> 0
          return @cogbusymsg '' busy
    
        arg1 := _arg1
        arg2 := _arg2
        arg3 := _arg3
        cmd  := _cmd    
        repeat until cmd <> _cmd
        return 0    
      
    {
    PUB DoCommandNoWait(_cmd, _arg1, _arg2, _arg3)
        if cmd <>0
          return -11 '' busy
    
        arg1 := _arg1
        arg2 := _arg2
        arg3 := _arg3
        cmd  := _cmd    
        return 0    
    }    
    
    DAT   org
    _asm_start      mov     ptr_to_mbox,    ptra        ' save mbox address for later
    '                call    #do_pasm_init               ' and do all inits 
    do_pasm_init    '' decode pins from first par, 1s from 2nd for init or pin change / clkset
                    mov     ptra,       ptr_to_mbox ' return ptra back to mbox    
                    rdlong  ptrb,       ptra++      ' dummy read, already have ptr to mbox and this won't change                
                    
                    rdlong  tmp1,       ptrb++      ' get pins because these might                
                    mov     pinDO,      tmp1        
                    rdlong  tmp1,       ptrb++      ' get pins because these might                
                    mov     pinCLK,     tmp1        
                    rdlong  tmp1,       ptrb++      ' get pins because these might                
                    mov     pinDI,      tmp1        
                    rdlong  tmp1,       ptrb++      ' get pins because these might                
                    mov     pinCS,      tmp1        
                    
                    rdlong  delay1s,    ptra++      ' get 1s because this might change
                    '' got 1 more par
                    drvh    pinCS
                    drvh    pinDI
                    drvh    pinCLK                
    do_pasm_init_ret
    '        ret                
                    'call   #do_card_init                                   
    do_card_init
                    rep     #.initclksout,  ##4800 ' send a bunch of clocks
                    drvnot  pinCS
    .initclksout       
    
                    getct   timeout
                    addct1  timeout,    delay1s
                    
    
                    
    {=== Assembly Interface Variables ===}
    pinDO         long 0    ' do
    pinCLK        long 0    ' clk
    pinDI         long 0    ' di
    pinCS         long 0    ' chip select
    
    adrShift      long 9    ' will be 0 for SDHC, 9 for MMC & SD
    
    bufAdr        long 0    ' where in Hub RAM is the buffer to copy to/from?
    sdAdr         long 0    ' where on the SD card does it read/write?
    
    readMode      long 0
    
    const512      long 512
    const1024     long 1024
    
    ' loaded on init
    {===== Command Mailbox =====}
    ptr_to_mbox res 1
    cmd_in      res 1
    arg1_in     res 1
    arg2_in     res 1
    arg3_in     res 1
    
    delay1s     res 1   ' clkfreq = 1 s 
    delay1us    res 1   ' clkfreq / 100_000_000
    
    'starttime   res 1
    timeout     res 1   
    tmp1        res 1     ' this may get used in all subroutines...don't use except in lowest 
    temp        res 1
    
    
    sd_cmd      res 1
    sd_parm     res 1
    data_in     res 1    
    data_out    res 1
    count       res 1
    
    
    FIT 496
    


    I'm at a pause in testing due to power supply issues. I keep wishing there was an LED on Brownout, as well as a way to get to the reset pin! Hopefully tomorrow this time my power issues will be solved. I just hope I don't get too distracted with the activity board and other upgrades for my !!! 17 !!! year old boe-bot!
Sign In or Register to comment.