AS6/ASF and SD card initialization

All design tool related questions: compiler, assembler, linker. Embedded programming questions: assembler, C code.

Moderator: nferre

memel182
Posts: 4
Joined: Mon Jun 02, 2014 10:40 pm

AS6/ASF and SD card initialization

Thu Jul 03, 2014 10:25 pm

Hello everyone,

I am working with an Arduino Due and Ethernet shield with SD slot.

I wanted to write a file on a 2Go SD card (fat16) but failed to initialize it, with ASF code examples : I am calling the init code sequence (sd_mmc_init()) but this line always fails (return false) on the first "f_open()" call:

(file sd_mmc.c, method 'static bool sd_mmc_spi_card_init(void)')

Code: Select all

// CMD0 - Reset all cards to idle state.
	if (!driver_send_cmd(SDMMC_SPI_CMD0_GO_IDLE_STATE, 0)) {
		return false;
	}
This seems to be caused by a timeout in spi command response time (ncr) to CMD0...

Debug mode drives me in this method (returns false in the while loop) :

(file sd_mmc_spi.c)

Code: Select all

bool sd_mmc_spi_adtc_start(sdmmc_cmd_def_t cmd, uint32_t arg,
		uint16_t block_size, uint16_t nb_block, bool access_block)
{
	uint8_t dummy = 0xFF;
	uint8_t cmd_token[6];
	uint8_t ncr_timeout;
	uint8_t r1; //! R1 response

	UNUSED(access_block);
	Assert(cmd & SDMMC_RESP_PRESENT); // Always a response in SPI mode
	sd_mmc_spi_err = SD_MMC_SPI_NO_ERR;

	// Encode SPI command
	cmd_token[0] = SPI_CMD_ENCODE(SDMMC_CMD_GET_INDEX(cmd));
	cmd_token[1] = arg >> 24;
	cmd_token[2] = arg >> 16;
	cmd_token[3] = arg >> 8;
	cmd_token[4] = arg;
	cmd_token[5] = sd_mmc_spi_crc7(cmd_token, 5);

	// 8 cycles to respect Ncs timing
	// Note: This byte does not include start bit "0",
	// thus it is ignored by card.
	sd_mmc_spi_drv_write_packet(SD_MMC_SPI, &dummy, 1);
	// Send command
	sd_mmc_spi_drv_write_packet(SD_MMC_SPI, cmd_token, sizeof(cmd_token));

	// Wait for response
	// Two retry will be done to manage the Ncr timing between command and reponse
	// Ncr: Min. 1x8 clock  cycle, Max. 8x8 clock cycles
	// WORKAROUND for no compliance card (Atmel Internal ref. SD13):
	r1 = 0xFF;
	// Ignore first byte because Ncr min. = 8 clock cylces
	sd_mmc_spi_drv_read_packet(SD_MMC_SPI, &r1, 1);
	ncr_timeout = 7;
	while (1) {
		sd_mmc_spi_drv_read_packet(SD_MMC_SPI, &r1, 1); // 8 cycles
		if ((r1 & R1_SPI_ERROR) == 0) {
			// Valid R1 response
			break;
		}
		if (--ncr_timeout == 0) {
			// Here Valid R1 response received
			sd_mmc_spi_debug("%s: cmd %02d, arg 0x%08lX, R1 timeout\n\r",
					__func__, (int)SDMMC_CMD_GET_INDEX(cmd), arg);
			sd_mmc_spi_err = SD_MMC_SPI_ERR_RESP_TIMEOUT;
			return false; // ENTERS HERE!  :evil: 
		}
	}

	// Save R1 (Specific to SPI interface) in 32 bit response
	// The R1_SPI_IDLE bit can be checked by high level
	sd_mmc_spi_response_32 = r1;

	// Manage error in R1
	if (r1 & R1_SPI_COM_CRC) {
		sd_mmc_spi_debug("%s: cmd %02d, arg 0x%08lx, r1 0x%02x, R1_SPI_COM_CRC\n\r",
				__func__, (int)SDMMC_CMD_GET_INDEX(cmd), arg, r1);
		sd_mmc_spi_err = SD_MMC_SPI_ERR_RESP_CRC;
		return false;
	}
	if (r1 & R1_SPI_ILLEGAL_COMMAND) {
		sd_mmc_spi_debug("%s: cmd %02d, arg 0x%08lx, r1 0x%x, R1 ILLEGAL_COMMAND\n\r",
				__func__, (int)SDMMC_CMD_GET_INDEX(cmd), arg, r1);
		sd_mmc_spi_err = SD_MMC_SPI_ERR_ILLEGAL_COMMAND;
		return false;
	}
	if (r1 & ~R1_SPI_IDLE) {
		// Other error
		sd_mmc_spi_debug("%s: cmd %02d, arg 0x%08lx, r1 0x%x, R1 error\n\r",
				__func__, (int)SDMMC_CMD_GET_INDEX(cmd), arg, r1);
		sd_mmc_spi_err = SD_MMC_SPI_ERR;
		return false;
	}

	// Manage other responses
	if (cmd & SDMMC_RESP_BUSY) {
		if (!sd_mmc_spi_wait_busy()) {
			sd_mmc_spi_err = SD_MMC_SPI_ERR_RESP_BUSY_TIMEOUT;
			sd_mmc_spi_debug("%s: cmd %02d, arg 0x%08lx, Busy signal always high\n\r",
					__func__, (int)SDMMC_CMD_GET_INDEX(cmd), arg);
			return false;
		}
	}
	if (cmd & SDMMC_RESP_8) {
		sd_mmc_spi_response_32 = 0;
		sd_mmc_spi_drv_read_packet(SD_MMC_SPI, (uint8_t*) & sd_mmc_spi_response_32, 1);
		sd_mmc_spi_response_32 = le32_to_cpu(sd_mmc_spi_response_32);
	}
	if (cmd & SDMMC_RESP_32) {
		sd_mmc_spi_drv_read_packet(SD_MMC_SPI, (uint8_t*) & sd_mmc_spi_response_32, 4);
		sd_mmc_spi_response_32 = be32_to_cpu(sd_mmc_spi_response_32);
	}

	sd_mmc_spi_block_size = block_size;
	sd_mmc_spi_nb_block = nb_block;
	sd_mmc_spi_transfert_pos = 0;
	return true; // Command complete
}
Any hint on how/why this timeout appends?

