• 0
Roberto_UDC

Help needed using micro SD card in Nexys 4

Question

Hello, I've been strugling with de micro-sd card in Nexys-4 for quite some time.

I'm using the code at sd_spi.vhd by Lawrence Wilkinson, but the FPGA never gets a valid answer from the card so it keeps looping forever (CMD8)

I think I've checked all the obvious things :

- Trying an old card, just in case SDHC was not properly suported

- Booting the FPGA from the SD card (not USB), to check that the physical circuits were working properly

- Trying with 3 different Nexys 4 boards 

- Lowering clock frequency to only a few hertzs (normal speed should be 50MHz, and a counter insides L.W. code slows it down for start-up)

- Making sure that all jumper settings were put to SD

 

So it's time to ask if someone has tryed to do the same with this board. I just need a simple way to read data from the SD card. I don't need a file system and using an embedded processor is too much hassle. 

If anybody wants to give it a try, the code is here: Project code (Constraints only for Vivado)

 

Also, to avoid you the burden of downloading it, these are the pins I've being using (just in case is something that embarrasing obvious as using the wrong pin): 

set_property -dict { PACKAGE_PIN E2    IOSTANDARD LVCMOS33 } [get_ports { SD_RESET }];
set_property -dict { PACKAGE_PIN A1    IOSTANDARD LVCMOS33 } [get_ports { SD_CD }]; 
set_property -dict { PACKAGE_PIN B1    IOSTANDARD LVCMOS33 } [get_ports { SD_SCK }];
set_property -dict { PACKAGE_PIN C1    IOSTANDARD LVCMOS33 } [get_ports { SD_CMD }];
set_property -dict { PACKAGE_PIN C2    IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[0] }];
set_property -dict { PACKAGE_PIN E1    IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[1] }];
set_property -dict { PACKAGE_PIN F1    IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[2] }];
set_property -dict { PACKAGE_PIN D2    IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[3] }];

 

Thanks in advance

 

Roberto

 

 

Share this post


Link to post
Share on other sites

4 answers to this question

Recommended Posts

  • 1

@Roberto_UDC,

Are you aware that the SD-card needs to start at a slower clock speed, any only after its been configured you can switch to the 50MHz clock speed?

I support a SPI based SD-card controller myself.  You might find the instructions for that project valuable.  Basically, the card requires quite the start-up sequence (discussed in the instruction manual) before you can start reading from or writing to it.

If you are willing to use Verilog and the Verilator simulator, you'll also find an SD-card based emulator in the bench/cpp directory.  I've used this quite successfully to get the SPI based SD controller working in the first place.  The actual demo software code is kept in a different repository, which you are welcome to look through as well.

Dan

Share this post


Link to post
Share on other sites
  • 1

@Roberto_UDC,

Fair enough, that's your call.  I notice the core you referenced doesn't have a bus interface at all, nor does it necessarily have a command interface.  That'll make some of this more interesting to work through, but so be it.  Let's work through the startup commands.  In my examples, I start up at a 400kHz clock.  Then ...

  • The first command that needs to be sent to the card is a command zero.  CS should start out inactive (high), and go active (low) at the beginning of this command.  This should put the card into SPI mode in the first place.
  • (Incidentally, did you check the pin-outs?  That should be checked first ...)
  • The next command that needs to be sent to the card is CMD1.  In the CMD1 you send, are you indicating a support for high capacity cards?  (Data field = 32'h4000_0000 ?)
  • Only then is the CMD 8 sent.  In this case, you need to send an appropriate interface condition.  I send 32'h01a5.  Can you check what you are sending?
  • We can also check CRC's if necessary, but I'd like to believe that the core you are using sets the CRC's properly ... (Perhaps not ...)

Dan

Share this post


Link to post
Share on other sites
  • 0

Thanks D@n. I checked the forum before posting my question and I already knew your work on the SD controller. 

However, I found the work too tied to the wishbone bus, and I'd problems to extract the basic code to make it work alone. 

I suspect my problems with the Nexys-4 must be something really obvious I'm overlooking. 

 

Regarding clock speed, I think that frequency must be quite low during negotiation, and then it can rise up to 25 or 50 MHz

Roberto

Share this post


Link to post
Share on other sites
  • 0

Hello. I haven’t been able to solve the problem, but I’ve found another piece of code that work with the Nexys 4 board.

That code was provided by Xess Corp  and it can be found here: https://github.com/xesscorp/VHDL_Lib/blob/master/SDCard.vhd

I don’t have the time to check what Xess’s code makes different compared to Wilkinson’s one, but I would like to share this information and also the flowgraph of the module I used to check that reading and writing was possible:

FSM_SDcard.png.e31eff351e3f0e476a616ecfc1552c8c.png

 

A couple of things more. As it is, the code failed to work with an old SD card. One of the commands in the the initialization stage only works with high capacity cards. Also, this is the procedure I followed to check the code was working: writting one or more blocks of synthetic data; reading one of those blocks to an array of signals; writting the array to a new block; checking with HxD that all the data I wrote was actually there. 

 

I hope this helps and thanks to D@n for his contributions

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now