SD Card interfacing

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
LGB
Posts: 28
Joined: 28 Nov 2004
Location: Budapest, Hungary
Contact:

Re: SD Card interfacing

Post by LGB »

enso wrote:
Bit-banging SPI is very simple, and SD cards have very lax timing requirements. I've driven SD card clocks by hand on one occasion! This is the code I've been using on my 45MHz 6502 CHOCHI board. I am sure it could be improved:
It seems the key factor here is the 45MHz :) However I would use my solution with existing computers for 65xx like Commodore 64 (about 1MHz) and for Z80 like Enterprise-128 (4MHz, but Z80 is slower on the same clock rate in average). I built something like "common I/O interface" which is a light bus using only 4 bit for address bus and 8 bit for data with some control signals. This is implemented for Z80 and 65xx too, so the connected devices only need to deal with a common factor in the sense of interfacing with various CPUs. But the average speed of these systems are far below of something like 45MHz, so it's quite slow to get some decent speed for SD card via SPI ...

I've started to think about this project since it's finally the time to build a light 65xx SBC too, not "only" interfacing with existing computers, but still I'd like to keep the "common I/O bus" idea, so I can use the same devices created by me on various range of hardwares without the need to rebuild them for each platform.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: SD Card interfacing

Post by GARTHWILSON »

Quote:
I'm also thinking on SD-card interfacing (and other SPI devices btw) but not with bit-banging which seems to be too slow for my taste.
Do you have a particular speed goal?

Here's part of the SPI-bitbanging code I have posted on my website:

Code: Select all

CLK_UP: MACRO                 ; NOTE!  Accum is not preserved!
        LDA  #1
        TSB  VIA3PB
        ENDM
 ;------------------

CLK_DN: MACRO                 ; NOTE!  Accum is not preserved!
        LDA  #1
        TRB  VIA3PB
        ENDM
 ;------------------

CLK_LO_PULSE: MACRO           ; NOTE!  Clock must already be known to be high!
         DEC  VIA3PB
         INC  VIA3PB
         ENDM
 ;------------------

CLK_HI_PULSE: MACRO           ; NOTE!  Clock must already be known to be low!
         INC  VIA3PB
         DEC  VIA3PB
         ENDM
 ;------------------

MOSI_UP: MACRO                ; NOTE!  Accum is not preserved!
         LDA  #2
         TSB  VIA3PB
         ENDM
 ;------------------

MOSI_DN: MACRO                ; NOTE!  Accum is not preserved!
         LDA  #2
         TRB  VIA3PB
         ENDM
 ;------------------

 ; For SEND_BYT and RCV_BYT below, I use program structures discussed in my web page
 ; http://wilsonminesco.com/StructureMacros/index.html .  The source code for implementing them on the C32 assembler is at
 ; http://wilsonminesco.com/StructureMacros/STRUCMAC.ASM , but you can undoubtedly see what they will assemble if you want to do it
 ; without the macros.  I used them here to make it more clear what is happening.