Thanks a lot.
Tyler@Technica
Posts: 8
Joined: Thu Jul 03, 2014 12:02 am

Re: AS6/ASF and SD card initialization

Tue Jul 15, 2014 8:30 pm

Unfortunately I can't answer your question...BUT...

I think you're the only other person on the entire internet trying to use Atmel Studio to communicate with an SD card using SPI on an Arduino Due.  I've been trying to get something similar to work, I've just got an SD shield.  I can't find anyone else who has tried to do this though, and without any examples to work off of, I'm stuck.

I managed to get the code for the SD/MMC/SDIO example for the SAM3X-EK moved over from the SAM3X8H to the SAM3X8E (chip on the Due), and then from that I built a new file switching from MCI to SPI.  It compiles and runs, and the card detect pin works, but none of the SPI stuff is working, so the card doesn't initialize.

I haven't had the problem that you're having yet, so my guess is that you're further along than I am.  If you'd be willing to share your project with me, I'll try to run it on my board and see if I can help you with your timeout issue.  If we work together, maybe we can both benefit. 

-Tyler
memel182
Posts: 4
Joined: Mon Jun 02, 2014 10:40 pm

Re: AS6/ASF and SD card initialization

Wed Jul 16, 2014 9:01 am

Really? You mean nobody tried the ASF source code? The Framework seems pretty useful... I just wanted to go a bit further/deeper than the very-high-level Arduino code.
I will share my project in the next few days.
Well, BTW, what would be your better advice? Should I have to change my dev env, and kick off Atmel Studio? (to Eclipse or...?)
Thank you.
Tyler@Technica
Posts: 8
Joined: Thu Jul 03, 2014 12:02 am

Re: AS6/ASF and SD card initialization

Wed Jul 16, 2014 9:18 pm

memel182 wrote:Really? You mean nobody tried the ASF source code? The Framework seems pretty useful... I just wanted to go a bit further/deeper than the very-high-level Arduino code.
I will share my project in the next few days.
Well, BTW, what would be your better advice? Should I have to change my dev env, and kick off Atmel Studio? (to Eclipse or...?)
Thank you.
Don't get me wrong, plenty of people use ASF with the Arduino Due.  Just not for SD card communication via SPI, as far as I have found.  As with everything else, it seems the people who know how to do it have much better things to do, and the people who don't know how to do it don't even know where to begin. 

Atmel Studio is an excellent platform, I'm in the process of migrating everything I have over to AS6.  I've got a custom project based on the Due's design, which is why I need more control than the Arduino IDE can offer.  After everything I've learned, I wish I had started with AS6 from the very beginning.  That's what you get for being self-taught, though.  Live and learn.

That said, I kept working on my code yesterday after my post here, and actually managed to get the SD/MMC/SDIO example for the SAM3X-EK working with SPI instead of MCI on the Arduino Due.  It successfully writes the test text file to the SD card.  I'd be happy to share it with you, maybe it'll help you get yours working for your application.  I'm going to have to go through and redo it in my full application project file, so I'll make sure to document all of the changes I had to make.  It was a bunch of little, random stuff here and there that I had to diagnose with the debugger.
memel182
Posts: 4
Joined: Mon Jun 02, 2014 10:40 pm

Re: AS6/ASF and SD card initialization

Sat Jul 19, 2014 9:56 am

What kind of SD Card are you using? I bought a 2Go (!) one and formatted it in FAT.

And on what physical layer is it? I personally use an Arduino Ethernet shield stacked on the Due.

In your previous answer you mentioned a "card detect pin", that AFAIK is not wired/usable on this Ethernet shield : I had to comment the code related to it to go further in my project... I would have like to keep using this shield because I will need the Ethernet interface later.

And to answer to the choice of AS6, it started with a very little project on an Arduino Uno coded with Arduino IDE, but with the evolution of the needs, I had to migrate to a more powerful platform (the DUE) and IDE with features of debugging, customizing toolchains and full code "hands on" (even if I am still a newcomer in embedded world).
Tyler@Technica
Posts: 8
Joined: Thu Jul 03, 2014 12:02 am

Re: AS6/ASF and SD card initialization

Sat Jul 19, 2014 7:35 pm

I've tested it using a 4Gb and an 8Gb Sandisk, both formatted in FAT32.  

This is the physical hardware that I'm using - http://www.adafruit.com/product/1141

I was able to turn the card detect pin off, so it's not required.  

I took a look at the schematic for the Arduino Ethernet shield (http://arduino.cc/en/uploads/Main/ardui ... ematic.pdf), and I noticed that the SD card slot signals are first run through line drivers (http://www.ti.com/lit/ds/sces223s/sces223s.pdf).

There's a note on the schematic by the SD slot that says that the signals are active low.  Honestly I'm not sure which direction the ASF code drives those signals at, but it's possible that this could be your problem.  
naray23
Posts: 3
Joined: Tue Dec 31, 2013 1:15 pm

Re: AS6/ASF and SD card initialization

Sat Sep 13, 2014 11:12 am

Hi
I am starting of with the examples of SD/MMC card and using the SPI interface to interface the SD card.I am getting the error "sd_mmc_spi.h" not found .Can anybody tell me where is this file.

Regards
Gopalakrishnan.N

Return to “Development Tools”

Who is online

Users browsing this forum: No registered users and 1 guest