SEND_BYT:                     ; Start with byte in A.  Slave must already be selected.
    PHA                       ; Put the input number on the stack because we need A for the TRB/TSB mask below.
        CLK_DN                ; Prepare for mode-0 transmit, and for high clock pulse with INC DEC.
        TSX                   ; Put the stack pointer in X for shifting below without bringing it back into the accum.
        LDA  #2               ; 2 is the value of the MOSI bit for TSB & TRB.
        FOR_Y  8, DOWN_TO, 0  ; 8 is the number of bits we will shift out and test in the loop.
            ASL  101,X        ; Shift the input number left, since transmission is msb-first.
            IF_C_CLR          ; The bit gets put in the carry flag.
                TRB  VIA3PB   ; If the bit was a 0,  clear the MOSI bit in VIA3PB,
            ELSE_             ; otherwise
                TSB  VIA3PB   ; (ie, the bit was a 1), set the MOSI bit in VIA3PB.
            END_IF
            CLK_HI_PULSE      ; Pulse the clock line.  The INC/DEC does not affect A.
        NEXT_Y                ; Decr the counter and see if we need to repeat the loop.
    PLA                       ; Remove the number from the stack.  (We don't need it anymore, but we need the stack cleaned up.)
    RTS
 ;------------------

RCV_BYT:                      ; Slave must already be selected, and first bit must already be waiting on MISO.  Output is in A.
    CLK_DN                    ; Prepare for mode-0 receive, and for high clk pulse with INC DEC.
    LDA  #0                   ; We will build up the byte in A, so init it to 0.
    FOR_Y  8, DOWN_TO, 0      ; 8 is the number of bits we will shift in in the loop.
        BIT  VIA3PB           ; MISO is on VIA3PB6, which BIT reflects in the V flag.
        CLC
        IF_V_SET
            SEC               ; Transfer V flag into C flag,
        END_IF
        ROL  A                ; then rotate it into the accum.
        CLK_HI_PULSE          ; Pulse the clock to get the next bit ready, even if it won't get read
    NEXT_Y                    ; until the next RCV_BYT .  Decr the counter and see if we need to repeat.
    RTS                       ; Output is in accum.
 ;------------------

 < now build the routines specific to the SPI ICs you want to use >
Note that it only takes two instructions for a complete clock pulse, and that in the sending, the MOSI is set or cleared using only one instruction, not having to read, AND/OR, and then store back. It's still bit-banging of course, but probably quicker than many might think. For further speed-up, you could straight-line it to eliminate the DEY, BNE (which are what the "NEXT_Y" macro assembles) so it's no longer a loop.

I know SPI allows sending and receiving at the same time, but none of the SPI ICs I've used so far do that. They only do one at a time.
Quote:
Option2: Let's use a dedicated SPI interface IC. Unfortunately there is not so many ... Unlike UARTs, they're quite rate [rare?]. To be precise I only know about 65SPI, but it would be harder/more expensive to get one from Hungary, also maybe it's too 65xx specific, I'd like something I can use in my Z80 projects as well. I don't know if 65SPI can be used with outer [other?] CPUs easily or not.
Contact Daryl here on the forum and get one or more 65SPI's directly from him. I know he won't charge you abusive amounts for shipping like some companies do, and he can probably send it out within a day of when you ask. I'm sure you'll find him to be very easy to do business with.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: SD Card interfacing

Post by enso »

It seems possible to achieve close to 100KHz clocking bitbanging even at 1MHz. Even at 50KHz you can read data at the rate of 6K per second! You will fill your 64K of RAM in 11 seconds, or more realistically, load a respectable 32K app in under 6 seconds. Is it really worth adding extra hardware to bring that time down to 1 second?
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
Klaus2m5
Posts: 442
Joined: 28 Jul 2012
Location: Wiesbaden, Germany

Re: SD Card interfacing

Post by Klaus2m5 »

enso wrote:
It seems possible to achieve close to 100KHz clocking bitbanging even at 1MHz. Even at 50KHz you can read data at the rate of 6K per second! You will fill your 64K of RAM in 11 seconds, or more realistically, load a respectable 32K app in under 6 seconds. Is it really worth adding extra hardware to bring that time down to 1 second?
To load or store raw data? True, but people usually have a file system on their SD-cards. You also need to read and maybe write a directory and you need to find allocation units in a table. And if you want to access an SD-card from your application it is stuck during access of the card because all CPU power is consumed by bit-banging.
6502 sources on GitHub: https://github.com/Klaus2m5
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: SD Card interfacing

Post by Arlet »

For comparison, I just read a file from an old floppy disk, and I got 33K per second (including a few seeks back and forth). Of course, this is with relatively modern equipment from the end of the floppy era. The original drives that you could buy for home computers were much slower.

I guess it all depends on your application and expectations. For recreating retro experience, 100 Kbit/sec is good enough to load some old games.
User avatar
LGB
Posts: 28
Joined: 28 Nov 2004
Location: Budapest, Hungary
Contact:

Re: SD Card interfacing

Post by LGB »

enso wrote:
It seems possible to achieve close to 100KHz clocking bitbanging even at 1MHz. Even at 50KHz you can read data at the rate of 6K per second! You will fill your 64K of RAM in 11 seconds, or more realistically, load a respectable 32K app in under 6 seconds. Is it really worth adding extra hardware to bring that time down to 1 second?
Yeah, for loading apps, it must be enough, that's true :) However, I'm simply interested in trying "something different" by thinking on building an SPI interface by myself. Also, my second plan is to hook up that ethernet controller (28J60) via SPI, when speed is useful, as I would love (ok, I know there is not so much point to do this, but still) to have demos like listening music on a small 8 bit thing in good quality (audio streaming) or even some lower res/low colour video streaming (of course they're not my brilliant ideas, there are existing projects like this, I know). This is strictly "just for fun" category, I have to admit, of course. I've already _did_ bit banging of an SD card, but it's true it was done on the printer port of a PC (it was easier to "play" with it first). I also started to construct an SBC (well, on breadboard) using an UMC 6502 (NMOS part) because I have one (and I hadn't have CMOS 65xx). I never ever finished it, but I thought using SO pin as SPI MISO somehow (now it's the bit banging topic again), but now I am really not sure it would give any boost of the speed at all. I also tried to play with my PC parallel port experiment to support the simple bit banging with at least clock generation by hardware, but it was a hard task (as on the printer port there is not so much handshaking, like you can know actually somebody _reads_ the port at the given moment).
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: SD Card interfacing

Post by enso »

I will try to be the voice of reason here. If speed is in fact an issue, why not get a 45MHz 6502 computer for $25? And since it's on an FPGA, you can pop in a shift register with no problems if you feel like doing some interesting work. The FPGA is 1/2 full, so there is plenty of room for innovation and interesting projects.

If speed is not the issue (that is you want to run at less than 14MHz), then can you really worry about being locked out for a few seconds while the computer is bitbanging?
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
User avatar
LGB
Posts: 28
Joined: 28 Nov 2004
Location: Budapest, Hungary
Contact:

Re: SD Card interfacing

Post by LGB »

enso wrote:
I will try to be the voice of reason here. If speed is in fact an issue, why not get a 45MHz 6502 computer for $25? And since it's on an FPGA, you can pop in a shift register with no problems if you feel like doing some interesting work. The FPGA is 1/2 full, so there is plenty of room for innovation and interesting projects.

If speed is not the issue (that is you want to run at less than 14MHz), then can you really worry about being locked out for a few seconds while the computer is bitbanging?
Hmm because it's cheating to use a such a powerful piece of hardware :) In my viewpoint at least. As I've said I have some ideas about "fun projects" some rudimentary "video" streaming on Commodore 64 which has a 6510 clocked about at 1MHz. It's one thing to build something really fast new construction, but it's another topic to develop an interface for an existing computer, I also feel SuperCPU for C64 as some kind of "cheating" btw :) It should be called another computer, not C64 anymore, but otherwise it's nice (and also I'd love to have ...), indeed. The same here for a 45MHz 6502: it's really cool, I'd love to have it, etc, but now my project is about mainly for a minimal-design interface for _existing_ computers, like C64, to show what a C64 can do, so the interface for doing SPI should be minimal as much as possible to gain to goal, and bit banging is to slow. And it's a bit odd to use a 45MHz 6502, or even a 20MHz AVR (that was the other reason I didn't like one of my options in my original post) when they are much powerful than the host computer itself, it's not the same feeling. Well, I am sure it sounds odd for others, as I am an odd person in general with strange ideas sometimes :) Of course with a "built an own 65xx system" project, I would consider using something more modern stuff, like a 65SPI, which is - AFAIK - a CPLD or even a 45MHz 6502 implemented in an FPGA.
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: SD Card interfacing

Post by Arlet »

@LGB: The whole point of wanting to use a 6502 in any form is a bit odd, considering that there are so much more powerful alternatives. It's not surprising that everybody has their own specific motivations and self-imposed restrictions. So, maybe you are odd, but not worse than anybody else here. :D
User avatar
LGB
Posts: 28
Joined: 28 Nov 2004
Location: Budapest, Hungary
Contact:

Re: SD Card interfacing

Post by LGB »

Arlet wrote:
@LGB: The whole point of wanting to use a 6502 in any form is a bit odd, considering that there are so much more powerful alternatives. It's not surprising that everybody has their own specific motivations and self-imposed restrictions. So, maybe you are odd, but not worse than anybody else here. :D
Yeah, I could guess this :), just I felt I needed too much amount of explanation why I want to do this, so I had the idea that I want something too odd ;)
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: SD Card interfacing

Post by enso »

OK, I totally get it. I suppose the proper solution for you is a shift register or two.

However, having used the stock C64 disk drive, I am convinced that bitbanging SPI would be an incredible increase in performance, even at 50khz.
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
User avatar
LGB
Posts: 28
Joined: 28 Nov 2004
Location: Budapest, Hungary
Contact:

Re: SD Card interfacing

Post by LGB »

enso wrote:
OK, I totally get it. I suppose the proper solution for you is a shift register or two.

However, having used the stock C64 disk drive, I am convinced that bitbanging SPI would be an incredible increase in performance, even at 50khz.
Hehe, that's _so_ true :) Nearly everything is faster (well, Datasette is not so much, but still ...) than a stock 1541 and likes with the standard IEC protocol.

And btw, SD card is the first stage only to try (that's not for the C64 too much btw but I also tried with an SBC project, where bit banging would be enough!) SPI and play a bit, the SPI based ethernet controller would be a more important goal for me, with some kind of extra flexibility to use a some custom bus signals to connect the same "card" to various types of my machines, let it be a C64, a Z80 based computer or a little SBC project based on 6502. That was the "common I/O bus" idea I wrote about. Also there are interesting other ISP devices like the um-FPU, and maybe others too. As you can see the "speed of loading apps on this machines is OK even with bit banging" is really true, but much wider spectrum of devices would be considered by me than just SD cards ... Well. Later :)
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: SD Card interfacing

Post by Arlet »

If you're interested in ethernet, perhaps the Silabs CP220x would be an option (further ethernet discussion should get its own thread).
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: SD Card interfacing

Post by enso »

Arlet wrote:
@LGB: The whole point of wanting to use a 6502 in any form is a bit odd, considering that there are so much more powerful alternatives....
Arlet, your 6502 core is perhaps the smallest usable general purpose core for FPGAs (I like Picoblaze, but it is only good for very small applications), and at 45MHz it can go head to head with many modern microcontrollers. There are a lot of 6502 tools out there as well. I know I am preaching to the choir, but it is hardly that odd to chose a 6502 core for a small FPGA.
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: SD Card interfacing

Post by GARTHWILSON »

LGB wrote:
And btw, SD card is the first stage only to try (that's not for the C64 too much btw but I also tried with an SBC project, where bit banging would be enough!) SPI and play a bit, the SPI based ethernet controller would be a more important goal for me, with some kind of extra flexibility to use a some custom bus signals to connect the same "card" to various types of my machines, let it be a C64, a Z80 based computer or a little SBC project based on 6502. That was the "common I/O bus" idea I wrote about. Also there are interesting other ISP devices like the um-FPU, and maybe others too. As you can see the "speed of loading apps on this machines is OK even with bit banging" is really true, but much wider spectrum of devices would be considered by me than just SD cards ... Well. Later :)
Do look into the 65SIB (6502.org serial interface bus) we developed here, sumarized at viewtopic.php?t=1064&start=105. It is basically SPI, but expanded in several directions at once, making it more flexible (including as an external bus), usable for multi-mode SPI, QSPI, Microwire, and related interfaces, and dumb shift registers too, all at the same time. It offers autoaddressing, power on the connector, interrupts, and allows autoconfiguration and a lot of intelligence but does not require it at all, and very smart devices can sit on the bus along with very dumb ones, simultaneously, without conflicts. External hubs can be added for more addresses. Again though, if you don't want to use the extra intelligence possibilities, you can totally ignore them and just use it as a very simple multi-purpose serial bus with different processors (not just 6502).

Also see our I2C-6 method for facilitating the use of multiple pluggable I²C devices. The brief spec is at viewtopic.php?f=4&t=2155.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Post Reply